#ifndef __DECAL_INC #define __DECAL_INC #include "globals.cginc" #include "pbr.cginc" #include "interpolators.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); \ if (_Decal##N##_Rotation_Enabled) \ uv = decal_rotate(uv, _Decal##N##_Rotation); \ uv -= _Decal##N##_MainTex_ST.zw; \ uv *= _Decal##N##_MainTex_ST.xy; \ float4 albedo = decal_sample(_Decal##N##_MainTex, uv, _Decal##N##_UV_Mode); \ 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, albedo.a); \ pbr.smoothness = lerp(pbr.smoothness, mg.a, albedo.a); \ pbr.roughness_perceptual = clamp(1 - pbr.smoothness, MIN_PERCEPTUAL_ROUGHNESS, 1); \ pbr.roughness = clamp(pbr.roughness_perceptual * pbr.roughness_perceptual, MIN_ROUGHNESS, 1); \ } \ } void applyDecals(v2f i, inout Pbr pbr) { #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