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
|
#ifndef __MATCAPS_INC
#define __MATCAPS_INC
#include "globals.cginc"
#include "lighting.cginc"
#include "math.cginc"
#include "pbr.cginc"
#include "texture_utils.cginc"
#if defined(_MATCAP0) || defined(_MATCAP1) || defined(_RIM_LIGHTING0)
#define HAS_MATCAP_RL
#endif
#if defined(HAS_MATCAP_RL)
float2 getMatcapUV(v2f i, Pbr 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 applyMatcapImpl(inout float3 color, float3 sample, uint mode, float mask)
{
[forcecase]
switch(mode) {
case MATCAP_MODE_REPLACE:
color.rgb = lerp(color.rgb, sample, mask);
break;
case MATCAP_MODE_ADD:
color.rgb += lerp(0, sample, mask);
break;
case MATCAP_MODE_MULTIPLY:
color.rgb *= lerp(1, sample, mask);
break;
case MATCAP_MODE_SUBTRACT:
color.rgb -= lerp(0, sample, mask);
break;
case MATCAP_MODE_ADD_PRODUCT:
color.rgb += lerp(0, sample * color.rgb, mask);
break;
default:
break;
}
}
void applyMatcap(inout Pbr pbr, float3 sample, uint mode, float mask)
{
applyMatcapImpl(pbr.albedo.rgb, sample, mode, mask);
}
float2 quantizeMatcapUV(float2 muv, float muv_r, float steps) {
float muv_r_q = floor(muv_r * steps) / steps;
const float epsilon = 1e-4f;
return muv_r_q * (muv / max(epsilon, muv_r));
}
#endif // HAS_MATCAP_RL
void apply_matcaps_and_rim_lighting(v2f i, inout Pbr pbr, inout LightData light_data) {
#if defined(HAS_MATCAP_RL)
float2 muv = getMatcapUV(i, pbr);
float2 muv_centered = muv * 2 - 1;
float muv_r = length(muv_centered);
#endif
#if defined(_MATCAP0)
#if defined(_MATCAP0_QUANTIZATION)
float2 m0uv = quantizeMatcapUV(muv, muv_r, _Matcap0_Quantization_Steps);
#else
float2 m0uv = muv;
#endif
float3 m0 = _Matcap0.Sample(linear_repeat_s, m0uv);
m0 = _Matcap0_Invert ? 1 - m0 : m0;
m0 *= _Matcap0_Strength;
#if defined(_MATCAP0_MASK)
float m0_mask = _Matcap0_Mask.Sample(linear_repeat_s, UV_SCOFF(i, _Matcap0_Mask_ST, /*which_channel=*/0));
#else
float m0_mask = 1;
#endif
applyMatcap(pbr, m0, _Matcap0_Mode, m0_mask);
#endif // _MATCAP0
#if defined(_MATCAP1)
#if defined(_MATCAP1_QUANTIZATION)
float2 m1uv = quantizeMatcapUV(muv, muv_r, _Matcap1_Quantization_Steps);
#else
float2 m1uv = muv;
#endif
float3 m1 = _Matcap1.Sample(linear_repeat_s, m1uv);
m1 = _Matcap1_Invert ? 1 - m1 : m1;
m1 *= _Matcap1_Strength;
#if defined(_MATCAP1_MASK)
float m1_mask = _Matcap1_Mask.Sample(linear_repeat_s, UV_SCOFF(i, _Matcap1_Mask_ST, /*which_channel=*/0));
#else
float m1_mask = 1;
#endif
applyMatcap(pbr, m1, _Matcap1_Mode, m1_mask);
#endif // _MATCAP1
#if defined(_RIM_LIGHTING0)
// 1 at rim center, 0 outside blur radius.
float rl0_inner = smoothstep(
_Rim_Lighting0_Center - _Rim_Lighting0_Blur,
_Rim_Lighting0_Center,
muv_r);
float rl0_outer = 1 - smoothstep(
_Rim_Lighting0_Center,
_Rim_Lighting0_Center + _Rim_Lighting0_Blur,
muv_r);
float rl0_dist = rl0_inner * rl0_outer;
#if defined(_RIM_LIGHTING0_QUANTIZATION)
rl0_dist = floor(rl0_dist * _Rim_Lighting0_Quantization_Steps) / _Rim_Lighting0_Quantization_Steps;
#endif
float3 rl0;
switch(_Rim_Lighting0_Mode) {
case MATCAP_MODE_ADD:
// Fall through.
case MATCAP_MODE_SUBTRACT:
rl0 = lerp(0, _Rim_Lighting0_Color, rl0_dist);
break;
case MATCAP_MODE_MULTIPLY:
rl0 = lerp(1, _Rim_Lighting0_Color, rl0_dist);
break;
default:
rl0 = lerp(pbr.albedo.xyz, _Rim_Lighting0_Color, rl0_dist);
break;
}
#if defined(_RIM_LIGHTING0_MASK)
float rl0_mask = _Rim_Lighting0_Mask.Sample(linear_repeat_s, UV_SCOFF(i, _Rim_Lighting0_Mask_ST, /*which_channel=*/0));
#else
float rl0_mask = 1;
#endif
applyMatcap(pbr, rl0, _Rim_Lighting0_Mode, rl0_mask);
#endif // _RIM_LIGHTING0
}
#endif
|