Unity Shader Alpha Blend 填坑记录
这篇文章主要说的是关于Unity Shader 中对Alpha的Blend
Blend 透明度混合.通过参数来调整透明度,真正的透明效果.
Blend的位置在SubShader 中,CGPROGRAM前.用例如下
Shader "Example/Diffuse Bump" {
Properties {
_MainTex ("Texture", 2D) = "white" {}
_BumpMap ("Bumpmap", 2D) = "bump" {}
}
SubShader {
Tags { "RenderType" = "Opaque" }
==注意看这里==
Blend One One
CGPROGRAM
#pragma surface surf Lambert
// 略
ENDCG
}
Fallback "Diffuse"
}
好的.我们着重来看下Blend One One 部分
混合命令有一下这些:
参数 | 描述 |
---|---|
Blend Off | 关闭混合(默认) |
Blend SrcFactor DstFactor | 片元产生的颜色乘以SrcFactor,加上屏幕上已有的颜色乘以DstFactor,得到最终的颜色(写入颜色缓存),示例: float4 result = SrcFactor * fragment_output + DstFactor * pixel_color |
Blend SrcFactor DstFactor,SrcFactorA, DstFactorA | 同上,只不过使用单独的因子SrcFactorA和DstFactorA来混合透明度通道 |
BlendOp BlendOperation | 用其他的操作来取代加法混合 |
BlendOp OpColor,OpAlpha | 同上,只不过对于透明度通道使用不同的操作 |
测试在Unity 中 Blend SrcFactor DstFactor,SrcFactorA, DstFactorA 命令失效,unity只认 Blend SrcFactor DstFactor 这种形式, “,” 后面的参数不认,但是调试中发现Unity生成的是 Blend One One,One One 这样的4个参数的形式.很是不解
混合操作(BlendOp) | 具体操作 |
---|---|
Add | 加法:float4 result = SrcFactor * fragment_output + DstFactor * pixel_color |
Sub | 减法( 源-目标): float4 result = SrcFactor * fragment_output - DstFactor * pixel_color |
RevSub | 减法(目标-源): float4 result = DstFactor * pixel_color - SrcFactor * fragment_output |
Min | 较小值(逐个通道比较) |
Max | 较大值(逐个通道比较) |
常用的混合命令有:
Blend SrcAlpha OneMinusSrcAlpha // 传统透明度
Blend One OneMinusSrcAlpha // 预乘透明度
Blend One One // 叠加
Blend OneMinusDstColor One // 柔和叠加
Blend DstColor Zero // 相乘——正片叠底
Blend DstColor SrcColor // 两倍相乘
Blend 参数值说明. fragment_output 为片元产生的颜色,pixel_color为缓存区的颜色
Blend {code for SrcFactor} {code for DstFactor}
Code | 代表的值 |
---|---|
One | float4(1.0, 1.0, 1.0, 1.0) |
Zero | float4(0.0, 0.0, 0.0, 0.0) |
SrcColor | fragment_output |
SrcAlpha | fragment_output.aaaa |
DstColor | pixel_color |
DstAlpha | pixel_color.aaaa |
OneMinusSrcColor | float4(1.0, 1.0, 1.0, 1.0) - fragment_output |
OneMinusSrcAlpha | float4(1.0, 1.0, 1.0, 1.0) - fragment_output.aaaa |
OneMinusDstColor | float4(1.0, 1.0, 1.0, 1.0) - pixel_color |
OneMinusDstAlpha | float4(1.0, 1.0, 1.0, 1.0) - pixel_color.aaaa |
之前看过一些文章,误以为Blend One One 最后产生的值也会对透明度产生影响,后来经过实际测试,发现没有效果,因为按照公式 float4 result = SrcFactor * fragment_output + DstFactor * pixel_color
result是包括含透明度的,其实不然,虽然result包含透明度的值,但是最终呈现到屏幕后Alpha会被舍弃,而这一步是最后一步计算颜色的地方,所以One*fragment_output 得到的值还是原来的值,透明度没有被改变,
如果是 Blend SrcAlpha One,那么就变成了
Blend SrcAlpha One
result=fragment_output.aaaa*fragment_output.rgba+float4(1,1,1,1)*pixel_color
result=fragment_output(a*r,a*g,a*b,a*a)+pixel_color
颜色值与Alpha相乘,颜色值被改变.
先写到这里,有纰漏之处还望指教.
参考链接 https://en.wikibooks.org/wiki/Cg_Programming/Unity/Transparency