diff options
| author | yum <yum.food.vr@gmail.com> | 2026-03-06 15:10:27 -0800 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2026-03-06 15:10:27 -0800 |
| commit | 20234b7fdc550fd3d2542391ac5bb735a7edb820 (patch) | |
| tree | f9ef3c10151a1186743dac32b1c25b891a171006 /decal.cginc | |
| parent | 86680bb2efb0854d95de8ca1dabbd7399d806dd9 (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.cginc | 236 |
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 } |
