关于透明度测试,主要是通过clip函数来实现裁剪功能
函数:void clip(float4 x);void clip(float3 x);void clip(float2 x);void clip(float x).
如果指定的一个参数为负数,就会舍弃当前像素的输出颜色
SubShader {
Tags {“Queue”=“AlphaTest” “IgnoreProjector”=“True” “RenderType”=“TransparentCutout”}
Pass {Tags { "LightMode"="ForwardBase" }......fixed4 frag(v2f i) : SV_Target {...clip (texColor.a - _Cutoff);...}这里就是通过对该像素采样后的alpha通道来进行alpha测试,来决定该像素是否参与渲染。
透明度混合:简单理解,就是加了alpha通道混合,来实现透明度->a通道为1就不透明,为0就透明的线性计算。
这里列的都是要注意的地方:
SubShader {
Tags {“Queue”=“Transparent” “IgnoreProjector”=“True” “RenderType”=“Transparent”}
…
…
Pass{
…
Blend SrcAlpha OneMinusSrcAlpha
…
}
这里是要设置两个比较重要的参数,一个是设置alpha,一个是原本的材质,其实说白了,就是photoshop里,调透明度的效果,设置的alpha与原本的材质混合,得到的就是ps里设置的alpha(透明度效果)。
看嘛,不就是这个意思,很简单。
但注意的是,上面的两个东西,都没有开启深度写入,也就是说,如果存在遮挡关系,就会出现遮挡关系错误(在后面的跑前面了,或者就看不出谁前谁后)。
为了解决这个问题,下面是开启深度写入的透明度混合:
这里是两个Pass,
Pass1:开启深度写入,但不输出颜色,目的是将该模型的深度值写入到深度缓存种
Pass2:进行正常的透明度混合,因为上个pass已经得到了逐像素的正确深度信息
我的理解是第一个pass就是为了理清深度关系(遮挡),第二个pass才是真正的实现透明效果的。
不输出颜色,也是为了保留只是深度的原因。
第一个pass:
Pass {
ZWrite On
ColorMask 0
}
第二个pass:
…
Pass {
Tags { “LightMode”=“ForwardBase” }
ZWrite OffBlend SrcAlpha OneMinusSrcAlpha...
第二个pass就和之前的透明度混合是一样的。
此外补充的是关于Blend的操作,
使用的公式就是原先的颜色信息混合因子 操作符 模板里的颜色信息混合因子。
这里又要对比到PS里了,如果学过的话就非常容易对比到图像的变化上,玩过ps的应该都知道PS的图层可以选择混合模式,这里就是那些混合模式的计算。
双面的透明度渲染:
上一个透明度混合,已经得到了较为正确的透明度混合,但还是存在缺点,如果是单个物体的正面和背面的深度渲染顺序,采用一个个物体整体的深度,就会造成单体的正反面存在问题。但我们希望的是背面总是在正面之前渲染,对此的话,就不会造成背面跑到正面前面或者重叠的情况!
怎么弄呢? 在渲染透明里有个基本概念,就是大家都是透明的,你想让我表现在前面,那你就让我后渲染(原因是透明计算,需要对模板里的颜色信息进行混合,也就是上面扯了这么多的Blend操作)。
所以在上述的代码上要添加一些修改,目的就是,在只写入深度的时候,把正面剔除,只渲染反面。
Pass1和pass2的代码都和上面的pass2一样,但pass1里变成了cull front,pass2为cull back
SubShader {
Tags {“Queue”=“Transparent” “IgnoreProjector”=“True” “RenderType”=“Transparent”}
Pass {Tags { "LightMode"="ForwardBase" }// First pass renders only back faces Cull FrontZWrite OffBlend SrcAlpha OneMinusSrcAlpha...}..Pass {Tags { "LightMode"="ForwardBase" }// Second pass renders only front faces Cull BackZWrite OffBlend SrcAlpha OneMinusSrcAlpha}
这里的思想非常简单,就是最直接的,想让我在前,你让我最后渲染就行了呗的思想(unity里subshader里的pass是按顺序执行的)