unityshader入门精要8.4代码(透明度混合)

透明度混合

半透明必须关闭深度写入

把自身颜色和已经存在于颜色缓存区中的颜色值进行混合

先渲染背景,然后把半透明物体从后往前渲染,这里关闭了深度写入,颜色缓存区是写入的背景颜色,再将前面的颜色按混合因子和缓存区的颜色混合。

Shader "Custom/6"
{
	
	//透明度混合
	//半透明必须关闭深度写入
	//把自身颜色和已经存在于颜色缓存区中的颜色值进行混合
	

	Properties
	{
		_Color("Main Tint", Color) = (1,1,1,1)
		_MainTex("Main Tex",2D) = "white"{}
		_AlphaScale("Alpha Scale", Range(0,1)) = 1
	}

	SubShader
	{
		Tags{"Queue" = "Transparent" " IgnoreProjector" = "true" "RenderType" = "Transparent"}

		 把模型的深度信息写入深度缓冲中,从而剔除模型中被自身遮挡的片元
		Pass {
			ZWrite On
			ColorMask 0
		}

		Pass
		{
			Tags{"LightMode" = "ForwardBase"}

			ZWrite Off
			Blend SrcAlpha OneMinusSrcAlpha 
			//将该片元着色器中产生的颜色的混合因子设为SrcAlpha
			//把已存在颜色缓存中的混合因子设为OneMinusSrcAlpha

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



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

			struct a2v
			{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 texcoord : TEXCOORD0;
			};

			struct v2f
			{
				float4 pos : SV_POSITION;
				float2 uv : TEXCOORD0;
				float3 worldNormal : TEXCOORD1;
				float3 worldPos : TEXCOORD2;
			};

			v2f vert(a2v v)
			{
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				o.worldNormal = UnityObjectToWorldNormal(v.normal);
				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;

				o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);

				return o;
			}

			fixed4 frag(v2f i) : SV_Target 
			{
				fixed3 worldNormal = normalize(i.worldNormal);
				fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));

				fixed4 texColor = tex2D(_MainTex,i.uv);

				fixed3 albedo = texColor.rgb * _Color.rgb;

				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;

				fixed3 diffuse = albedo * _LightColor0.rgb * max(0,dot(worldNormal,worldLightDir));

				return fixed4(ambient + diffuse ,texColor.a * _AlphaScale);
				
				//fixed4 中的四个元素是rgba,第四个是a透明度
			}

			ENDCG
		}
	}
	FallBack "Transparent/VertexLit"

}

 

ZWrite Off  取消深度写入
Blend SrcAlpha OneMinusSrcAlpha 

将该片元着色器中产生的颜色的混合因子设为SrcAlpha
把已存在颜色缓存中的混合因子设为OneMinusSrcAlpha

 Orgba = SrcFactor * Srgba + DstFactor * Drgba

Unity中,使用Blend命令,设置混合状态同时开启了混合。

使用BlendOP BlendOperation 混合操作命令

通过混合操作和混合因子命令的组合,可以得到以下的几种效果:

 

Question:正方体背后的透明颜色为什么不加入计算?

默认情况下渲染引擎剔除了物体背面的渲染图元,而只渲染了物体的正面。如果想要获得双面渲染的效果,可以使用Cull指令来控制需要剔除哪个面的渲染图元。

Cull off

Shader "Custom/6"
{
	
	//透明度混合
	//半透明必须关闭深度写入
	//把自身颜色和已经存在于颜色缓存区中的颜色值进行混合
	

	Properties
	{
		_Color("Main Tint", Color) = (1,1,1,1)
		_MainTex("Main Tex",2D) = "white"{}
		_AlphaScale("Alpha Scale", Range(0,1)) = 1
	}

	SubShader
	{
		Tags{"Queue" = "Transparent" " IgnoreProjector" = "true" "RenderType" = "Transparent"}
		
		//第一个Pass只渲染背面
		 
		Pass
		{
			Tags{"LightMode" = "ForwardBase"}

			Cull Front

			ZWrite Off
			Blend SrcAlpha OneMinusSrcAlpha 
			//将该片元着色器中产生的颜色的混合因子设为SrcAlpha
			//把已存在颜色缓存中的混合因子设为OneMinusSrcAlpha
			

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

			

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

			struct a2v
			{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 texcoord : TEXCOORD0;
			};

			struct v2f
			{
				float4 pos : SV_POSITION;
				float2 uv : TEXCOORD0;
				float3 worldNormal : TEXCOORD1;
				float3 worldPos : TEXCOORD2;
			};

			v2f vert(a2v v)
			{
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				o.worldNormal = UnityObjectToWorldNormal(v.normal);
				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;

				o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);

				return o;
			}

			fixed4 frag(v2f i) : SV_Target 
			{
				fixed3 worldNormal = normalize(i.worldNormal);
				fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));

				fixed4 texColor = tex2D(_MainTex,i.uv);

				fixed3 albedo = texColor.rgb * _Color.rgb;

				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;

				fixed3 diffuse = albedo * _LightColor0.rgb * max(0,dot(worldNormal,worldLightDir));

				return fixed4(ambient + diffuse ,texColor.a * _AlphaScale);
				
				//fixed4 中的四个元素是rgba,第四个是a透明度
			}

			ENDCG
		}

		//第二个Pass只渲染正面

		Pass
		{
			Tags{"LightMode" = "ForwardBase"}

			Cull Back

			ZWrite Off
			Blend SrcAlpha OneMinusSrcAlpha 
			//将该片元着色器中产生的颜色的混合因子设为SrcAlpha
			//把已存在颜色缓存中的混合因子设为OneMinusSrcAlpha
			

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

			

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

			struct a2v
			{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 texcoord : TEXCOORD0;
			};

			struct v2f
			{
				float4 pos : SV_POSITION;
				float2 uv : TEXCOORD0;
				float3 worldNormal : TEXCOORD1;
				float3 worldPos : TEXCOORD2;
			};

			v2f vert(a2v v)
			{
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				o.worldNormal = UnityObjectToWorldNormal(v.normal);
				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;

				o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);

				return o;
			}

			fixed4 frag(v2f i) : SV_Target 
			{
				fixed3 worldNormal = normalize(i.worldNormal);
				fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));

				fixed4 texColor = tex2D(_MainTex,i.uv);

				fixed3 albedo = texColor.rgb * _Color.rgb;

				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;

				fixed3 diffuse = albedo * _LightColor0.rgb * max(0,dot(worldNormal,worldLightDir));

				return fixed4(ambient + diffuse ,texColor.a * _AlphaScale);
				
				//fixed4 中的四个元素是rgba,第四个是a透明度
			}
			ENDCG
			}

	}
	FallBack "Transparent/VertexLit"

}

复制粘贴pass。两个pass中,一个Cull Front只渲染背面,一个Cull Back只渲染正面,按顺序执行pass 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值