枪神纪轮廓渲染方法对比与解析

发表于2016-04-14
评论1 2.7k浏览
一、摘要
  在枪神纪里先后采用了两种方式进行了对人物进行轮廓渲染,分别是Object Based几何处理方法与Image Based的图像处理方法,本文就这两种方法的实现方式,性能,系统整合等方面进行对比与解析。

二、方法介绍
  角色的轮廓渲染有两种方法,Object Based之类的几何操作的,以及使用后处理进行的图像处理的方法。
  Object Based的几何方法
1、首先渲染一遍基础的模型,并标记Stencil。


2、第二遍再渲染一遍模型,不过在VS阶段,沿垂直屏幕方向进行Extrude Vertex一段距离。


3、PS阶段进行勾边颜色的渲染,对于标记Stencil的部分,不通过。
 

三、Image base的图像处理方法
1、首先渲染一遍基础的模型,利用MRT功能输出轮廓颜色到RT1上。


2、在后处理阶段,对此RT1进行边缘检测,描绘出边缘。


四、性能分析
  效果层面,两个并没有多大的区别。然而到了效率层面,Object Based的方法的缺点在于,他需要两次渲染一个物体,虽然第二次的PS简单,但是第二遍绘制的过程,仍然需要处理一遍顶点Shader,对于那些需要GPU Skinning的 顶点来说,这是一个很大的负担。反观Image Based的方法,虽然他节省了一次渲染的过程,但是最后那一次后处理,即使在VS阶段做了AABB标出了物体的大概范围,仍然有很多个像素需要进行处理,每个像素的都需要经历5次的贴图采样,这个对于缺少TMU低端显卡来说[1],简直就是噩梦。
  总之,就是Object Based会导致两次的Vetex Process,Image Based会导致贴图采样消耗过大,这两者对于低端显卡都是消耗巨大。那么我们如何去选择呢?
  Intel HD Graphics的白皮书上有这样一段阐述[2]:
  Multi-Texture Rendering is better than multi-pass rendering since MTR reduces state changes, driver overhead, and CPU load. In addition, Intel integrated graphics utilizes main system memory for graphics. The intermediate pixels computed in a multi-pass rendering need to be transported back to main memory and then back to the graphics subsystem when needed again, causing a full round-trip over the bus per render target for each pass. 
  上面阐述了在Intel HD Graphics 上,使用MRT会更好一些。

五、性能测试
  我们仍然缺少其他平台的理论依据,因此这个时候,我们使用了枪神纪独有的性能测试方法。我们借助NSight来生成单帧测试用例,这个单帧的测试用例可以编译成一个本地的D3D程序,通过衡量在不同平台上该D3D程序的帧率,来评定一个渲染算法的优劣。
1、这样做有这样的好处:
(1)、测试过程准确,可重复。
(2)、测试过程迅速,程序免安装,体积小(通常在10M以下)。
2、具体的步骤如下:
(1)、实现命令行,能够在灵活的调整两种轮廓渲染方法。
(2)、使用Nsight分别截取两个轮廓渲染的帧数据。


(3)、调整编译参数,移除Debug CRT,生成测试用例程序


(4)、在目标机器上运行测试用例程序,并通过Fraps截取帧率。
  
六、测试结果:

显卡Image BasedObject Based
Intel HD Graphics 10007261
Intel HD Graphics 20007659
Nvidia 7600GT10095
Nvidia 9500GT120113
AMD 545010196
Nvidia GT 210109100
GTX 660670630
760G4137

  我们发现在各个平台上,Image Based方法还是稍微快一些。节省了一次GPU Skinning,这个消耗在低端机器上还是较大的。

七、图像处理方法的弊端
1、带宽的瓶颈加重
  MRT虽然是DirectX 9.0c的标准之一,但是早些年的显卡却需要RT的Bit Depth一样才能正确输出MRT[3]。这个看似不起眼的设定,却影响着Image Based的方法的效率,在UE3中,使用了Half[4]去代替BYTE[4]来作为Base Color的格式,因此,我们的Base Color的格式需要Half 格式,同时也就约束了我们的RT1的格式也为Half,而这个是很没有必要的。因为MRT本身就是制约在带宽方面,此处无疑大大加重渲染的负担。
  解决的方法:
  检查D3D里D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS 标记是否有设置,如果此标记是OK的话,那么就可以设置不同Bit Depth的RT,进而大大节省带宽。如果标记为False,那么还是需要使用和RT0一样的BitDepth。
  一般来说,对于支持DX10以上的显卡都支持这个特性,因此,在实际测试中,还是能够覆盖大部分的玩家机器的。
2、Shader爆炸
  因为需要在Shader里标记输出的Render Target,就不可避免的需要修改Shader,注意,这里是需要修改一整套的Shader。 Unreal3使用的是Forward Shading,并通过一个ubershader将这个材质根据不同的光照生成不同的Shader[4], 同时一个材质不仅要和光源种类耦合,也要和他的顶点,预计算光照算法种类等等因素耦合。这些耦合导致了Shader的个数成倍的上涨,最终导致了Shader数量上的爆炸。

 

  解决方法:
  使用特定的标记,标记当前特定的材质才需要生成MRT材质。在实际的测试中,因为枪神纪的角色大量的使用了公用材质模板,最后实际生成的MRT类型的材质非常的少。

八、参考
1、Comparison of Intel graphics processing units
http://en.wikipedia.org/wiki/Comparison_of_Intel_graphics_processing_units
2、Intel Integrated Graphics Developer Guide 2.7.1
http://software.intel.com/sites/default/files/m/d/4/1/d/8/Intel_Integrated_Graphics_Performance_Developer_s_Guide_v2_7_1..pdf
3、Multiple Render Targets (Direct3D 9) 
http://msdn.microsoft.com/en-us/library/windows/desktop/bb147221(v=vs.85).aspx
4、Real Time Rendering 3rd, Chapter 7.9 Combining Lights and Materials.

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引