开发近况 - 计算着色器(2011.8.16)

又发博客了Oye!我明白我们已经潜水了一年多没有发任何开发记录了,但是这里的主要原因是我们所做的大部分工作基本都是引擎相关和涉及低层的东西,所以实在是没什么新的东西可以秀的(无图无真相)。不过最近我开始了将行星引擎和新的材质系统整合的工作,而这里就是第一步工作的结果:计算着色器!

DirectX 11

在我开始进入主题前,先谈谈去年我们都做了些什么——大部分都是底层和引擎相关的东西,例如改进的场景图(scene graph),一个全新的场景编辑器(Keith的推特上有相关的信息),新的材质系统(从此之后美工就可以像用Unreal引擎一样,不需要懂脚本和编程也可以自己设置着色器了)还有最重要的……一个DirectX 11渲染器!

你们中一些人也许还记得我很长时间是如何吐槽OpenGL并且计划转用DirectX的……现在这件事情已经完成了。不过我们转向DirectX的原因是为了能够使用顶尖的技术,而不是直接把原来的OpenGL的渲染器——依然停留在DirectX 9水平——直接移植到DirectX平台。转向DirectX的一个结果是,我们现在可以给行星引擎使用计算着色器了。

计算着色器?(Compute Shaders?)

并不需要多专业的知识,大多数人都知道着色器这个东西。顶点着色器负责处理顶点,像素着色器负责处理像素。那么计算着色器又是什么呢?(简称CS,Directx11新增特性)额…这就是有趣之处:它能够处理任何东西。计算着色器支持GPGPU(通用图形处理器)上的通用计算。你发送一块数据给GPU,然后在上面运行一段并行计算,并得到返回的结果。相对于在CPU上运行同样的计算任务,它很快,非常快。

在本引擎的上一个版本,我们曾经使用像素着色器来生成行星。我们创建一个33x33的空材质,在上面跑一个过程化高度像素着色器,然后读取返回的结果,将之作为一组高度图输入数据以便在CPU上建立地形网格(注:我们一般使用CPU来创建网格数据以便执行碰撞检测,如果不需要考虑碰撞检测问题,那么直接在GPU上生成网格数据也是可能的)。

对于贴图来说,办法也差不多,但是在高分辨率模式下,我们将生成256 x 256(甚至是512 x 512)的空材质,使用同样的过程化高度像素着色器来做几何生成,不过这次我们并不会把数据读回到CPU。我们将之作为一个贴图材质来保存在GPU,然后在之上运行一系列的其它着色器(1个用来生成法线贴图,另外一个用来基于倾斜度/高度数据生成漫反射颜色)。

这些几何/材质生成工作并不会再每一帧画面中都发生,而只是在创建新的地形网络时才执行。例如你飞到了一颗行星后,有很多的地形网格将会被实时生成/丢弃。因此这将相当依赖GPU性能,以及相当大的显存容量来存储所有相关数据。

精度不足是在OpenGL/DX9这种水平的着色器上运行过程生成时遇到的另外一个问题。32位浮点的精度不够,并且在低地平线时将出现光照瑕疵/裂缝。这问题在我以前发表的大多数游戏视频里都没有出现,因为当我飞近地平线时,大多数时候都是在平坦区域附近所以这个问题不是那么容易被发现。

随着DirectX11计算着色器的使用,我们将把行星引擎发展到更高一级水平。这并不意味着它将像变戏法一样会好看了10倍,但是它将会比以前运行得更快,尽管会带来一些小问题。

返工行星引擎的第一步就是在我们的DirectX11渲染器里添加计算着色器的支持。一旦这个工作完成,我将移植我们的噪声库(过程生成技术的基础,使用一系列的柏林噪声函数)到HLSL上(高级着色器语言)。接着我搞了一个小应用程序来演示计算着色器的威力。这个程序现在作为一个示例已成为我们的引擎开发工具的一部分。

