#ifndef __DECAL_INC #define __DECAL_INC #include "data.cginc" #include "interpolators.cginc" #include "math.cginc" #include "texture_utils.cginc" float4 decal_sample(texture2D tex, float2 uv, int uv_mode) { [forcecase] switch (uv_mode) { case DECAL_UV_MODE_REPEAT: return tex.Sample(aniso4_trilinear_repeat_s, uv); case DECAL_UV_MODE_MIRROR: return tex.Sample(aniso4_trilinear_mirror_s, uv); case DECAL_UV_MODE_CLAMP: return tex.Sample(aniso4_trilinear_clamp_s, uv); default: return 0; } } float2 decal_rotate(float2 uv, float rotation) { float s, c; sincos(rotation * TAU, s, c); float2 d = uv - 0.5; return float2(d.x * c - d.y * s, d.x * s + d.y * c) + 0.5; } #define APPLY_DECAL(N) \ { \ float2 uv = get_uv_by_channel(i, _Decal##N##_UV_Channel); \ uv -= _Decal##N##_MainTex_ST.zw; \ uv *= _Decal##N##_MainTex_ST.xy; \ if (_Decal##N##_Rotation_Enabled) \ uv = decal_rotate(uv, _Decal##N##_Rotation); \ float4 albedo = decal_sample(_Decal##N##_MainTex, uv, _Decal##N##_UV_Mode); \ if (_Decal##N##_SDF_Enabled) { \ float sd = _Decal##N##_SDF_Invert ? 1 - albedo.r : albedo.r; \ float d = sd - _Decal##N##_SDF_Threshold; \ float w = fwidth(d) * 0.5; \ albedo.rgb = sd; \ albedo.a = smoothstep(-w, w, d); \ } \ albedo *= _Decal##N##_Color; \ albedo.a *= _Decal##N##_Opacity; \ if (_Decal##N##_Mask_Enabled) { \ float2 mask_uv = get_uv_by_channel(i, _Decal##N##_Mask_UV_Channel); \ mask_uv -= _Decal##N##_Mask_ST.zw; \ mask_uv *= _Decal##N##_Mask_ST.xy; \ float mask = decal_sample(_Decal##N##_Mask, mask_uv, _Decal##N##_UV_Mode); \ if (_Decal##N##_Mask_Invert) mask = 1 - mask; \ albedo.a *= mask; \ } \ if (_Decal##N##_Albedo_Clamp) albedo.rgb = saturate(albedo.rgb); \ [forcecase] \ switch (_Decal##N##_Mix_Mode) { \ case DECAL_MIX_MODE_ALPHA_BLEND: \ pbr.albedo = alpha_blend(albedo, pbr.albedo); \ break; \ case DECAL_MIX_MODE_MULTIPLY: \ pbr.albedo.rgb *= lerp(1, albedo.rgb, albedo.a); \ break; \ case DECAL_MIX_MODE_ADD_PRODUCT: \ pbr.albedo.rgb += lerp(0, albedo.rgb * pbr.albedo.rgb, albedo.a); \ break; \ } \ if (_Decal##N##_Metallic_Gloss_Enabled) { \ float4 mg = decal_sample(_Decal##N##_Metallic_Gloss, uv, _Decal##N##_UV_Mode); \ pbr.metallic = lerp(pbr.metallic, mg.r * _Decal##N##_Metallic, albedo.a); \ pbr.smoothness = lerp(pbr.smoothness, mg.a * _Decal##N##_Gloss, albedo.a); \ } \ if (_Decal##N##_Normal_Enabled) { \ float3 dn = UnpackNormal(decal_sample(_Decal##N##_Normal, uv, _Decal##N##_UV_Mode)); \ dn.xy *= _Decal##N##_Normal_Scale; \ normal_tangent = blendNormalsHill12(normal_tangent, float3(dn.xy * albedo.a, dn.z)); \ } \ } void applyDecals(v2f i, inout Pbr pbr, inout float3 normal_tangent) { #if defined(_DECAL0) APPLY_DECAL(0) #endif #if defined(_DECAL1) APPLY_DECAL(1) #endif #if defined(_DECAL2) APPLY_DECAL(2) #endif #if defined(_DECAL3) APPLY_DECAL(3) #endif #if defined(_DECAL4) APPLY_DECAL(4) #endif #if defined(_DECAL5) APPLY_DECAL(5) #endif #if defined(_DECAL6) APPLY_DECAL(6) #endif #if defined(_DECAL7) APPLY_DECAL(7) #endif } #endif // __DECAL_INC