AvatarMaterialStateShader.cginc
9.04 KB
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
#ifndef AVATAR_UTIL_CG_INCLUDED
#define AVATAR_UTIL_CG_INCLUDED
#include "UnityCG.cginc"
#define SAMPLE_MODE_COLOR 0
#define SAMPLE_MODE_TEXTURE 1
#define SAMPLE_MODE_TEXTURE_SINGLE_CHANNEL 2
#define SAMPLE_MODE_PARALLAX 3
#define SAMPLE_MODE_RSRM 4
#define MASK_TYPE_NONE 0
#define MASK_TYPE_POSITIONAL 1
#define MASK_TYPE_REFLECTION 2
#define MASK_TYPE_FRESNEL 3
#define MASK_TYPE_PULSE 4
#define BLEND_MODE_ADD 0
#define BLEND_MODE_MULTIPLY 1
#ifdef LAYERS_1
#define LAYER_COUNT 1
#elif LAYERS_2
#define LAYER_COUNT 2
#elif LAYERS_3
#define LAYER_COUNT 3
#elif LAYERS_4
#define LAYER_COUNT 4
#elif LAYERS_5
#define LAYER_COUNT 5
#elif LAYERS_6
#define LAYER_COUNT 6
#elif LAYERS_7
#define LAYER_COUNT 7
#elif LAYERS_8
#define LAYER_COUNT 8
#endif
#define DECLARE_LAYER_UNIFORMS(index) \
int _LayerSampleMode##index; \
int _LayerBlendMode##index; \
int _LayerMaskType##index; \
fixed4 _LayerColor##index; \
sampler2D _LayerSurface##index; \
float4 _LayerSurface##index##_ST; \
float4 _LayerSampleParameters##index; \
float4 _LayerMaskParameters##index; \
float4 _LayerMaskAxis##index;
DECLARE_LAYER_UNIFORMS(0)
DECLARE_LAYER_UNIFORMS(1)
DECLARE_LAYER_UNIFORMS(2)
DECLARE_LAYER_UNIFORMS(3)
DECLARE_LAYER_UNIFORMS(4)
DECLARE_LAYER_UNIFORMS(5)
DECLARE_LAYER_UNIFORMS(6)
DECLARE_LAYER_UNIFORMS(7)
struct VertexOutput
{
float4 pos : SV_POSITION;
float2 texcoord : TEXCOORD0;
float3 worldPos : TEXCOORD1;
float3 worldNormal : TEXCOORD2;
float3 viewDir : TEXCOORD3;
float4 vertColor : COLOR;
#if NORMAL_MAP_ON || PARALLAX_ON
float3 worldTangent : TANGENT;
float3 worldBitangent : TEXCOORD5;
#endif
};
float _Alpha;
int _BaseMaskType;
float4 _BaseMaskParameters;
float4 _BaseMaskAxis;
fixed4 _DarkMultiplier;
fixed4 _BaseColor;
sampler2D _AlphaMask;
float4 _AlphaMask_ST;
sampler2D _AlphaMask2;
float4 _AlphaMask2_ST;
sampler2D _NormalMap;
float4 _NormalMap_ST;
sampler2D _ParallaxMap;
float4 _ParallaxMap_ST;
sampler2D _RoughnessMap;
float4 _RoughnessMap_ST;
float4x4 _ProjectorWorldToLocal;
VertexOutput vert(appdata_full v)
{
VertexOutput o;
UNITY_INITIALIZE_OUTPUT(VertexOutput, o);
o.texcoord = v.texcoord.xy;
o.worldPos = mul(unity_ObjectToWorld, v.vertex);
o.vertColor = v.color;
o.viewDir = normalize(_WorldSpaceCameraPos.xyz - o.worldPos);
o.worldNormal = normalize(mul(unity_ObjectToWorld, float4(v.normal, 0.0)).xyz);
#if NORMAL_MAP_ON || PARALLAX_ON
o.worldTangent = normalize(mul(unity_ObjectToWorld, float4(v.tangent.xyz, 0.0)).xyz);
o.worldBitangent = normalize(cross(o.worldNormal, o.worldTangent) * v.tangent.w);
#endif
o.pos = UnityObjectToClipPos(v.vertex);
return o;
}
#ifndef NORMAL_MAP_ON
#define COMPUTE_NORMAL IN.worldNormal
#else
#define COMPUTE_NORMAL normalize(mul(lerp(float3(0, 0, 1), surfaceNormal, normalMapStrength), tangentTransform))
#endif
float3 ComputeColor(
VertexOutput IN,
float2 uv,
#if PARALLAX_ON || NORMAL_MAP_ON
float3x3 tangentTransform,
#endif
#ifdef NORMAL_MAP_ON
float3 surfaceNormal,
#endif
sampler2D surface,
float4 surface_ST,
fixed4 color,
int sampleMode,
float4 sampleParameters
) {
if (sampleMode == SAMPLE_MODE_TEXTURE) {
float2 panning = _Time.g * sampleParameters.xy;
return tex2D(surface, (uv + panning) * surface_ST.xy + surface_ST.zw).rgb * color.rgb;
}
else if (sampleMode == SAMPLE_MODE_TEXTURE_SINGLE_CHANNEL) {
float4 channelMask = sampleParameters;
float4 channels = tex2D(surface, uv * surface_ST.xy + surface_ST.zw);
return dot(channels, channelMask) * color.rgb;
}
#ifdef PARALLAX_ON
else if (sampleMode == SAMPLE_MODE_PARALLAX) {
float parallaxMinHeight = sampleParameters.x;
float parallaxMaxHeight = sampleParameters.y;
float parallaxValue = tex2D(_ParallaxMap, TRANSFORM_TEX(uv, _ParallaxMap)).r;
float scaledHeight = lerp(parallaxMinHeight, parallaxMaxHeight, parallaxValue);
float2 parallaxUV = mul(tangentTransform, IN.viewDir).xy * scaledHeight;
return tex2D(surface, (uv * surface_ST.xy + surface_ST.zw) + parallaxUV).rgb * color.rgb;
}
#endif
else if (sampleMode == SAMPLE_MODE_RSRM) {
float roughnessMin = sampleParameters.x;
float roughnessMax = sampleParameters.y;
#ifdef ROUGHNESS_ON
float roughnessValue = tex2D(_RoughnessMap, TRANSFORM_TEX(uv, _RoughnessMap)).r;
float scaledRoughness = lerp(roughnessMin, roughnessMax, roughnessValue);
#else
float scaledRoughness = roughnessMin;
#endif
#ifdef NORMAL_MAP_ON
float normalMapStrength = sampleParameters.z;
#endif
float3 viewReflect = reflect(-IN.viewDir, COMPUTE_NORMAL);
float viewAngle = viewReflect.y * 0.5 + 0.5;
return tex2D(surface, float2(scaledRoughness, viewAngle)).rgb * color.rgb;
}
return color.rgb;
}
float ComputeMask(
VertexOutput IN,
#ifdef NORMAL_MAP_ON
float3x3 tangentTransform,
float3 surfaceNormal,
#endif
int maskType,
float4 layerParameters,
float3 maskAxis
) {
if (maskType == MASK_TYPE_POSITIONAL) {
float centerDistance = layerParameters.x;
float fadeAbove = layerParameters.y;
float fadeBelow = layerParameters.z;
float3 objPos = mul(unity_WorldToObject, float4(IN.worldPos, 1.0)).xyz;
float d = dot(objPos, maskAxis);
if (d > centerDistance) {
return saturate(1.0 - (d - centerDistance) / fadeAbove);
}
else {
return saturate(1.0 - (centerDistance - d) / fadeBelow);
}
}
else if (maskType == MASK_TYPE_REFLECTION) {
float fadeStart = layerParameters.x;
float fadeEnd = layerParameters.y;
#ifdef NORMAL_MAP_ON
float normalMapStrength = layerParameters.z;
#endif
float power = layerParameters.w;
float3 viewReflect = reflect(-IN.viewDir, COMPUTE_NORMAL);
float d = max(0.0, dot(viewReflect, maskAxis));
return saturate(1.0 - (d - fadeStart) / (fadeEnd - fadeStart));
}
else if (maskType == MASK_TYPE_FRESNEL) {
float power = layerParameters.x;
float fadeStart = layerParameters.y;
float fadeEnd = layerParameters.z;
#ifdef NORMAL_MAP_ON
float normalMapStrength = layerParameters.w;
#endif
float d = saturate(1.0 - max(0.0, dot(IN.viewDir, COMPUTE_NORMAL)));
float p = pow(d, power);
return saturate(lerp(fadeStart, fadeEnd, p));
}
else if (maskType == MASK_TYPE_PULSE) {
float distance = layerParameters.x;
float speed = layerParameters.y;
float power = layerParameters.z;
float3 objPos = mul(unity_WorldToObject, float4(IN.worldPos, 1.0)).xyz;
float d = dot(objPos, maskAxis);
float theta = 6.2831 * frac((d - _Time.g * speed) / distance);
return saturate(pow((sin(theta) * 0.5 + 0.5), power));
}
else {
return 1.0;
}
}
float3 ComputeBlend(float3 source, float3 blend, float mask, int blendMode) {
if (blendMode == BLEND_MODE_MULTIPLY) {
return source * (blend * mask);
}
else {
return source + (blend * mask);
}
}
float4 ComputeSurface(VertexOutput IN)
{
#if PROJECTOR_ON
float3 projectorPos = mul(_ProjectorWorldToLocal, float4(IN.worldPos, 1.0)).xyz;
if (abs(projectorPos.x) > 1.0 || abs(projectorPos.y) > 1.0 || abs(projectorPos.z) > 1.0)
{
discard;
}
float2 uv = projectorPos.xy * 0.5 + 0.5;
#else
float2 uv = IN.texcoord.xy;
#endif
fixed4 c = _BaseColor;
IN.worldNormal = normalize(IN.worldNormal);
#if PARALLAX_ON || NORMAL_MAP_ON
float3x3 tangentTransform = float3x3(IN.worldTangent, IN.worldBitangent, IN.worldNormal);
#endif
#ifdef NORMAL_MAP_ON
float3 surfaceNormal = UnpackNormal(tex2D(_NormalMap, TRANSFORM_TEX(uv, _NormalMap)));
#endif
#if PARALLAX_ON || NORMAL_MAP_ON
#ifndef NORMAL_MAP_ON
#define COLOR_INPUTS IN, uv, tangentTransform
#define MASK_INPUTS IN
#else
#define COLOR_INPUTS IN, uv, tangentTransform, surfaceNormal
#define MASK_INPUTS IN, tangentTransform, surfaceNormal
#endif
#else
#define COLOR_INPUTS IN, uv
#define MASK_INPUTS IN
#endif
#define LAYER_COLOR(index) ComputeColor(COLOR_INPUTS, _LayerSurface##index, _LayerSurface##index##_ST, _LayerColor##index, _LayerSampleMode##index, _LayerSampleParameters##index)
#define LAYER_MASK(index) ComputeMask(MASK_INPUTS, _LayerMaskType##index, _LayerMaskParameters##index, _LayerMaskAxis##index##.xyz)
#define LAYER_BLEND(index, c) ComputeBlend(c, LAYER_COLOR(index), LAYER_MASK(index), _LayerBlendMode##index)
c.rgb = LAYER_BLEND(0, c.rgb);
#if LAYER_COUNT > 1
c.rgb = LAYER_BLEND(1, c.rgb);
#endif
#if LAYER_COUNT > 2
c.rgb = LAYER_BLEND(2, c.rgb);
#endif
#if LAYER_COUNT > 3
c.rgb = LAYER_BLEND(3, c.rgb);
#endif
#if LAYER_COUNT > 4
c.rgb = LAYER_BLEND(4, c.rgb);
#endif
#if LAYER_COUNT > 5
c.rgb = LAYER_BLEND(5, c.rgb);
#endif
#if LAYER_COUNT > 6
c.rgb = LAYER_BLEND(6, c.rgb);
#endif
#if LAYER_COUNT > 7
c.rgb = LAYER_BLEND(7, c.rgb);
#endif
#ifdef VERTALPHA_ON
float scaledValue = IN.vertColor.a * 2.0;
float alpha0weight = max(0.0, 1.0 - scaledValue);
float alpha2weight = max(0.0, scaledValue - 1.0);
float alpha1weight = 1.0 - alpha0weight - alpha2weight;
c.a = _Alpha * c.a * (tex2D(_AlphaMask, TRANSFORM_TEX(uv, _AlphaMask)).r * alpha1weight + tex2D(_AlphaMask2, TRANSFORM_TEX(uv, _AlphaMask2)).r * alpha2weight + alpha0weight) * ComputeMask(MASK_INPUTS, _BaseMaskType, _BaseMaskParameters, _BaseMaskAxis);
#else
c.a = _Alpha * c.a * tex2D(_AlphaMask, TRANSFORM_TEX(uv, _AlphaMask)).r * IN.vertColor.a * ComputeMask(MASK_INPUTS, _BaseMaskType, _BaseMaskParameters, _BaseMaskAxis);
#endif
c.rgb = lerp(c.rgb, c.rgb * _DarkMultiplier, IN.vertColor.r);
return c;
}
#endif