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