——内容源自唐老狮的shader课程
目录
1.必备知识
1.1.用到的标签与状态
深度缓冲:记录像素的深度值,之后用于比较,决定片元(颜色)去留
深度测试:将当前片元深度值混合深度缓冲中深度值进行比较,决定片元(颜色)去留
渲染队列:确定物体的渲染顺序
混合方式:将通过深度测试的片元颜色和颜色缓冲区中的颜色按指定算法进行混合,并更新颜色缓冲区
1.2.渲染顺序的重要性
处理透明混合的时候,需要关闭深度写入,因为如果不关闭,后面的物体就无法通过深度测试,进而导致颜色丢失。而图形学中模拟出半透明效果靠的就是多个颜色混合计算。
开启深度写入和深度测试的好处:无需关心不透明物体的渲染顺序,否则就必须注意这方面
所以我们就要设置正确的渲染顺序,以获得正确的效果,我们采取的方法是:
(1).先渲染不透明物体,开启它们的深度写入和深度测试
(2).将半透明物体按照距离摄像机的远近进行排序,然后由后往前地渲染他们,并开启深度测试关闭深度写入,排序是基于物体而非片元。
这个方法在一些情况下会出现问题,如奥运五环和上下斜放,即一些从摄像机角度看有部分重叠的物体,解决方法有:
(1)接收瑕疵
(2)拆分模型
(3)使用开启深度写入的半透明效果来模拟半透明(性能消耗较高)
1.3.设置深度写入
在Pass或者SubShader中写ZWrite Off即可,因为它是个渲染状态,但由于我们需要在指定Pass中关闭,所以在Pass写该状态
1.4.设置渲染队列
一般在SubShader中进行书写
渲染队列通过标签"Queue"来设置,他一般与其他标签配合使用
IgnoreProjector(忽略投影器)标签:
投影器是unity中一种特殊的光源,它用于在场景中投射纹理(Texture)或简单的几何形状(如圆形或方形)来模拟光照,阴影或其他视觉效果
这里要将其开启
RenderType(渲染类型)标签:
对着色器进行分类,用于着色器替换功能。有五种类型:Opaque(不透明),Transparent(透明),TransparentCutout(透明切割),Background(背景),Overlay(覆盖)
这里按需求设置
1.5.设置混合命令
混合默认为关闭
1.5.1.什么是混合
当片元通过了深度测试后,就会进入混合流程。此时,当前片元的颜色被称为源颜色,颜色缓冲区的颜色称为目标颜色。
而混合就是将源颜色和目标颜色用对应的混合算法进行计算后,输出一个新的颜色并更新到颜色缓冲区中
1.5.2.混合的计算规则
该计算的规则就是构建两个混合等式
(1).RGB通道的混合等式:O.rgb(输出颜色) = 源因子 * S(原颜色).rgb + 目标因子 * D(目标颜色).rgb
(2).A通道的混合等式:O.a = 源透明因子 * S.a + 目标透明因子 * D.a
1.6.混合的计算规则——混合因子(渲染状态)
基本格式:Blend 源因子 目标因子,源透明因子 目标透明因子
Blend SrcAlpha OneMinusSrcColor, One Zero(例)
省略格式:Blend 源因子 目标因子
这会让源透明因子 = 源因子,目标透明因子 = 目标因子
带Src的与源因子有关,带Dst的与目标因子有关
BlendOp也可设置混合因子
2.混合度测试
2.1.作用
处理那些需要一部分完全透明而另一部分完全不透明的情况。如树叶,栅栏等
2.2.基本原理
声明一个阈值(_Cutout),用它来和片元携带的颜色的a值(透明度)进行比较,当a小于该阈值时,就将该片元丢弃,反之则保留。丢弃的部分会按照不透明物体的方式来处理,其也不会对颜色缓冲区有任何影响
2.3.实现
使用 clip(参数) 函数进行判断,参数可以是float4,3,2以及float等;参数只要有一个分量为负数,那么就会舍弃该片元。其内部实现会用到到一个discard指令,代表剔除该片元,不参与渲染
标签里需要将Queue设置为AlphaTest,RenderType设置为TransparentCutout

3.透明度混合
3.1.作用
主要用来处理半透明效果,如玻璃
3.2.基本原理
关闭深度写入,开启混合,让片元颜色和颜色缓冲区的颜色能够进行混合计算
3.3.实现
1.关闭深度写入,设置混合为 Blend SrcAlpha OneMinusSrcAlpha,渲染队列设置为Transparent
2.声明一个0~1区间上的_AlphaScale 用于控制对象整体透明度
3.片元着色器的返回值的a值修改为 tex.a * _AlphaScale

4.开启了深度写入的半透明效果
4.1.作用
用于本身较为复杂(有前后关系)的模型,这类模型在关闭深度写入时会出问题
4.2.基本原理
使用俩Pass渲染通道来处理渲染逻辑
第一个Pass:开启深度写入,使用颜色遮罩(这是个渲染状态,ColorMask 0表示不输出颜色,ColorMask RB表示只写入红色和蓝色通道)不输出颜色,目的是让模型各片元的深度值写入深度缓冲
第二个Pass:正常进行透明度混合
在这种情况下,第一个Pass会执行深度测试并进行深度写入,如果该片元没有通过深度测试则会被直接抛弃,不会执行第二个Pass
//这个是第一个Pass
Pass
{
ZWrite On
ColorMask 0
}

5.双面渲染的透明效果
5.1.作用
对于现实中的半透明物体,我们是可以从外部看到其内部结构的。而这个就是用来干这个的
5.2.基本原理
对于透明度混合:搞俩Pass,一个渲染正面,使用渲染状态(剔除指令) Cull Back;一个渲染背面 ,使用渲染状态 Cull Front
对于透明度测试:由于其不需要混合,所以直接把剔除关了就行,使用 Cull Off
