关于EarlyZ

在前向渲染中,ZTest是在Fragement Shader之后进行的,也就是说,被遮挡的部分也要绘制FS,就产生了Over Draw,其实很费,Early Z Culling就解决了这个问题

Early fragment tests, as an optimization, exist to prevent unnecessary executions of the Fragment Shader. If a fragment will be discarded based on the Depth Test (due perhaps to being behind other geometry), it saves performance to avoid executing the fragment shader. There is specialized hardware that makes this particularly efficient in many GPUs.

The most effective way to use early depth test hardware is to run a depth-only pre-processing pass. This means to render all available geometry, using minimal shaders and a rendering pipeline that only writes to the depth buffer. The Vertex Shader should do nothing more than transform positions, and the Fragment Shader does not even need to exist.

This provides the best performance gain if the fragment shader is expensive, or if you intend to use multiple passes across the geometry.

OpenGL Wiki上简单介绍了EarlyZ,是一个硬件功能,硬件会运行一个depth-only pre-processing pass,然后执行ZTest,把不可见的fragment discard掉

 

在intel这篇文章中https://software.intel.com/en-us/articles/early-z-rejection-sample

在软件层帮硬件生成更准确的ZBuffer ,为 front to back rendering 和 z pre-pass.

关于 back rendering requires

所有不透明的几何根据相机由近到远进行排序,先渲染近的FS,渲染到后面的被遮挡的就会被ZTest掉,此方法不需要额外的D3D API调用

这样的话不透明的物体由近到远画,半透明物体由远到近画,就没有问题

关于Z pre-pass

所有的不透明几何物体都要多走一个Pass,每个几何物体先写入一遍ZBuffer,使用一个空的FS,只执行简单的顶点着色器。之后会禁用ZWrite(关闭),开启ZTest,之后再走VS和FS,这样被挡住Fragment的FS就会被拒绝

Z pre-pass回增加不透明几何物体个Pass,在有些情况可能会更费,但是当FS是性能瓶颈时可以使用

 

ATI和NVIDIA也有相关说明,Early Z是一个硬件功能

关于EarlyZ

 

在Applications of Explicit Early-Z Culling上说,ATI R300的EarlyZ,在PS执行前,是Check primitive的插值得到的Z而不是ZBuffer

关于EarlyZ

同样不能在PS里面写入Z

 

在NVIDIA GPU Programming Guide,3.6节里讲到Nvidia的硬件 Early Z,不会渲染被挡住的部分,EarlyZ是默认启用的,但是不能Alpha Test&TexKill,也不能修改深度,,是为了让GPU可以用插值的深度值,下图为Gforce7的版本

关于EarlyZ

关于EarlyZ

关于EarlyZ

 

下图是Gforce8&9的版本,写了两种方法,一种是粗糙的ZCull,一种是细粒度的EarlyZ,配合使用 Double-Speed Z-Only,可以做到ZPrePass也加速,又能避免FS的OverDraw

关于EarlyZ

 

Alpha Test与Early Z

 

如果有Alpha Test就不会执行EarlyZ,

EarlyZ是在FS前写Z-Buffer,随后进行FS,只有深度等于/小于等于 ZBuffer的FS才可以被渲染,此时的深度是没有被Alpha Test Discard掉的部分fragment的Z-buffer,挡在后面的部分画不上去,所以有问题

这也是为什么说Alpha Test在部分显卡上会影响性能的原因,因为会使EarlyZ失效

在NVIDIA GPU Programming Guide8&9的版本里写到不会影响 coarse-z,但是会影响fine-grained z。

参考:

https://www.khronos.org/opengl/wiki/Early_Fragment_Test

https://software.intel.com/en-us/articles/early-z-rejection-sample

https://www.csee.umbc.edu/~olano/s2004c01/ch14.pdf

https://developer.amd.com/wordpress/media/2012/10/ShadingCourse2004_EarlyZ_Slides.pdf

https://developer.download.nvidia.com/GPU_Programming_Guide/GPU_Programming_Guide_G80.pdf

 

--------by wolf96 2018/12/14