shader入门基础-透明效果二
shader入门基础-透明效果二
本文内容主要参考 《Unity shader 入门精要》一书,旨在总结所学知识与加深个人理解
clip 函数
在片原着色器中使用 clip 函数进行透明度测试,clip 参数可以是标量,也可以是矢量。如果给定的参数的任何一个分量是负数,就会舍弃当前 像素输出的颜色。discard 指令显示剔除片元。
1
2
3
4
5
6
void clip(float 4)
{
if (any(x<0))
discard;
}
透明度测试实践
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
Shader "Practice/AlphaTest"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Color("Color Tint",Color) = (1,1,1,1)
_Cutoff("Alpha Cutoff",Range(0,1))=0.5
}
SubShader
{
//RenderType 可以让unity把这个shader归入到提“TransparentCutout”
//"IgnoreProjector"="True" 不受投影器影响
//渲染序列设置为 AlphaTest
Tags { "Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout" }
Pass
{
//LightModel 是 pass标签的一种,正确定义LightModel 才能正确得到unity的内置光照变量
Tags {"LightModel"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
//包含内置变量的 _LightColor0
#include "Lighting.cginc"
//C_diffuse = (C_light·m_diffuse)max(0,N·L) //漫反射计算公式
//都在unity 世界坐标计算,需要知道顶点在世界的位置,顶点法线,顶点视角位置
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord :TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD1;
float4 pos : SV_POSITION;
float3 worldNormal:NORMAL;
float3 worldPos:TEXCOORD2;
};
sampler2D _MainTex;
float4 _MainTex_ST;
fixed4 _Color;
fixed _Cutoff;
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
//把顶点坐标转换到世界坐标,为后续取 L做准备
o.worldPos = mul(unity_ObjectToWorld,v.vertex);
//把法线转换到 世界空间中
o.worldNormal = UnityObjectToWorldNormal(v.normal);
//纹理映射坐标,该顶点在纹理中对应的2D坐标
o.uv=v.texcoord.xy*_MainTex_ST.xy+_MainTex_ST.zw;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
//逐像素 光照
//C_diffuse = (C_light·m_diffuse)max(0,N·L)
//获取公式中的各个变量,m_diffuse =此时材质面板给定的_Color*顶点的color
fixed4 col;
fixed4 texColor = tex2D(_MainTex,i.uv);
fixed3 N = normalize(i.worldNormal);
//UnityWorldSpaceLightDir输入世界空间中的坐标点,WorldSpaceLightDir 输入模型空间中的坐标顶点
fixed3 L = normalize(UnityWorldSpaceLightDir(i.worldPos));
clip(texColor.a-_Cutoff);
//equal to
//if(m_diffuse.a-_Cutoff)<0{
//discard;
//}
//计算漫反射部分
fixed3 c_light = _LightColor0.rgb;
fixed3 m_diffuse =texColor.rgb*_Color.rgb;
fixed3 c_diffuse = c_light*m_diffuse*max(0,dot(N,L));
//计算环境光产生的影响,环境光反射的也会受材质本身颜色影响
fixed3 ambient = m_diffuse*UNITY_LIGHTMODEL_AMBIENT.rgb;
//环境光和漫反射光
col = fixed4(ambient+c_diffuse,1.0);
return col;
}
ENDCG
}
}
}
效果图
本文由作者按照 CC BY 4.0 进行授权