渐变纹理

可以用于实现卡通效果

代码实现

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
Shader "Unlit/012"
{
Properties
{
_RampTex("MainTex", 2D) = "white"{}
_Diffuse("Diffuse", Color) = (1,1,1,1)
_Specular("Specular", Color) = (1,1,1,1)
_Gloss("Gloss", Range(1,256)) = 5
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100

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

fixed4 _Diffuse;
fixed4 _Specular;
float _Gloss;
sampler _RampTex;
float4 _RampTex_ST; //不需要在Properties里定义,用于存放Tiling(缩放)和Offset(位移)的数值

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

v2f vert (appdata_base v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
o.worldNormal = worldNormal;
o.worldPos = mul(unity_ObjectToWorld, v.vertex);
//o.uv = v.texcoord.xy * _RampTex_ST.xy + _RampTex_ST.zw; //为了时Tiling和Offset的数值影响到uv
o.uv = TRANSFORM_TEX(v.texcoord, _RampTex);
return o;
}

fixed4 frag (v2f i) : SV_Target
{
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

//漫反射
fixed3 worldLightDir = UnityWorldSpaceLightDir(i.worldPos);
fixed halfLambert = max(0, dot(worldLightDir, i.worldNormal))* 0.5 + 0.5;
fixed3 diffuse = _LightColor0.rgb * tex2D(_RampTex, fixed2(halfLambert, halfLambert)) * _Diffuse.rgb;

//高光反射
//fixed3 reflectDir = normalize(reflect(-worldLightDir, i.worldNormal));
fixed3 viewDir = normalize(_WorldSpaceLightPos0.xyz - i.worldPos.xyz);
fixed3 halfDir = normalize(worldLightDir + viewDir);
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(i.worldNormal, halfDir)), _Gloss);

fixed3 color = ambient + diffuse + specular;
return float4(color, 1);
}
ENDCG
}
}
}

效果图

三种渐变纹理的效果

遮罩纹理

​ 相当于在某些图上去做一些保护,不去被影响,例如高光,在物体上,不像某个部分不需要高光,就可以使用遮罩纹理罩住这片区域

​ 通过通道来做到遮罩的控制,0便是遮罩,0到1之间便是削弱,1便是不变。

代码实现

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
92
93
94
95
96
97
98
99
Shader "Unlit/013"
{
Properties
{
_MainTex("MainTex", 2D) = "white"{}
_BumpMap("Bump Map", 2D) = "bump"{}
_BumpScale("BumpS cale", float) = 1
_SpecularMask("Specular Mask", 2D) = "white"{} //遮罩纹理相关属性
_SpecularScale("Specular Scale", float) = 1 //高光系数
_Diffuse("Diffuse", Color) = (1,1,1,1)
_Specular("Specular", Color) = (1,1,1,1)
_Gloss("Gloss", Range(1,256)) = 5
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100

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

sampler _MainTex;
float4 _MainTex_ST; //不需要在Properties里定义,用于存放Tiling(缩放)和Offset(位移)的数值
sampler2D _BumpMap;
float4 _BumpMap_ST;
sampler2D _SpecularMask;
float4 _SpecularMask_ST;
float _SpecularScale;
float _BumpScale;
fixed4 _Diffuse;
fixed4 _Specular;
float _Gloss;

struct v2f
{
float4 vertex : SV_POSITION;
fixed3 lightDir : TEXCOORD0;
float3 viewDir : TEXCOORD1;
float4 uv : TEXCOORD2;
float2 maskUv : TEXCOORD3;
};

v2f vert (appdata_tan v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
o.uv.zw = TRANSFORM_TEX(v.texcoord, _BumpMap);
o.maskUv = TRANSFORM_TEX(v.texcoord, _SpecularMask);

TANGENT_SPACE_ROTATION;// 官方提供的计算方式,内容和上面求副切线向量的写法一样。

// 求切线空间光源方向及视角方向
o.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex)).xyz;
o.viewDir = mul(rotation, ObjSpaceViewDir(v.vertex)).xyz;

return o;
}

fixed4 frag (v2f i) : SV_Target
{
fixed3 tangentLightDir = normalize(i.lightDir);
fixed3 tangentviewDir = normalize(i.viewDir);

fixed4 packedNormal = tex2D(_BumpMap, i.uv.zw); // 采样

//法线贴图设置成normal map
fixed3 tangentNormal = UnpackNormal(packedNormal);
tangentNormal.xy *= _BumpScale;

//环境光
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

//图片采样
fixed3 albedo = tex2D(_MainTex, i.uv.xy).rgb;

//漫反射
fixed3 diffuse = _LightColor0.rgb * albedo * _Diffuse.rgb * (max(0, dot(tangentLightDir, normalize(tangentNormal)))* 0.5 + 0.5);

//高光遮罩
fixed3 specularMask = tex2D(_SpecularMask, i.maskUv).r * _SpecularScale;

//高光反射
fixed3 halfDir = normalize(tangentLightDir + tangentviewDir);
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(tangentNormal, halfDir)), _Gloss) * specularMask;

fixed3 color = ambient + diffuse + specular;
return float4(color, 1);
}
ENDCG
}
}
}