Unity Shader入门精要笔记(十六):透明相关概念

本系列文章由Aimar_Johnny编写,欢迎转载,转载请标明出处,谢谢。

https://blog.csdn.net/lzhq1982/article/details/82710020

 

从这节开始说透明,透明有两种表达方式,一种是透明度测试(Alpha Test),一种是透明度混合(Alpha Blending)。前者只有透明和不透明两种效果,不存在半透,后者有半透效果。

在说透明前,要重点说明渲染顺序,对于不透明(opaque)物体,我们不需要考虑它的渲染顺序,因为深度缓冲区(depth buffer)已经帮我们处理好了,它会根据片元深度值和深度缓冲中的值作比较(开启深度测试情况下),当其值距摄像机更远时,则不会渲染,否则会覆盖掉颜色缓冲中的像素,并把深度值更新到深度缓冲中(开启深度写入情况下)。

但透明就不能这么做了,下面说明透明度测试和透明度混合的原理。

透明度测试

当片元的透明度小于我们设定的阈值时,它就会被舍弃,则不会参与绘制,否则会被当做不透明处理,进行深度测试,深度写入等。所以透明度测试是不需要关掉深度写入的。除了会舍弃片元,其实和不透明物体渲染差不多。

透明度混合

这种方法可以得到真正的半透效果。它会使用当前片元的透明度作为混合因子,与颜色缓冲中的颜色进行混合,得到新的颜色。这里需要注意,透明度混合需要关闭深度写入。但没有关闭深度测试,所以当混合渲染一个片元时,它还是会比较它的深度和深度缓冲中的深度,如果它的深度值离摄像机更远,则不再进行混合操作。所以当透明物体在不透明物体后面时,透明物体就不会混合了。所以对于透明度混合来说,深度缓冲只是可读的。

为什么透明度混合要关闭深度写入呢?如果不关闭深度写入,一个半透明表面背后的表面本来是可以透过它被看到的,但由于深度测试时该半透明表面离摄像机更近,导致后面的表面会被剔除,那就无法透过半透明表面看到后面物体了。但是这样也同时破坏了深度缓冲的工作机制,所以渲染顺序就非常重要了。

看下图:

根据上图我们看看不同的渲染顺序会有什么结果:

1、先渲染B,再渲染A,由于不透明物体开启了深度测试和写入,所以B会先写入颜色缓冲和深度缓冲。然后渲染A,深度测试发现A离摄像机更近,则用A的透明度来和颜色缓冲中的B的颜色混合,得到正确结果。

2、先渲染A,再渲染B,A是半透,则先写入颜色缓冲,但不会写入深度缓冲。再渲染B,由于深度缓冲没有值,则B直接写入深度缓冲,进而直接写入颜色缓冲,则覆盖了A,这个效果不是我们想要的。

所以我们应该在不透明物体渲染完之后再渲染半透物体。

那么如果都是半透物体,渲染顺序还重要吗?答案是肯定的。

1、先渲染B,再渲染A,则B先写入颜色缓冲,然后A会和颜色缓冲中的B进行混合,得到正确结果。

2、先渲染A,再渲染B,则A先写入颜色缓冲,随后B会和A进行混合,这样混合结果就反过来了,得到错误结果。

基于以上说明,渲染引擎一般会先对物体进行排序,再渲染。常用方法是:

1、先渲染不透明物体,并开启它们的深度测试和写入。

2、把半透明物体按它们离摄像机远近排序,然后按照从后往前的顺序渲染,开启深度测试,关闭深度写入。

 

下面我们看看unity的渲染顺序:

Unity提供了自己的渲染队列(render queue),可以用SubShader的Queue标签来决定模型属于哪个渲染队列。内部用一系列整数索引来表示每个渲染队列,索引号越小越早被渲染。如下表:

因此,如果用透明度测试实现透明效果,可以设置如下标签:

SubShader{
    Tags { "Queue" = "AlphaTest" }
    Pass {
        ...
    }
}

同样,透明度混合如下:

SubShader{
    Tags { "Queue" = "Transparent" }
    Pass {
        ...
    }
}

后面章节详细介绍透明度测试和透明度混合。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值