candycat1992 / Unity_Shaders_Book

:book: 书籍《Unity Shader入门精要》源代码
5.48k stars 1.61k forks source link

关于Occlusion Culling 和Depth Test 、ShaderLab 中的 Cull 的疑问 #180

Closed haolly closed 6 years ago

haolly commented 6 years ago

今天看到16.5.3 节的遮挡剔除了,突然就有了疑问: 1,根据2.3.8 中所说,深度测试是可配置的,如果深度测试没有通过,那么这个片元就会被丢弃,这个和 遮挡剔除很是类似呀,如果物体A 在 物体 B的前面挡住了B,那么B的 物体的所有片元 的z 值都是小于 A 物体的,这个在 深度测试中就可以剔除了呀,为啥还需要 额外的 工作呢?(Occlusion Culling) 所以,按照我的理解,被不透明物体挡住的物体是不会被渲染的,但是从 Occlusion Culling 的存在来看,应该不是我所理解的这样。

2,另一个疑惑的地方是, Shader 中的 Cull 指令,unity 文档https://docs.unity3d.com/Manual/SL-CullAndDepth.html 中说

Back Don’t render polygons facing away from the viewer (default).

2.1,这个指令应该是对应配置了渲染流水线的某一个阶段吧?但是哪个阶段呢,有点不清楚 2.2,这里的多边形(polygons)是指组成模型的三角形吧? (是不是面向观察者应该是跟三角形的顶点顺序(顺时针/逆时针)定义有关),所以我的理解是: 例如立方体六个面的内面,他们都是三角形的背面,所以不会被渲染,如果三角形某一个面是透明的,那么就可以看到立方体的内部,所以设置 Cull Off 就可以把内面渲染出来。

2.3,根据8.7 节第一段所说:

默认情况下渲染引擎剔除了物体的背面(相对于摄像机的方向)的渲染图元,而只渲染了物体的正面。

根据上面所说,这里的多边形应该就是指模型本身了吧? 但问题是,例如一个正方体,如果三角形是背对着观察者的,那么他的 Z 坐标应该就是大于正对着观察者的面的,然后应该就被 深度测试的时候给剔除掉了,所以,Cull 这个指令的作用应该是啥?

怎么看书看着看着就越来越糊涂了。。。。。 乐乐要是觉得回答这些问题太蠢了,可以直接甩我几个相关的链接或者书名之类的,我自己再慢慢看

MyLostBear commented 6 years ago

1:unity里的Occlusion Culling是由CPU完成的

2.1:图元装配之后,片元着色器之前 2.2:没看明白问题,使用见书8.7节 2.3:无论正面反面,Z值都是相同的,因为“三角形”是没有厚度的,所以不存在“背面Z坐标大”这一问题。而且深度测试在face culling之后,按渲染流水线的流程来说,会先剔除背面,再做深度测试。

candycat1992 commented 6 years ago
  1. Occlusion Culling的比较单位都比较大,比如逐物体,而渲染遮挡的前后关系是要精确到pixel级别的比较才可以保证最后效果是正确的。所以一般是先用Occlusion Culling来在大尺度上进行剔除,减少GPU的工作,最后再由GPU来完成像素级的排序。

2.1 这个指令一般是发生在光栅化之前的图元装配阶段(Primitive assembly),你可以参考OpenGL的Pipeline

2.2 你应该是问face culling的具体实现,这个可以参考wiki

2.3 你可以看@bcydl0116的回答,再结合wiki看下具体face culling是怎么算的。

haolly commented 6 years ago

三角形确实是没有正反面的,谢谢 @bcydl0116 OpenGL 的 wiki 真的很有帮助,谢谢 @candycat1992