渲染引擎一般会先对物体进行排序再渲染
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则剔除该片元
};