z pre-pass 相关问题的讨论

z pre-pass

是指在渲染流程中,第一个pass先画一张深度buffer出来,得到需要绘制的最前面这层深度,用这个在接下来的pass中做深度剔出,这样在第二个pass中会省略很多绘制。

这项技术在渲染透明物体时可以的到理想结果。因为有了这层深度剔除,透明物体内部的错乱的内部结构就不会显示出来。

 

有关z pre-pass 的效率问题,实际上并不那么乐观。

 

http://casual-effects.blogspot.hk/2013/08/z-prepass-considered-irrelevant.html

http://www.gamedev.net/topic/641257-depth-pre-pass-worth-it/

 

这两位作者都做了测试,前者测试相当严格。结论是z pre-pass在forward+基本没有效率提升。

 z pre-pass在第一个pass有从vertexshader到rasterize的开销。这个和后面用这张depth buffer剔除后面的绘制节省的开销在很多情况下是互相抵消,基本没多少优势。我想这也是AC2关掉z pre-pass的原因。但这会导致透明物体渲染次序的问题。

 

front-to-back

是指渲染opaque物体时从前向后画,开深度测试,这样后面的物体被前面物体遮住的部分就会被剔除,效率得到提升。

 

合并批次

是指把渲染状态相同的batch,顶点数据合并起来提交。一次绘制出来,减少drawcall的调用次数,进而也提升了效率。判断是否需要合并是通过batch的填充率满不满来决定的。如果batchsize不满,又是同样render state的批次,就应该合并起来。

 

但front-to-back 和合并批次有个矛盾的地方在于同样渲染状态的物体,比如一种类型的草,它们通常位于场景的各个位置,如果严格由近及远画,就会导致渲染状态反复被切换,就无法合并批次了。

针对这个问题,zxy和chenzhe讨论得出一个观点,如果做了z pre-pass就不需要 front-to-back 这样就可以合并批次了。

之前得到大家的一致认同,但后来我看了上述两篇文章意识到上述观点有如下问题:

 

z pre-pass绘制的时候 如果可以做front-to-back 也是可以极大提升这个阶段效率的,这是我们在讨论过程中一直忽视的一个问题。z pre-pass 和 front-to-back不是互斥的。

讨论的时候忽视了z pre-pass在第一个pass有从vertexshader到rasterize的开销。虽然是很简单的ps,从上文两个连接测试来看,前面这部分vs的开销也不少。

 

综述,z pre-pass加合并批次不见得是最优解。个人倾向在front-to-back和合并批次之间取个折中,即不那么严格的front-to-back排序。

引用Morgan McGuire (G3D作者)的话:

In other words, the z-prepass may be irrelevant in modern rendering systems that submit many draw calls for well-sorted objects,

and ispotentially harmful as tessellation (and thus rasterizer setup) and skinning workloads increase.

 

 

欢迎提出意见。

 

posted on 2016-11-17 11:45  minggoddess  阅读(3804)  评论(1编辑  收藏  举报