yum-archive/2ner

A toon shader for Unity's BIRP.

git clone https://git.yummers.dev/yum-archive/2ner

yumPush eyeVec into fragmenta54b415

master
7.9 KiB214 linesraw
1#ifndef __MATCAPS_INC
2#define __MATCAPS_INC
3
4#include "features.cginc"
5#include "globals.cginc"
6#include "interpolators.cginc"
7#include "yum_lighting.cginc"
8#include "yum_pbr.cginc"
9
10#if defined(_MATCAP0) || defined(_MATCAP1) || defined(_MATCAP2) || defined(_RIM_LIGHTING0) || defined(_RIM_LIGHTING1) || defined(_RIM_LIGHTING2) || defined(_RIM_LIGHTING3)
11float2 getMatcapUV(v2f i, f2f f, inout YumPbr pbr) {
12  const float3 cam_normal = normalize(mul(UNITY_MATRIX_V, float4(pbr.normal, 0)));
13  const float3 cam_view_dir = normalize(mul(UNITY_MATRIX_V, float4(-f.eyeVec, 0)));
14  const float3 cam_refl = -reflect(cam_view_dir, cam_normal);
15  float m = 2.0 * sqrt(
16      cam_refl.x * cam_refl.x +
17      cam_refl.y * cam_refl.y +
18      (cam_refl.z + 1) * (cam_refl.z + 1));
19  return cam_refl.xy / m + 0.5;
20}
21
22void applyMatcapImpl(inout float3 color, float3 sample, uint mode, float mask)
23{
24  [forcecase]
25  switch(mode) {
26    case MATCAP_MODE_REPLACE:
27      color.rgb = lerp(color.rgb, sample, mask);
28      break;
29    case MATCAP_MODE_ADD:
30      color.rgb += lerp(0, sample, mask);
31      break;
32    case MATCAP_MODE_MULTIPLY:
33      color.rgb *= lerp(1, sample, mask);
34      break;
35    case MATCAP_MODE_SUBTRACT:
36      color.rgb -= lerp(0, sample, mask);
37      break;
38    case MATCAP_MODE_ADD_PRODUCT:
39      color.rgb += lerp(0, sample * color.rgb, mask);
40      break;
41    default:
42      break;
43  }
44}
45
46void applyMatcap(inout YumPbr pbr, inout YumLighting l, float3 sample,
47    uint mode, uint target_mask, float mask)
48{
49  [branch]
50  if (target_mask & MATCAP_TARGET_ALBEDO) {
51    applyMatcapImpl(pbr.albedo.rgb, sample, mode, mask);
52  }
53  [branch]
54  if (target_mask & MATCAP_TARGET_DIFFUSE) {
55    applyMatcapImpl(l.diffuse, sample, mode, mask);
56  }
57  [branch]
58  if (target_mask & MATCAP_TARGET_SPECULAR) {
59    applyMatcapImpl(l.specular, sample, mode, mask);
60  }
61}
62#endif  // _MATCAP0 || _RIM_LIGHTING0 || _RIM_LIGHTING1 || _RIM_LIGHTING2 || _RIM_LIGHTING3
63
64float getAngleAttenuation(float2 muv, float2 target_vector, float power) {
65  muv = muv * 2 - 1;
66  float NoL = dot(muv, target_vector);
67  NoL =  halfLambertianNoL(NoL);
68  return pow(NoL, power);
69}
70
71void applyMatcapsAndRimLighting(v2f i, f2f f, inout YumPbr pbr, inout YumLighting l) {
72#if defined(_MATCAP0) || defined(_MATCAP1) || defined(_MATCAP2) || defined(_RIM_LIGHTING0) || defined(_RIM_LIGHTING1) || defined(_RIM_LIGHTING2) || defined(_RIM_LIGHTING3)
73  float2 muv = getMatcapUV(i, f, pbr);
74#endif
75#if defined(_MATCAP0)
76#if defined(_MATCAP0_QUANTIZATION)
77  float2 m0uv = muv * 2 - 1;
78  float m0uv_r = length(m0uv);
79  float m0uv_r_q = floor(m0uv_r * _Matcap0_Quantization_Steps) / _Matcap0_Quantization_Steps;
80  m0uv = m0uv_r_q * (m0uv / max(1E-4, m0uv_r));
81  m0uv = m0uv * 0.5 + 0.5;
82#else
83  float2 m0uv = muv;
84#endif
85  float3 m0 = _Matcap0.Sample(linear_repeat_s, m0uv);
86  m0 = lerp(m0, 1 - m0, _Matcap0_Invert);
87  m0 *= _Matcap0_Strength;
88#if defined(_MATCAP0_MASK)
89  float m0_mask = _Matcap0_Mask.Sample(linear_repeat_s, UV_SCOFF(i, _Matcap0_Mask_ST, /*which_channel=*/0));
90#else
91  float m0_mask = 1;
92#endif
93  applyMatcap(pbr, l, m0, _Matcap0_Mode, _Matcap0_Target_Mask, m0_mask);
94#endif  // _MATCAP0
95#if defined(_MATCAP1)
96#if defined(_MATCAP1_QUANTIZATION)
97  float2 m1uv = muv * 2 - 1;
98  float m1uv_r = length(m1uv);
99  float m1uv_r_q = floor(m1uv_r * _Matcap1_Quantization_Steps) / _Matcap1_Quantization_Steps;
100  m1uv = m1uv_r_q * (m1uv / max(1E-4, m1uv_r));
101  m1uv = m1uv * 0.5 + 0.5;
102#else
103  float2 m1uv = muv;
104#endif  // _MATCAP1_QUANTIZATION
105  float3 m1 = _Matcap1.Sample(linear_repeat_s, m1uv);
106  m1 = lerp(m1, 1 - m1, _Matcap1_Invert);
107  m1 *= _Matcap1_Strength;
108#if defined(_MATCAP1_MASK)
109  float m1_mask = _Matcap1_Mask.Sample(linear_repeat_s, UV_SCOFF(i, _Matcap1_Mask_ST, /*which_channel=*/0));
110#else
111  float m1_mask = 1;
112#endif
113  applyMatcap(pbr, l, m1, _Matcap1_Mode, _Matcap1_Target_Mask, m1_mask);
114#endif  // _MATCAP1
115#if defined(_MATCAP2)
116#if defined(_MATCAP2_QUANTIZATION)
117  float2 m2uv = muv * 2 - 1;
118  float m2uv_r = length(m2uv);
119  float m2uv_r_q = floor(m2uv_r * _Matcap2_Quantization_Steps) / _Matcap2_Quantization_Steps;
120  m2uv = m2uv_r_q * (m2uv / max(1E-4, m2uv_r));
121  m2uv = m2uv * 0.5 + 0.5;
122#else
123  float2 m2uv = muv;
124#endif  // _MATCAP2_QUANTIZATION
125  float3 m2 = _Matcap2.Sample(linear_repeat_s, m2uv);
126  m2 = lerp(m2, 1 - m2, _Matcap2_Invert);
127  m2 *= _Matcap2_Strength;
128#if defined(_MATCAP2_MASK)
129  float m2_mask = _Matcap2_Mask.Sample(linear_repeat_s, UV_SCOFF(i, _Matcap2_Mask_ST, /*which_channel=*/0));
130#else
131  float m2_mask = 1;
132#endif
133  applyMatcap(pbr, l, m2, _Matcap2_Mode, _Matcap2_Target_Mask, m2_mask);
134#endif  // _MATCAP2
135
136#if defined(_RIM_LIGHTING0) || defined(_RIM_LIGHTING1) || defined(_RIM_LIGHTING2) || defined(_RIM_LIGHTING3)
137  float rl_radius = length(muv - 0.5);
138#endif
139
140#if defined(_RIM_LIGHTING0)
141  float rl0_dist = exp2(-_Rim_Lighting0_Power * abs(rl_radius - _Rim_Lighting0_Center));
142#if defined(_RIM_LIGHTING0_ANGLE_LIMIT)
143  rl0_dist *= getAngleAttenuation(muv, _Rim_Lighting0_Angle_Limit_Target_Vector,
144      _Rim_Lighting0_Angle_Limit_Power);
145#endif
146#if defined(_RIM_LIGHTING0_QUANTIZATION)
147  rl0_dist = floor(rl0_dist * _Rim_Lighting0_Quantization_Steps) / _Rim_Lighting0_Quantization_Steps;
148#endif
149  float3 rl0 = _Rim_Lighting0_Color * _Rim_Lighting0_Brightness * rl0_dist;
150#if defined(_RIM_LIGHTING0_MASK)
151  float rl0_mask = _Rim_Lighting0_Mask.Sample(linear_repeat_s, UV_SCOFF(i, _Rim_Lighting0_Mask_ST, /*which_channel=*/0));
152#else
153  float rl0_mask = 1;
154#endif
155  applyMatcap(pbr, l, rl0, _Rim_Lighting0_Mode, _Rim_Lighting0_Target_Mask, rl0_mask);
156#endif  // _RIM_LIGHTING0
157
158#if defined(_RIM_LIGHTING1)
159  float rl1_dist = exp2(-_Rim_Lighting1_Power * abs(rl_radius - _Rim_Lighting1_Center));
160#if defined(_RIM_LIGHTING1_ANGLE_LIMIT)
161  rl1_dist *= getAngleAttenuation(muv, _Rim_Lighting1_Angle_Limit_Target_Vector,
162      _Rim_Lighting1_Angle_Limit_Power);
163#endif
164#if defined(_RIM_LIGHTING1_QUANTIZATION)
165  rl1_dist = floor(rl1_dist * _Rim_Lighting1_Quantization_Steps) / _Rim_Lighting1_Quantization_Steps;
166#endif
167  float3 rl1 = _Rim_Lighting1_Color * _Rim_Lighting1_Brightness * rl1_dist;
168#if defined(_RIM_LIGHTING1_MASK)
169  float rl1_mask = _Rim_Lighting1_Mask.Sample(linear_repeat_s, UV_SCOFF(i, _Rim_Lighting1_Mask_ST, /*which_channel=*/0));
170#else
171  float rl1_mask = 1;
172#endif
173  applyMatcap(pbr, l, rl1, _Rim_Lighting1_Mode, _Rim_Lighting1_Target_Mask, rl1_mask);
174#endif  // _RIM_LIGHTING1
175
176#if defined(_RIM_LIGHTING2)
177  float rl2_dist = exp2(-_Rim_Lighting2_Power * abs(rl_radius - _Rim_Lighting2_Center));
178#if defined(_RIM_LIGHTING2_ANGLE_LIMIT)
179  rl2_dist *= getAngleAttenuation(muv, _Rim_Lighting2_Angle_Limit_Target_Vector,
180      _Rim_Lighting2_Angle_Limit_Power);
181#endif
182#if defined(_RIM_LIGHTING2_QUANTIZATION)
183  rl2_dist = floor(rl2_dist * _Rim_Lighting2_Quantization_Steps) / _Rim_Lighting2_Quantization_Steps;
184#endif
185  float3 rl2 = _Rim_Lighting2_Color * _Rim_Lighting2_Brightness * rl2_dist;
186#if defined(_RIM_LIGHTING2_MASK)
187  float rl2_mask = _Rim_Lighting2_Mask.Sample(linear_repeat_s, UV_SCOFF(i, _Rim_Lighting2_Mask_ST, /*which_channel=*/0));
188#else
189  float rl2_mask = 1;
190#endif
191  applyMatcap(pbr, l, rl2, _Rim_Lighting2_Mode, _Rim_Lighting2_Target_Mask, rl2_mask);
192#endif  // _RIM_LIGHTING2
193
194#if defined(_RIM_LIGHTING3)
195  float rl3_dist = exp2(-_Rim_Lighting3_Power * abs(rl_radius - _Rim_Lighting3_Center));
196#if defined(_RIM_LIGHTING3_ANGLE_LIMIT)
197  rl3_dist *= getAngleAttenuation(muv, _Rim_Lighting3_Angle_Limit_Target_Vector,
198      _Rim_Lighting3_Angle_Limit_Power);
199#endif
200#if defined(_RIM_LIGHTING3_QUANTIZATION)
201  rl3_dist = floor(rl3_dist * _Rim_Lighting3_Quantization_Steps) / _Rim_Lighting3_Quantization_Steps;
202#endif
203  float3 rl3 = _Rim_Lighting3_Color * _Rim_Lighting3_Brightness * rl3_dist;
204#if defined(_RIM_LIGHTING3_MASK)
205  float rl3_mask = _Rim_Lighting3_Mask.Sample(linear_repeat_s, UV_SCOFF(i, _Rim_Lighting3_Mask_ST, /*which_channel=*/0));
206#else
207  float rl3_mask = 1;
208#endif
209  applyMatcap(pbr, l, rl3, _Rim_Lighting3_Mode, _Rim_Lighting3_Target_Mask, rl3_mask);
210#endif  // _RIM_LIGHTING3
211}
212
213#endif
214