欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Unity Shader Alpha Blend 填坑记录

程序员文章站 2022-03-30 13:41:40
...

这篇文章主要说的是关于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

相关标签: Shader