科普向,Shader中“深度”的理解和思考(附例子)
yxriyin
yxriyin 4591 6
精华加亮 Shader 着色器 2016-01-17 22:14
经常看到深度测试啊,深度图啊,但这个名字和它的用途其实让人很难联想到一块去。
        这个不是高级议题,只不过很多高级议题会涉及到它,所以还是稍微写下,权当笔记。
        首先随手建立两个物体:
        

图片:1.png


       其中一个cube里面包含一个圆体,为何会呈现上面的样子呢,引擎是这么去做的:
      1.由于我设置的队列是透明队列,所以引擎保证绘制顺序是从远到近。当然对当前这个例子来说,不论是从远到近还是从近到远,绘制结果都是一样的。那么我们假定先画cube,再画圆体。
      2.注意,1中所谓的画,并不是真的直接在屏幕上直接画出来,而是在考虑接下来的步骤的时候的处理顺序。
      
3.首先顶点着色器执行完毕,然后开始进行深度测试和背面剔除。背面剔除就是如果这个面试朝后的,那么摄像机就看不到,所以不用画。我们主要看下深度测
试。所谓深度测试,就是将当前的深度值和深度缓冲中的深度值进行比较,以确定是否要剔除还是保留当前的绘制片段。你可以简单理解成,最靠近摄像机的才会被
绘制。但是这种抽象的理解不利于你去理解一些特殊的效果(后面会提到),所以还是要明确下具体的步骤:
       绘制cube的时候,深度缓冲中的是底部的Plane,毫无疑问,cube是更靠近摄像机的,所以深度缓冲更新为cube的深度。
       绘制圆体的时候,深度缓冲中的是cube的深度,那么圆体的上部分没有被遮住,所以绘制,下面的被遮住了,所以不绘制。此时,屏幕中有一部分的深度缓冲被更新成圆体的深度。
      
       这样整个过程就结束了。然后看下shader中涉及深度的指令:ZTest 和 ZWrite.
       ZTest就是指定如何进行深度测试,比如你可以指定不论如何
永远绘制,那么这个物体将永远是不剔除的,当然有可能还是会被挡住,这就是因为所谓的永远不剔除只是在过程上不去剔除它,但绘制的时候,如果后面绘制的物
体覆盖住了它,它还是会被挡住(可能描述的不够清楚,但我是为了说明不要从字面的意思去理解这个指令,而要理解它对绘制过程的影响,这样对后面的效果才会
明白如何做到的)。
       ZWrite就是表示是否写入深度缓冲,比如刚才,我们屏幕上的深度缓冲的更新,就是因为ZWrite是默认开启的。
       理论总是比较枯燥和不知所谓,还是配合例子一起看吧。
       首先,我们把Ztest调节成Greater,就变成了这样:
      

图片:2.png


      这个就是让被挡住的反而绘制出来。那么这个是啥用处,比如这个效果:
    

图片:3.png


      其实就是让遮挡的部位换一种着色方法。那么我们也可以马上利用ZTest实现类似的效果:
      

图片:4.png


被挡住的部分我着色器用绿色,不挡住的部分着色器用蓝色。唯一要注意的是,被挡住的部分ZWrite要关闭。因为假设你开启了ZWrite,那么你
想一下我们上面的步骤,当绘制绿色部分的时候,假设深度值被写入了,那么蓝色在比较深度的时候,就会被画出来,那么被挡住的绿色就被蓝色覆盖了。
     再看一个很多人碰到的情况,就是半透明的时候,物体内部显示出来,例如:
    

图片:5.png


这是因为半透明物体在绘制的时候,会根据当前的值和背景alpha混合,并不是我覆盖你就不绘制你,而是我根据当前的颜色和被我覆盖的进行剔除。那么这个怎么办呢,也很简单,就是在前面增加一个Pass{colormask 0}这样就可以了。
     效果如下:
    

图片:6.png


这是因为第一个pass干扰了绘制过程,让深度缓冲中已存在当前的深度值,这样就会去剔除内部了。

如果以上的东西你都能理解,说明你已经明白了深度的概念和意义,就可以开始利用他们实现一些非常有意思的效果了。
2条评分, 鲜花+501
分享:
游客
要评论请先登录 或者 注册
mayaformaya 学徒 2016-01-18 00:10 1楼
谢谢,受益很多~
tf107 学者 2016-01-18 10:46 2楼
嗯、 讲的很明白。多谢!
wangyel1 大师 2016-01-19 21:23 3楼
感谢分享
shader的东西总数感觉很抽象,就少你这种讲解的方式啊
magicer 学徒 2016-01-26 13:43 4楼
非常感谢  不错
happens32 学徒 2016-03-01 17:21 5楼
最后关于Transparent的互相影响问题,我加了Pass{ColorMask 0}反而增加了互相影响的范围。求解
wst3618 学徒 2016-03-08 15:15 6楼
666666 666666 666666 666666 666666 666666
返回顶部