以下是一个支持半透明阴影的Shader代码示例,你可以参考一下:
- Shader "Custom/AlphaShadow" {
- Properties {
- // 阴影贴图
- _ShadowTex ("Shadow Texture", 2D) = "white" {}
- // 阴影颜色
- _ShadowColor ("Shadow Color", Color) = (0, 0, 0, 0.5)
- }
- SubShader {
- Tags {"Queue"="Transparent"}
- Pass {
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment frag
- #include "UnityCG.cginc"
- struct appdata_t {
- // 顶点坐标
- float4 vertex : POSITION;
- // 纹理坐标
- float2 uv : TEXCOORD0;
- // 用于传递阴影纹理坐标的变量
- float2 uv2 : TEXCOORD1;
- };
- struct v2f {
- // 插值后的纹理坐标
- float2 uv : TEXCOORD0;
- // 插值后的阴影纹理坐标
- float2 uv2 : TEXCOORD1;
- // 插值后的半透明颜色及透明度
- fixed4 color : COLOR;
- };
- sampler2D _MainTex;
- sampler2D _ShadowTex;
- fixed4 _ShadowColor;
- v2f vert (appdata_t v) {
- v2f o;
- // 传递顶点坐标及纹理坐标
- o.vertex = UnityObjectToClipPos(v.vertex);
- o.uv = v.uv;
- // 传递阴影纹理坐标
- o.uv2 = v.uv2;
- // 计算顶点的半透明颜色及透明度
- o.color = tex2D(_MainTex, v.uv);
- return o;
- }
- fixed4 frag (v2f i) : SV_Target {
- // 采样阴影贴图
- half4 shadowColor = tex2D(_ShadowTex, i.uv2);
- // 将半透明颜色与阴影颜色混合
- fixed4 color = lerp(i.color, _ShadowColor, shadowColor.a);
- // 输出混合后的颜色
- return color;
- }
- ENDCG
- }
- }
- FallBack "Diffuse"
- }
复制代码
这个Shader有两个属性,一个是阴影贴图,一个是阴影颜色。在顶点着色器中传递了一个额外的变量uv2,用于传递阴影纹理坐标。在片段着色器中先采样阴影贴图,根据采样得到的阴影颜色值和半透明颜色值进行线性插值,得到最终的混合后的颜色输出。
值得注意的是,这个示例Shader仅支持阴影贴图带有透明通道的情况,如果阴影贴图没有透明通道你需要对上面的`lerp`函数进行改写。
提供单独的半透明材质渲染时,需要将渲染队列设置为"Queue"="Transparent"或"Queue"="AlphaTest"。另外,如果你的场景有其他透明物体,则需要控制半透明材质的渲染顺序,避免深度测试问题产生的阴影错误。 |