yum-archive/2ner
A toon shader for Unity's BIRP.
git clone https://git.yummers.dev/yum-archive/2ner
a54b415
master
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