Diffuse Shader 添加Alpha通道,并接受场景烘培(LightMap)

原创
2019/11/09 18:00
阅读数 1.5K

我们在做手机游戏开发过程中经常使用 Diffuse shader,并对场景进行烘培,这样能用很低的消耗达到不错的效果。 DiffuseShader 不能设置Alpha通道,在实际开发过程中遇到需要透明,或者实现渐隐效果。

全部Shader代码如下


Shader "Mobile/Diffuse_Aplha" {
		Properties{
			_Color("Color",Color) = (1,1,1,1)
			_MainTex("MainTex",2D) = "white"{}
			_AlphaScale("AlphaScale",Range(0,1)) = 1
		}
			SubShader{
				Tags{"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent"}
				//"RenderType"="Transparent"指明该shader为使用了透明度混合的shader

				//开启深度写入的Pass是为了将模型的深度信息写入深度缓冲中,从而剔除模型中被自身遮挡的片元
				Pass{
					ZWrite On
					ColorMask 0
				}
				Pass{
					//Tags{"LightMode" = "ForwardBase"}

					Zwrite Off  //关闭深度写入
					Blend SrcAlpha OneMinusSrcAlpha  //设置混合因子为源的透明度 

					CGPROGRAM
					#pragma vertex vert
					#pragma fragment frag
					#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
					#include "Lighting.cginc"


					fixed4 _Color;
					sampler2D _MainTex;
					float4 _MainTex_ST;
					fixed   _AlphaScale;

					struct a2v {
						float4 vertex : POSITION;
						float2 uv : TEXCOORD0;
						float2 uv1 : TEXCOORD1;
					};

					struct v2f {
						float4 vertex:SV_POSITION;
						float2 uv:TEXCOORD0;
#ifdef LIGHTMAP_ON
						float2 uvLM : TEXCOORD1;
#endif
					};


					v2f vert(a2v v) {
						v2f o;
						o.vertex = UnityObjectToClipPos(v.vertex);
						o.uv = TRANSFORM_TEX(v.uv, _MainTex);
#ifdef LIGHTMAP_ON
						o.uvLM = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
#endif
						return o;
					}

					fixed4 frag(v2f i) :SV_Target{
						fixed4 col = tex2D(_MainTex, i.uv);
						col = col * _Color;
#ifdef LIGHTMAP_ON
						fixed3 lm = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, i.uvLM));
						col.rgb *= lm;
#endif
						return fixed4(col.rgb, _AlphaScale);

					}
					ENDCG
				}
			}
		FallBack "Transparent/VertexLit"
}

首先我们需要透明,我们需要渲染队列 "Queue" = "Transparent"

接受场景烘培贴图 加入编辑指令 #pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON

(#ifdef LIGHTMAP_ON ) 处理LightMap 代码

这里为什么要用DecodeLightmap又要用UNITY_SAMPLE_TEX2D来解读ligtmap呢?

实际上unity生成的lightmap的有两种编码格式:doubleLDR和RGBM

Unity使用了两种编码方式来存储lightmap:

1、doubleLDR,需要一张rgb24贴图 2、RGBM,需要一张rgba32贴图

在移动设备上使用doubleLDR格式,可以获得更快的计算速度。它只用到了lightmap的RGB通道。

PC上则使用RGBM格式,可以获得更广的亮度范围,而牺牲一点速度。它使用了贴图的RGBA通道,而A通道是用来做乘法,所以称为RGBM格式。

这两种格式的差异就是导致不同平台下lightmap表现不同的原因,当然Unity会在切换平台时帮我们对贴图进行转换,而不需要太关心这个差异。

展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部