summaryrefslogtreecommitdiffstats
path: root/decal.cginc
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2026-03-06 15:10:27 -0800
committeryum <yum.food.vr@gmail.com>2026-03-06 15:10:27 -0800
commit20234b7fdc550fd3d2542391ac5bb735a7edb820 (patch)
treef9ef3c10151a1186743dac32b1c25b891a171006 /decal.cginc
parent86680bb2efb0854d95de8ca1dabbd7399d806dd9 (diff)
Switch from #ifdef to uniform branches for decals
Makes code much smaller & simpler, and shader locker constant folding should make it just as efficient.
Diffstat (limited to 'decal.cginc')
-rw-r--r--decal.cginc236
1 files changed, 44 insertions, 192 deletions
diff --git a/decal.cginc b/decal.cginc
index 5f60fe7..aee7cf0 100644
--- a/decal.cginc
+++ b/decal.cginc
@@ -27,206 +27,58 @@ float2 decal_rotate(float2 uv, float rotation) {
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); \
+ 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)
- {
- float2 uv = get_uv_by_channel(i, _Decal0_UV_Channel);
- uv -= _Decal0_MainTex_ST.zw;
- uv *= _Decal0_MainTex_ST.xy;
-#if defined(_DECAL0_ROTATION)
- uv = decal_rotate(uv, _Decal0_Rotation);
-#endif
- float4 albedo = decal_sample(_Decal0_MainTex, uv, _Decal0_UV_Mode);
- albedo *= _Decal0_Color;
- albedo.a *= _Decal0_Opacity;
-
-#if defined(_DECAL0_MASK)
- float2 mask_uv = get_uv_by_channel(i, _Decal0_Mask_UV_Channel);
- mask_uv -= _Decal0_Mask_ST.zw;
- mask_uv *= _Decal0_Mask_ST.xy;
- // For now, mask gets the same sampling mode as the decal.
- float mask = decal_sample(_Decal0_Mask, mask_uv, _Decal0_UV_Mode);
-#if defined(_DECAL0_MASK_INVERT)
- mask = 1 - mask;
-#endif // _DECAL0_MASK_INVERT
- albedo.a *= mask;
-#endif // _DECAL0_MASK
-
-#if defined(_DECAL0_ALBEDO_CLAMP)
- albedo.rgb = saturate(albedo.rgb);
-#endif // _DECAL0_ALBEDO_CLAMP
-
- [forcecase]
- switch (_Decal0_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 defined(_DECAL0_METALLIC_GLOSS)
- float4 mg = decal_sample(_Decal0_Metallic_Gloss, uv, _Decal0_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);
-#endif // _DECAL0_METALLIC_GLOSS
- }
+ APPLY_DECAL(0)
#endif
-
#if defined(_DECAL1)
- {
- float2 uv = get_uv_by_channel(i, _Decal1_UV_Channel);
- uv -= _Decal1_MainTex_ST.zw;
- uv *= _Decal1_MainTex_ST.xy;
-#if defined(_DECAL1_ROTATION)
- uv = decal_rotate(uv, _Decal1_Rotation);
-#endif
- float4 albedo = decal_sample(_Decal1_MainTex, uv, _Decal1_UV_Mode);
- albedo *= _Decal1_Color;
- albedo.a *= _Decal1_Opacity;
-
-#if defined(_DECAL1_MASK)
- float2 mask_uv = get_uv_by_channel(i, _Decal1_Mask_UV_Channel);
- mask_uv -= _Decal1_Mask_ST.zw;
- mask_uv *= _Decal1_Mask_ST.xy;
- float mask = decal_sample(_Decal1_Mask, mask_uv, _Decal1_UV_Mode);
-#if defined(_DECAL1_MASK_INVERT)
- mask = 1 - mask;
-#endif // _DECAL1_MASK_INVERT
- albedo.a *= mask;
-#endif // _DECAL1_MASK
-
-#if defined(_DECAL1_ALBEDO_CLAMP)
- albedo.rgb = saturate(albedo.rgb);
-#endif // _DECAL1_ALBEDO_CLAMP
-
- [forcecase]
- switch (_Decal1_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 defined(_DECAL1_METALLIC_GLOSS)
- float4 mg = decal_sample(_Decal1_Metallic_Gloss, uv, _Decal1_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);
-#endif // _DECAL1_METALLIC_GLOSS
- }
+ APPLY_DECAL(1)
#endif
-
#if defined(_DECAL2)
- {
- float2 uv = get_uv_by_channel(i, _Decal2_UV_Channel);
- uv -= _Decal2_MainTex_ST.zw;
- uv *= _Decal2_MainTex_ST.xy;
-#if defined(_DECAL2_ROTATION)
- uv = decal_rotate(uv, _Decal2_Rotation);
-#endif
- float4 albedo = decal_sample(_Decal2_MainTex, uv, _Decal2_UV_Mode);
- albedo *= _Decal2_Color;
- albedo.a *= _Decal2_Opacity;
-
-#if defined(_DECAL2_MASK)
- float2 mask_uv = get_uv_by_channel(i, _Decal2_Mask_UV_Channel);
- mask_uv -= _Decal2_Mask_ST.zw;
- mask_uv *= _Decal2_Mask_ST.xy;
- float mask = decal_sample(_Decal2_Mask, mask_uv, _Decal2_UV_Mode);
-#if defined(_DECAL2_MASK_INVERT)
- mask = 1 - mask;
-#endif // _DECAL2_MASK_INVERT
- albedo.a *= mask;
-#endif // _DECAL2_MASK
-
-#if defined(_DECAL2_ALBEDO_CLAMP)
- albedo.rgb = saturate(albedo.rgb);
-#endif // _DECAL2_ALBEDO_CLAMP
-
- [forcecase]
- switch (_Decal2_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 defined(_DECAL2_METALLIC_GLOSS)
- float4 mg = decal_sample(_Decal2_Metallic_Gloss, uv, _Decal2_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);
-#endif // _DECAL2_METALLIC_GLOSS
- }
+ APPLY_DECAL(2)
#endif
-
#if defined(_DECAL3)
- {
- float2 uv = get_uv_by_channel(i, _Decal3_UV_Channel);
- uv -= _Decal3_MainTex_ST.zw;
- uv *= _Decal3_MainTex_ST.xy;
-#if defined(_DECAL3_ROTATION)
- uv = decal_rotate(uv, _Decal3_Rotation);
-#endif
- float4 albedo = decal_sample(_Decal3_MainTex, uv, _Decal3_UV_Mode);
- albedo *= _Decal3_Color;
- albedo.a *= _Decal3_Opacity;
-
-#if defined(_DECAL3_MASK)
- float2 mask_uv = get_uv_by_channel(i, _Decal3_Mask_UV_Channel);
- mask_uv -= _Decal3_Mask_ST.zw;
- mask_uv *= _Decal3_Mask_ST.xy;
- float mask = decal_sample(_Decal3_Mask, mask_uv, _Decal3_UV_Mode);
-#if defined(_DECAL3_MASK_INVERT)
- mask = 1 - mask;
-#endif // _DECAL3_MASK_INVERT
- albedo.a *= mask;
-#endif // _DECAL3_MASK
-
-#if defined(_DECAL3_ALBEDO_CLAMP)
- albedo.rgb = saturate(albedo.rgb);
-#endif // _DECAL3_ALBEDO_CLAMP
-
- [forcecase]
- switch (_Decal3_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 defined(_DECAL3_METALLIC_GLOSS)
- float4 mg = decal_sample(_Decal3_Metallic_Gloss, uv, _Decal3_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);
-#endif // _DECAL3_METALLIC_GLOSS
- }
+ APPLY_DECAL(3)
#endif
}