yum/3ner
A toon shader for Unity's BIRP.
git clone https://git.yummers.dev/yum/3ner
70f2b5f
master
1#ifndef __DECAL_INC 2#define __DECAL_INC 3 4#include "data.cginc" 5#include "interpolators.cginc" 6#include "math.cginc" 7#include "texture_utils.cginc" 8 9float4 decal_sample(texture2D tex, float2 uv, int uv_mode) { 10 [forcecase] 11 switch (uv_mode) { 12 case DECAL_UV_MODE_REPEAT: 13 return tex.Sample(aniso4_trilinear_repeat_s, uv); 14 case DECAL_UV_MODE_MIRROR: 15 return tex.Sample(aniso4_trilinear_mirror_s, uv); 16 case DECAL_UV_MODE_CLAMP: 17 return tex.Sample(aniso4_trilinear_clamp_s, uv); 18 default: 19 return 0; 20 } 21} 22 23float2 decal_rotate(float2 uv, float rotation) { 24 float s, c; 25 sincos(rotation * TAU, s, c); 26 float2 d = uv - 0.5; 27 return float2(d.x * c - d.y * s, d.x * s + d.y * c) + 0.5; 28} 29 30#if defined(_DECAL0_REPLACE_ALPHA) 31#define APPLY_DECAL_REPLACE_ALPHA_0 pbr.albedo.a = lerp(albedo_alpha_before_decal, decal_alpha_at_full_opacity, _Decal0_Opacity); 32#else 33#define APPLY_DECAL_REPLACE_ALPHA_0 34#endif 35#if defined(_DECAL1_REPLACE_ALPHA) 36#define APPLY_DECAL_REPLACE_ALPHA_1 pbr.albedo.a = lerp(albedo_alpha_before_decal, decal_alpha_at_full_opacity, _Decal1_Opacity); 37#else 38#define APPLY_DECAL_REPLACE_ALPHA_1 39#endif 40#if defined(_DECAL2_REPLACE_ALPHA) 41#define APPLY_DECAL_REPLACE_ALPHA_2 pbr.albedo.a = lerp(albedo_alpha_before_decal, decal_alpha_at_full_opacity, _Decal2_Opacity); 42#else 43#define APPLY_DECAL_REPLACE_ALPHA_2 44#endif 45#if defined(_DECAL3_REPLACE_ALPHA) 46#define APPLY_DECAL_REPLACE_ALPHA_3 pbr.albedo.a = lerp(albedo_alpha_before_decal, decal_alpha_at_full_opacity, _Decal3_Opacity); 47#else 48#define APPLY_DECAL_REPLACE_ALPHA_3 49#endif 50#if defined(_DECAL4_REPLACE_ALPHA) 51#define APPLY_DECAL_REPLACE_ALPHA_4 pbr.albedo.a = lerp(albedo_alpha_before_decal, decal_alpha_at_full_opacity, _Decal4_Opacity); 52#else 53#define APPLY_DECAL_REPLACE_ALPHA_4 54#endif 55#if defined(_DECAL5_REPLACE_ALPHA) 56#define APPLY_DECAL_REPLACE_ALPHA_5 pbr.albedo.a = lerp(albedo_alpha_before_decal, decal_alpha_at_full_opacity, _Decal5_Opacity); 57#else 58#define APPLY_DECAL_REPLACE_ALPHA_5 59#endif 60#if defined(_DECAL6_REPLACE_ALPHA) 61#define APPLY_DECAL_REPLACE_ALPHA_6 pbr.albedo.a = lerp(albedo_alpha_before_decal, decal_alpha_at_full_opacity, _Decal6_Opacity); 62#else 63#define APPLY_DECAL_REPLACE_ALPHA_6 64#endif 65#if defined(_DECAL7_REPLACE_ALPHA) 66#define APPLY_DECAL_REPLACE_ALPHA_7 pbr.albedo.a = lerp(albedo_alpha_before_decal, decal_alpha_at_full_opacity, _Decal7_Opacity); 67#else 68#define APPLY_DECAL_REPLACE_ALPHA_7 69#endif 70 71#if defined(_DECAL0_REPLACE_ALPHA) || defined(_DECAL1_REPLACE_ALPHA) || defined(_DECAL2_REPLACE_ALPHA) || defined(_DECAL3_REPLACE_ALPHA) || defined(_DECAL4_REPLACE_ALPHA) || defined(_DECAL5_REPLACE_ALPHA) || defined(_DECAL6_REPLACE_ALPHA) || defined(_DECAL7_REPLACE_ALPHA) 72#define PREPARE_DECAL_REPLACE_ALPHA \ 73 float albedo_alpha_before_decal = pbr.albedo.a; \ 74 float decal_alpha_at_full_opacity = albedo.a; 75#else 76#define PREPARE_DECAL_REPLACE_ALPHA 77#endif 78 79#define APPLY_DECAL_REPLACE_ALPHA_IMPL(N) APPLY_DECAL_REPLACE_ALPHA_##N 80#define APPLY_DECAL_REPLACE_ALPHA(N) APPLY_DECAL_REPLACE_ALPHA_IMPL(N) 81 82#define APPLY_DECAL(N) \ 83 { \ 84 float2 uv = get_uv_by_channel(i, _Decal##N##_UV_Channel); \ 85 uv -= _Decal##N##_MainTex_ST.zw; \ 86 uv *= _Decal##N##_MainTex_ST.xy; \ 87 if (_Decal##N##_Rotation_Enabled) \ 88 uv = decal_rotate(uv, _Decal##N##_Rotation); \ 89 float4 albedo = decal_sample(_Decal##N##_MainTex, uv, _Decal##N##_UV_Mode); \ 90 if (_Decal##N##_SDF_Enabled) { \ 91 float sd = _Decal##N##_SDF_Invert ? 1 - albedo.r : albedo.r; \ 92 float d = sd - _Decal##N##_SDF_Threshold; \ 93 float w = fwidth(d) * 0.5; \ 94 albedo.rgb = sd; \ 95 albedo.a = smoothstep(-w, w, d); \ 96 } \ 97 albedo *= _Decal##N##_Color; \ 98 if (_Decal##N##_Mask_Enabled) { \ 99 float2 mask_uv = get_uv_by_channel(i, _Decal##N##_Mask_UV_Channel); \ 100 mask_uv -= _Decal##N##_Mask_ST.zw; \ 101 mask_uv *= _Decal##N##_Mask_ST.xy; \ 102 float mask = decal_sample(_Decal##N##_Mask, mask_uv, _Decal##N##_UV_Mode); \ 103 if (_Decal##N##_Mask_Invert) mask = 1 - mask; \ 104 albedo.a *= mask; \ 105 } \ 106 PREPARE_DECAL_REPLACE_ALPHA \ 107 albedo.a *= _Decal##N##_Opacity; \ 108 if (_Decal##N##_Albedo_Clamp) albedo.rgb = saturate(albedo.rgb); \ 109 [forcecase] \ 110 switch (_Decal##N##_Mix_Mode) { \ 111 case DECAL_MIX_MODE_ALPHA_BLEND: \ 112 pbr.albedo = alpha_blend(albedo, pbr.albedo); \ 113 break; \ 114 case DECAL_MIX_MODE_MULTIPLY: \ 115 pbr.albedo.rgb *= lerp(1, albedo.rgb, albedo.a); \ 116 break; \ 117 case DECAL_MIX_MODE_ADD_PRODUCT: \ 118 pbr.albedo.rgb += lerp(0, albedo.rgb * pbr.albedo.rgb, albedo.a); \ 119 break; \ 120 } \ 121 APPLY_DECAL_REPLACE_ALPHA(N) \ 122 if (_Decal##N##_Metallic_Gloss_Enabled) { \ 123 float4 mg = decal_sample(_Decal##N##_Metallic_Gloss, uv, _Decal##N##_UV_Mode); \ 124 pbr.metallic = lerp(pbr.metallic, mg.r * _Decal##N##_Metallic, albedo.a); \ 125 pbr.smoothness = lerp(pbr.smoothness, mg.a * _Decal##N##_Gloss, albedo.a); \ 126 } \ 127 if (_Decal##N##_Normal_Enabled) { \ 128 float3 dn = UnpackNormal(decal_sample(_Decal##N##_Normal, uv, _Decal##N##_UV_Mode)); \ 129 dn.xy *= _Decal##N##_Normal_Scale; \ 130 normal_tangent = blendNormalsHill12(normal_tangent, float3(dn.xy * albedo.a, dn.z)); \ 131 } \ 132 } 133 134void applyDecals(v2f i, inout Pbr pbr, inout float3 normal_tangent) { 135#if defined(_DECAL0) 136 APPLY_DECAL(0) 137#endif 138#if defined(_DECAL1) 139 APPLY_DECAL(1) 140#endif 141#if defined(_DECAL2) 142 APPLY_DECAL(2) 143#endif 144#if defined(_DECAL3) 145 APPLY_DECAL(3) 146#endif 147#if defined(_DECAL4) 148 APPLY_DECAL(4) 149#endif 150#if defined(_DECAL5) 151 APPLY_DECAL(5) 152#endif 153#if defined(_DECAL6) 154 APPLY_DECAL(6) 155#endif 156#if defined(_DECAL7) 157 APPLY_DECAL(7) 158#endif 159} 160 161#endif // __DECAL_INC