yum/3ner

A toon shader for Unity's BIRP.

git clone https://git.yummers.dev/yum/3ner

yumadd matcap albedo clamp togglee7b8483

master
4.2 KiB149 linesraw
1#ifndef __MATCAPS_INC
2#define __MATCAPS_INC
3
4#include "globals.cginc"
5#include "lighting.cginc"
6#include "math.cginc"
7#include "pbr.cginc"
8#include "texture_utils.cginc"
9
10#if defined(_MATCAP0) || defined(_MATCAP1) || defined(_RIM_LIGHTING0)
11#define HAS_MATCAP_RL
12#endif
13
14#if defined(HAS_MATCAP_RL)
15float2 getMatcapUV(v2f i, Pbr pbr) {
16  const float3 cam_normal = normalize(mul(UNITY_MATRIX_V, float4(pbr.normal, 0)));
17  const float3 cam_view_dir = normalize(mul(UNITY_MATRIX_V, float4(-i.eyeVec.xyz, 0)));
18  const float3 cam_refl = -reflect(cam_view_dir, cam_normal);
19  float m = 2.0 * sqrt(
20      cam_refl.x * cam_refl.x +
21      cam_refl.y * cam_refl.y +
22      (cam_refl.z + 1) * (cam_refl.z + 1));
23  return cam_refl.xy / m + 0.5;
24}
25
26void applyMatcapImpl(inout float3 color, float3 sample, uint mode, float mask)
27{
28  [forcecase]
29  switch(mode) {
30    case MATCAP_MODE_REPLACE:
31      color.rgb = lerp(color.rgb, sample, mask);
32      break;
33    case MATCAP_MODE_ADD:
34      color.rgb += lerp(0, sample, mask);
35      break;
36    case MATCAP_MODE_MULTIPLY:
37      color.rgb *= lerp(1, sample, mask);
38      break;
39    case MATCAP_MODE_SUBTRACT:
40      color.rgb -= lerp(0, sample, mask);
41      break;
42    case MATCAP_MODE_ADD_PRODUCT:
43      color.rgb += lerp(0, sample * color.rgb, mask);
44      break;
45    default:
46      break;
47  }
48}
49
50void applyMatcap(inout Pbr pbr, float3 sample, uint mode, float mask)
51{
52  applyMatcapImpl(pbr.albedo.rgb, sample, mode, mask);
53}
54
55float2 quantizeMatcapUV(float2 muv, float muv_r, float steps) {
56  float muv_r_q = floor(muv_r * steps) / steps;
57  const float epsilon = 1e-4f;
58  return muv_r_q * (muv / max(epsilon, muv_r));
59}
60#endif  // HAS_MATCAP_RL
61
62void apply_matcaps_and_rim_lighting(v2f i, inout Pbr pbr, inout LightData light_data) {
63#if defined(HAS_MATCAP_RL)
64  float2 muv = getMatcapUV(i, pbr);
65  float2 muv_centered = muv * 2 - 1;
66  float muv_r = length(muv_centered);
67#endif
68
69#if defined(_MATCAP0)
70#if defined(_MATCAP0_QUANTIZATION)
71  float2 m0uv = quantizeMatcapUV(muv, muv_r, _Matcap0_Quantization_Steps);
72#else
73  float2 m0uv = muv;
74#endif
75  float3 m0 = _Matcap0.Sample(linear_repeat_s, m0uv);
76  m0 = _Matcap0_Invert ? 1 - m0 : m0;
77  m0 *= _Matcap0_Strength;
78#if defined(_MATCAP0_MASK)
79  float m0_mask = _Matcap0_Mask.Sample(linear_repeat_s, UV_SCOFF(i, _Matcap0_Mask_ST, /*which_channel=*/0));
80#else
81  float m0_mask = 1;
82#endif
83  applyMatcap(pbr, m0, _Matcap0_Mode, m0_mask);
84#if defined(_MATCAP0_ALBEDO_CLAMP)
85  pbr.albedo.rgb = saturate(pbr.albedo.rgb);
86#endif
87#endif  // _MATCAP0
88
89#if defined(_MATCAP1)
90#if defined(_MATCAP1_QUANTIZATION)
91  float2 m1uv = quantizeMatcapUV(muv, muv_r, _Matcap1_Quantization_Steps);
92#else
93  float2 m1uv = muv;
94#endif
95  float3 m1 = _Matcap1.Sample(linear_repeat_s, m1uv);
96  m1 = _Matcap1_Invert ? 1 - m1 : m1;
97  m1 *= _Matcap1_Strength;
98#if defined(_MATCAP1_MASK)
99  float m1_mask = _Matcap1_Mask.Sample(linear_repeat_s, UV_SCOFF(i, _Matcap1_Mask_ST, /*which_channel=*/0));
100#else
101  float m1_mask = 1;
102#endif
103  applyMatcap(pbr, m1, _Matcap1_Mode, m1_mask);
104#if defined(_MATCAP1_ALBEDO_CLAMP)
105  pbr.albedo.rgb = saturate(pbr.albedo.rgb);
106#endif
107#endif  // _MATCAP1
108
109#if defined(_RIM_LIGHTING0)
110  // 1 at rim center, 0 outside blur radius.
111  float rl0_inner = smoothstep(
112      _Rim_Lighting0_Center - _Rim_Lighting0_Blur,
113      _Rim_Lighting0_Center,
114      muv_r);
115  float rl0_outer = 1 - smoothstep(
116      _Rim_Lighting0_Center,
117      _Rim_Lighting0_Center + _Rim_Lighting0_Blur,
118      muv_r);
119  float rl0_dist = rl0_inner * rl0_outer;
120#if defined(_RIM_LIGHTING0_QUANTIZATION)
121  rl0_dist = floor(rl0_dist * _Rim_Lighting0_Quantization_Steps) / _Rim_Lighting0_Quantization_Steps;
122#endif
123
124  float3 rl0;
125  switch(_Rim_Lighting0_Mode) {
126    case MATCAP_MODE_ADD:
127      // Fall through.
128    case MATCAP_MODE_SUBTRACT:
129      rl0 = lerp(0, _Rim_Lighting0_Color, rl0_dist);
130      break;
131    case MATCAP_MODE_MULTIPLY:
132      rl0 = lerp(1, _Rim_Lighting0_Color, rl0_dist);
133      break;
134    default:
135      rl0 = lerp(pbr.albedo.xyz, _Rim_Lighting0_Color, rl0_dist);
136      break;
137  }
138
139#if defined(_RIM_LIGHTING0_MASK)
140  float rl0_mask = _Rim_Lighting0_Mask.Sample(linear_repeat_s, UV_SCOFF(i, _Rim_Lighting0_Mask_ST, /*which_channel=*/0));
141#else
142  float rl0_mask = 1;
143#endif
144  applyMatcap(pbr, rl0, _Rim_Lighting0_Mode, rl0_mask);
145#endif  // _RIM_LIGHTING0
146}
147
148#endif
149