「UnityShader笔记」10.透明度测试
作者:互联网
Part1.概述
所谓透明度测试,就是根据一个不透明度的阈值,对需要进行透明度测试的物体进行筛选,通过筛选的片元将被正常渲染,否则会被直接剔除
透明度测试并没有真正实现半透明效果,它只是简单剔除了一些不透明度未到达阈值的片元
透明度测试是必须关闭深度写入的,因为如果一个片元被剔除,而仍然进行了深度写入,这会使得后来渲染的后方物体(如果有的话)仍然被遮挡,这是错误的
Part2.代码逐段分析
2.1属性快
Properties
{
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Main Tex", 2D) = "white" {}
_Cutoff("Alpha Cutoff", Range(0,1)) = 0.5
}
在属性块,我们有额外的参数需要定义,即Cutoff参数,它定义了剔除透明片元的阈值,范围在0~1,凡是不透明度小于这个阈值的片元,在透明度测试中将被剔除
Tags{"Queue" = "AlphaTest" "IgnoreProjector" = "True" "RenderType" = "TransparentCutout"}
在写Pass之前,我们需要设定几个重要tags,它们与透明度测试相关
Queue
这个tag设定了渲染顺序队列,Unity中默认的渲染队列如下:
将其设定为AlphaTest后,这使得其将会在不透明物体之后才被渲染,因为需要透明度测试的物体是关闭深度写入的,不能和不透明物体一起渲染
RenderType
常被用于着色器替换功能
IgnoreProjector
设置为true,代表不受投影器的影响
2.2顶点着色器
v2f vert(a2v v){
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldPos = mul(unity_ObjectToWorld, v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
顶点着色器只做实现一些常规工作
2.3片元着色器
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);
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);
}
片元着色器中,当我们对纹理采样完成后,需要根据采样的颜色结果进行透明度测试,内置的clip( )函数可以实现这个功能,当传入的参数<0时,片元将被剔除,因此我们将透明度减去阈值传入这个函数
Part3.效果图
Part4.完整代码
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
Shader "Chapert8/alphaTest"
{
Properties
{
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Main Tex", 2D) = "white" {}
_Cutoff("Alpha Cutoff", Range(0,1)) = 0.5
}
SubShader
{
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.worldPos = mul(unity_ObjectToWorld, v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
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);
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 "Diffuse"
}
标签:10,MainTex,Cutoff,Color,透明度,笔记,fixed3,UnityShader,worldNormal 来源: https://www.cnblogs.com/MuTsuKi/p/16352809.html