科普向,Shader中“深度”的理解和思考(附例子)

经常看到深度测试啊,深度图啊,但这个名字和它的用途其实让人很难联想到一块去。 
        这个不是高级议题,只不过很多高级议题会涉及到它,所以还是稍微写下,权当笔记。 
        首先随手建立两个物体: 
        
       其中一个cube里面包含一个圆体,为何会呈现上面的样子呢,引擎是这么去做的: 
      1.由于我设置的队列是透明队列,所以引擎保证绘制顺序是从远到近。当然对当前这个例子来说,不论是从远到近还是从近到远,绘制结果都是一样的。那么我们假定先画cube,再画圆体。 
      2.注意,1中所谓的画,并不是真的直接在屏幕上直接画出来,而是在考虑接下来的步骤的时候的处理顺序。 
       
3.首先顶点着色器执行完毕,然后开始进行深度测试和背面剔除。背面剔除就是如果这个面试朝后的,那么摄像机就看不到,所以不用画。我们主要看下深度测 
试。所谓深度测试,就是将当前的深度值和深度缓冲中的深度值进行比较,以确定是否要剔除还是保留当前的绘制片段。你可以简单理解成,最靠近摄像机的才会被 
绘制。但是这种抽象的理解不利于你去理解一些特殊的效果(后面会提到),所以还是要明确下具体的步骤: 
       绘制cube的时候,深度缓冲中的是底部的Plane,毫无疑问,cube是更靠近摄像机的,所以深度缓冲更新为cube的深度。 
       绘制圆体的时候,深度缓冲中的是cube的深度,那么圆体的上部分没有被遮住,所以绘制,下面的被遮住了,所以不绘制。此时,屏幕中有一部分的深度缓冲被更新成圆体的深度。 
       
       这样整个过程就结束了。然后看下shader中涉及深度的指令:ZTest 和 ZWrite. 
       ZTest就是指定如何进行深度测试,比如你可以指定不论如何 
永远绘制,那么这个物体将永远是不剔除的,当然有可能还是会被挡住,这就是因为所谓的永远不剔除只是在过程上不去剔除它,但绘制的时候,如果后面绘制的物 
体覆盖住了它,它还是会被挡住(可能描述的不够清楚,但我是为了说明不要从字面的意思去理解这个指令,而要理解它对绘制过程的影响,这样对后面的效果才会 
明白如何做到的)。 
       ZWrite就是表示是否写入深度缓冲,比如刚才,我们屏幕上的深度缓冲的更新,就是因为ZWrite是默认开启的。 
       理论总是比较枯燥和不知所谓,还是配合例子一起看吧。 
       首先,我们把Ztest调节成Greater,就变成了这样: 
      
      这个就是让被挡住的反而绘制出来。那么这个是啥用处,比如这个效果: 
    
      其实就是让遮挡的部位换一种着色方法。那么我们也可以马上利用ZTest实现类似的效果: 
      
被挡住的部分我着色器用绿色,不挡住的部分着色器用蓝色。唯一要注意的是,被挡住的部分ZWrite要关闭。因为假设你开启了ZWrite,那么你 
想一下我们上面的步骤,当绘制绿色部分的时候,假设深度值被写入了,那么蓝色在比较深度的时候,就会被画出来,那么被挡住的绿色就被蓝色覆盖了。 
     再看一个很多人碰到的情况,就是半透明的时候,物体内部显示出来,例如: 
    
这是因为半透明物体在绘制的时候,会根据当前的值和背景alpha混合,并不是我覆盖你就不绘制你,而是我根据当前的颜色和被我覆盖的进行剔除。那么这个怎么办呢,也很简单,就是在前面增加一个Pass{colormask 0}这样就可以了。 
     效果如下: 
    
这是因为第一个pass干扰了绘制过程,让深度缓冲中已存在当前的深度值,这样就会去剔除内部了。 

如果以上的东西你都能理解,说明你已经明白了深度的概念和意义,就可以开始利用他们实现一些非常有意思的效果了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值