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
|
#ifndef __MATCAPS_INC
#define __MATCAPS_INC
#include "features.cginc"
#include "globals.cginc"
#include "interpolators.cginc"
#include "yum_pbr.cginc"
#if defined(_MATCAP0) || defined(_RIM_LIGHTING0)
float2 getMatcapUV(v2f i, inout YumPbr pbr) {
const float3 cam_normal = normalize(mul(UNITY_MATRIX_V, float4(pbr.normal, 0)));
const float3 cam_view_dir = normalize(mul(UNITY_MATRIX_V, float4(-i.eyeVec.xyz, 0)));
const float3 cam_refl = -reflect(cam_view_dir, cam_normal);
float m = 2.0 * sqrt(
cam_refl.x * cam_refl.x +
cam_refl.y * cam_refl.y +
(cam_refl.z + 1) * (cam_refl.z + 1));
return cam_refl.xy / m + 0.5;
}
void applyMatcap(inout YumPbr pbr, float3 sample, uint mode, float mask)
{
[forcecase]
switch(mode) {
case MATCAP_MODE_REPLACE:
pbr.albedo.rgb = lerp(pbr.albedo.rgb, sample, mask);
break;
case MATCAP_MODE_ADD:
pbr.albedo.rgb += lerp(0, sample, mask);
break;
case MATCAP_MODE_MULTIPLY:
pbr.albedo.rgb *= lerp(1, sample, mask);
break;
case MATCAP_MODE_SUBTRACT:
pbr.albedo.rgb -= lerp(0, sample, mask);
break;
case MATCAP_MODE_ADD_PRODUCT:
pbr.albedo.rgb += lerp(0, sample * pbr.albedo.rgb, mask);
break;
default:
break;
}
}
#endif
float getAngleAttenuation(float2 muv, float2 target_vector, float power) {
muv = muv * 2 - 1;
float NoL = dot(muv, target_vector);
NoL = halfLambertianNoL(NoL);
return pow(NoL, power);
}
void applyMatcapsAndRimLighting(v2f i, inout YumPbr pbr) {
#if defined(_MATCAP0) || defined(_RIM_LIGHTING0) || defined(_RIM_LIGHTING1)
float2 muv = getMatcapUV(i, pbr);
#endif
#if defined(_MATCAP0)
float3 m0 = _Matcap0.Sample(linear_repeat_s, muv);
m0 = lerp(m0, 1 - m0, _Matcap0_Invert);
m0 *= _Matcap0_Strength;
#if defined(_MATCAP0_MASK)
float m0_mask = _Matcap0_Mask.Sample(linear_repeat_s, i.uv01.xy);
#else
float m0_mask = 1;
#endif
applyMatcap(pbr, m0, _Matcap0_Mode, m0_mask);
#endif
#if defined(_RIM_LIGHTING0) || defined(_RIM_LIGHTING1)
float rl_radius = length(muv - 0.5);
#endif
#if defined(_RIM_LIGHTING0)
float rl0_dist = exp2(-_Rim_Lighting0_Power * abs(rl_radius - _Rim_Lighting0_Center));
float3 rl0 = _Rim_Lighting0_Color * _Rim_Lighting0_Brightness * rl0_dist;
#if defined(_RIM_LIGHTING0_MASK)
float rl0_mask = _Rim_Lighting0_Mask.Sample(linear_repeat_s, i.uv01.xy);
#else
float rl0_mask = 1;
#endif
#if defined(_RIM_LIGHTING0_ANGLE_LIMIT)
rl0 *= getAngleAttenuation(muv, _Rim_Lighting0_Angle_Limit_Target_Vector,
_Rim_Lighting0_Angle_Limit_Power);
#endif
#if defined(_RIM_LIGHTING0_QUANTIZATION)
rl0 = floor(rl0 * _Rim_Lighting0_Quantization_Steps) / _Rim_Lighting0_Quantization_Steps;
#endif
applyMatcap(pbr, rl0, _Rim_Lighting0_Mode, rl0_mask);
#endif
#if defined(_RIM_LIGHTING1)
float rl1_dist = exp2(-_Rim_Lighting1_Power * abs(rl_radius - _Rim_Lighting1_Center));
float3 rl1 = _Rim_Lighting1_Color * _Rim_Lighting1_Brightness * rl1_dist;
#if defined(_RIM_LIGHTING1_MASK)
float rl1_mask = _Rim_Lighting1_Mask.Sample(linear_repeat_s, i.uv01.xy);
#else
float rl1_mask = 1;
#endif
#if defined(_RIM_LIGHTING1_ANGLE_LIMIT)
rl1 *= getAngleAttenuation(muv, _Rim_Lighting1_Angle_Limit_Target_Vector,
_Rim_Lighting1_Angle_Limit_Power);
#endif
#if defined(_RIM_LIGHTING1_QUANTIZATION)
rl1 = floor(rl1 * _Rim_Lighting1_Quantization_Steps) / _Rim_Lighting1_Quantization_Steps;
#endif
applyMatcap(pbr, rl1, _Rim_Lighting1_Mode, rl1_mask);
#endif
}
#endif
|