计算着色器样例

实际上这是一个很简单的样例,只有几百行代码长;它的效果类似于谷歌地图,所以它是全2D的(不过噪声和数据都是真3D)。你可以拖动鼠标来在世界中移动,并且可以实时进行缩放。

在开发的同时,我实现了一个已经想了好久的阴影算法。这个算法的思路比较简单,利用从采样点到太阳的光线步进来确定采样点是否在地形的高度之下。这样就为地形提供了阴影,可以让地形看起来更加真实。不过这个算法需要对每个采样点的高度进行充分的估算,所以……用这个算法来做着色器的压力测试似乎是个不错的想法。因为我们需要大量的系统资源来生成高质量/高分辨率的材质,所以我们不打算把这个算法用在新的行星引擎里。阴影还是会用阴影贴图来实现。

性能

新的噪声库比老的(OpenGL版本)的性能怎么样? ? 三个字:极度好!

老的OpenGL版本使用材质查找表来实现柏林噪声。新版本的代码采用整数形运算,比起以前快了很多。给你举一个例子,使用老版本实现可以达到10帧,而新版本和整数型运算可以达到35帧。这足足快了3.5倍! 不过有一个问题:必须得有一张DX10+显卡。

但是还不止这些提升!在内存组共享时使用了特殊的共享结构,可以从缓存高速读取查找表。这使执行性能再次提速了30%。

用我的Radeon 6870,以1280 x 1024缓存模式执行一张高度图的阴影渲染,可以达到45帧。但我增加到4个阴影源时,可以达到26帧。

所以,我们可以说在DirectX11时的噪声执行性能是老的OpenGL行星引擎的4.5倍。这很令人激动,不是吗?~

视频

注意:实时录制的视频,所以感官上有些卡(但帧率非常平滑):下载点此

http://player.youku.com/player.php/sid/XMjk1MjM1MjQ4/v.swf

文章翻译:Infinity汉化组:euyis, iaau0908, zhaozdi, 300y;润色校对:FreemanGL
原文链接:http://www.infinity-universe.com/Infinity/index.php?option=com_content&task=view&id=117&Itemid=47

一些说明:
问:我必须使用DX11的显卡才能跑游戏吗?
答:

我们并不强制要求你有一块DX11或以上级别的显卡才能跑得动引擎(尽管强烈推荐)。OpenGL的渲染方式将作为多平台的支持。使用计算着色器的关键点是如果你的显卡支持,你将获得30%的额外性能提升相比之前(像素+顶点着色)的低端硬件必须使用的方法。

问:为什么不使用OpenCL?
答:

我们使用的是通用界面。具体实现方法留给了渲染器。DX11渲染器使用DX计算着色器11。而OpenGL渲染器可能会使用OpenCL来实现,不过还没写呢。

终于出来了…英文压力大…看得不明不白的…
饿…我说英文官网…

劲爆了 :7_485::7_485::7_485::7_485::7_485:

似乎进度开始快起来了

比上次那个等高线好看多了。。。。话说河流之类的呢?
PS:啥时候加上植被就完美了。。。动物什么的咱们就不要幻象了:7_624:

期待可以进入游戏的那一天,我都等不及了。。。。

过程生成点植物啥的 不然也太光秃秃了:7_485:

最好是各种各样~千奇百怪的 植物 都要有~~~

居然有更新。。这是年刊吧,估计等我大学毕业游戏都不一定能出来。。

呜呜。。。。无限坐等,好久没有看了。。。。

我追随你来了;A002;

不错,争取在30岁前能玩到,从23岁开始等,今年26

原来这个项目还在继续;A028;

靠。说明这游戏。还是没机会玩。等他出来不知道我现在多大。真是晕。。老外和国人就是不同。国人讲的是速度开快,快速挣钱,老外讲的是长期出精品,精品挣大钱。唉。我看是要等我40才能玩了。