unityshader入门精要8.3代码(透明度测试)

渲染引擎一般会先对物体进行排序再渲染

1.先渲染所有不透明物体,开启深度测试和深度写入(Geometry)

2.把半透明物体按照距离远近进行排序,按照从后往前的顺序渲染半透明物体,并开启深度测试,关闭深度写入(Transparent)

但是仍然会存在问题

Shader "Unlit/5"
{
   Properties
   {
		_Color("Main Tint",Color) = (1,1,1,1)
		_MainTex("Main Tex",2D) = "white"{}
	
		//Cutoff决定调用clip进行透明度测试时使用的判断条件
		_Cutoff("Alpha Cutoff",Range(0,1)) = 0.5
   }


   SubShader
   {
		//AlphaTest透明度测试队列 -
		
		//RenderType标签让Unity把shader归入到TransparentCutout的组中
		//用于替代渲染
		//调用替代渲染的方法 Camera.SetReplacementShader("shader1","TransparentCutout")   
		//场上所有带TransparentCutout标签的物体按shader1渲染

		//Queue渲染队列,用来指定当前shader作用的对象的渲染顺序: 
		//Unity中的几种内置的渲染队列,按照渲染顺序,从先到后进行排序,队列数越小的,越先渲染,队列数越大的,越后渲染。
		
		//Background(1000) 最早被渲染的物体的队列。
		//Geometry (2000) 不透明物体的渲染队列。大多数物体都应该使用该队列进行渲染,也是Unity Shader中默认的渲染队列。
		//AlphaTest (2450) 有透明通道,需要进行Alpha Test的物体的队列,比在Geomerty中更有效。
		//Transparent(3000) 半透物体的渲染队列。一般是不写深度的物体,Alpha Blend等的在该队列渲染。
		//Overlay (4000) 最后被渲染的物体的队列,一般是覆盖效果,比如镜头光晕,屏幕贴片之类的


		//“IgnoreProjector”=“True”告诉Unity3D,我们不希望任何投影类型材质或者贴图,影响我们的物体或者着色器。这个特性往往那个用在GUI上。程序默认“IgnoreProjector”=“Flase”。

		Tags{"Queue" = "AlphaTest" "IgnoreProjector" = "True" "RenderType" = "TransparentCutout"}
		
		
		Pass
		{
			Tags{"LightMode" = "ForwardBase"}
		

		CGPROGRAM

		#pragma vertex vert 
		#pragma fragment frag

		#include "Lighting.cginc"


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


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

		struct v2f
		{
			float4 pos :SV_POSITION;
			float3 worldNormal : TEXCOORD0;
			float3 worldPos : TEXCOORD1;
			float2 uv : 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;


			// #define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)
			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);

			clip (texColor.a - _Cutoff);
			//if((texColor.a - _Cutoff) < 0.0)
			//{
			//	discard;若小于_Cutoff则剔除该片元
			//}

			fixed3 albedo = texColor.rgb * _Color.rgb;

			fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;

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

			return fixed4(ambient + diffuse,1.0);

		}


		
		ENDCG
		}
   }
   FallBack "Transparent/Cutout/VertexLit"
}

AlphaTest透明度测试队列 -
        
RenderType标签让Unity把shader归入到TransparentCutout的组中
用于替代渲染
调用替代渲染的方法 Camera.SetReplacementShader("shader1","TransparentCutout")   
场上所有带TransparentCutout标签的物体按shader1渲染

Queue渲染队列,用来指定当前shader作用的对象的渲染顺序: 

Unity中的几种内置的渲染队列,按照渲染顺序,从先到后进行排序,队列数越小的,越先渲染,队列数越大的,越后渲染。

Background(1000) 最早被渲染的物体的队列。
Geometry (2000) 不透明物体的渲染队列。大多数物体都应该使用该队列进行渲染,也是Unity Shader中默认的渲染队列。
AlphaTest (2450) 有透明通道,需要进行Alpha Test的物体的队列,比在Geomerty中更有效。
Transparent(3000) 半透物体的渲染队列。一般是不写深度的物体,Alpha Blend等的在该队列渲染。
Overlay (4000) 最后被渲染的物体的队列,一般是覆盖效果,比如镜头光晕,屏幕贴片之类的


“IgnoreProjector”=“True”告诉Unity3D,我们不希望任何投影类型材质或者贴图,影响我们的物体或者着色器。这个特性往往那个用在GUI上。程序默认“IgnoreProjector”=“Flase”

Tags{"Queue" = "AlphaTest" "IgnoreProjector" = "True" "RenderType" = "TransparentCutout"}

clip (texColor.a - _Cutoff);

和以下的语句段意思一样


if((texColor.a - _Cutoff) < 0.0)
{
        discard;若小于_Cutoff则剔除该片元
};

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值