summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2024-12-16 09:41:26 -0800
committeryum <yum.food.vr@gmail.com>2024-12-16 09:41:26 -0800
commitf27c89c6ba69ad7abbe60b03e0cc4ccc75f24369 (patch)
tree132a39b4e0c68d47cc3756a779cf0f03585c72c1
parent3b0aba19021e0288905e0f9b8e5398bbf8d6f003 (diff)
Add domain warping to decal feature
-rw-r--r--Editor/tooner.cs26
-rw-r--r--feature_macros.cginc10
-rw-r--r--globals.cginc8
-rw-r--r--tooner.shader62
-rw-r--r--tooner_lighting.cginc61
5 files changed, 147 insertions, 20 deletions
diff --git a/Editor/tooner.cs b/Editor/tooner.cs
index 865934d..60a5c2d 100644
--- a/Editor/tooner.cs
+++ b/Editor/tooner.cs
@@ -591,6 +591,11 @@ public class ToonerGUI : ShaderGUI {
RangeProperty(bc, "Alpha multiplier");
bc = FindProperty($"_Decal{i}_Round_Alpha_Multiplier");
+ enabled = bc.floatValue > 1E-6;
+ EditorGUI.BeginChangeCheck();
+ enabled = Toggle("Round alpha multiplier", enabled);
+ EditorGUI.EndChangeCheck();
+ bc.floatValue = enabled ? 1.0f : 0.0f;
bct = FindProperty($"_Decal{i}_Mask");
TexturePropertySingleLine(MakeLabel(bct, "Mask"), bct);
@@ -615,6 +620,27 @@ public class ToonerGUI : ShaderGUI {
RangeProperty(
bc,
"UV channel");
+
+ bc = FindProperty($"_Decal{i}_Domain_Warping_Enable_Static");
+ enabled = bc.floatValue > 1E-6;
+ EditorGUI.BeginChangeCheck();
+ enabled = Toggle("Enable domain warping", enabled);
+ EditorGUI.EndChangeCheck();
+ bc.floatValue = enabled ? 1.0f : 0.0f;
+ SetKeyword($"_DECAL{i}_DOMAIN_WARPING", enabled);
+
+ if (enabled) {
+ bc = FindProperty($"_Decal{i}_Domain_Warping_Noise");
+ TexturePropertySingleLine(MakeLabel(bc, "Domain warping noise"), bc);
+ bc = FindProperty($"_Decal{i}_Domain_Warping_Strength");
+ FloatProperty(bc, "Domain warping noise strength");
+ bc = FindProperty($"_Decal{i}_Domain_Warping_Speed");
+ FloatProperty(bc, "Domain warping noise speed");
+ bc = FindProperty($"_Decal{i}_Domain_Warping_Octaves");
+ FloatProperty(bc, "Domain warping octaves");
+ bc = FindProperty($"_Decal{i}_Domain_Warping_Scale");
+ FloatProperty(bc, "Domain warping scale");
+ }
}
EditorGUI.indentLevel -= 1;
show_ui.RemoveAt(show_ui.Count - 1);
diff --git a/feature_macros.cginc b/feature_macros.cginc
index e57117e..3c358fb 100644
--- a/feature_macros.cginc
+++ b/feature_macros.cginc
@@ -178,42 +178,52 @@
#pragma shader_feature_local _ _DECAL0_ROUGHNESS
#pragma shader_feature_local _ _DECAL0_METALLIC
#pragma shader_feature_local _ _DECAL0_MASK
+#pragma shader_feature_local _ _DECAL0_DOMAIN_WARPING
#pragma shader_feature_local _ _DECAL1
#pragma shader_feature_local _ _DECAL1_ROUGHNESS
#pragma shader_feature_local _ _DECAL1_METALLIC
#pragma shader_feature_local _ _DECAL1_MASK
+#pragma shader_feature_local _ _DECAL1_DOMAIN_WARPING
#pragma shader_feature_local _ _DECAL2
#pragma shader_feature_local _ _DECAL2_ROUGHNESS
#pragma shader_feature_local _ _DECAL2_METALLIC
#pragma shader_feature_local _ _DECAL2_MASK
+#pragma shader_feature_local _ _DECAL2_DOMAIN_WARPING
#pragma shader_feature_local _ _DECAL3
#pragma shader_feature_local _ _DECAL3_ROUGHNESS
#pragma shader_feature_local _ _DECAL3_METALLIC
#pragma shader_feature_local _ _DECAL3_MASK
+#pragma shader_feature_local _ _DECAL3_DOMAIN_WARPING
#pragma shader_feature_local _ _DECAL4
#pragma shader_feature_local _ _DECAL4_ROUGHNESS
#pragma shader_feature_local _ _DECAL4_METALLIC
#pragma shader_feature_local _ _DECAL4_MASK
+#pragma shader_feature_local _ _DECAL4_DOMAIN_WARPING
#pragma shader_feature_local _ _DECAL5
#pragma shader_feature_local _ _DECAL5_ROUGHNESS
#pragma shader_feature_local _ _DECAL5_METALLIC
#pragma shader_feature_local _ _DECAL5_MASK
+#pragma shader_feature_local _ _DECAL5_DOMAIN_WARPING
#pragma shader_feature_local _ _DECAL6
#pragma shader_feature_local _ _DECAL6_ROUGHNESS
#pragma shader_feature_local _ _DECAL6_METALLIC
#pragma shader_feature_local _ _DECAL6_MASK
+#pragma shader_feature_local _ _DECAL6_DOMAIN_WARPING
#pragma shader_feature_local _ _DECAL7
#pragma shader_feature_local _ _DECAL7_ROUGHNESS
#pragma shader_feature_local _ _DECAL7_METALLIC
#pragma shader_feature_local _ _DECAL7_MASK
+#pragma shader_feature_local _ _DECAL7_DOMAIN_WARPING
#pragma shader_feature_local _ _DECAL8
#pragma shader_feature_local _ _DECAL8_ROUGHNESS
#pragma shader_feature_local _ _DECAL8_METALLIC
#pragma shader_feature_local _ _DECAL8_MASK
+#pragma shader_feature_local _ _DECAL8_DOMAIN_WARPING
#pragma shader_feature_local _ _DECAL9
#pragma shader_feature_local _ _DECAL9_ROUGHNESS
#pragma shader_feature_local _ _DECAL9_METALLIC
#pragma shader_feature_local _ _DECAL9_MASK
+#pragma shader_feature_local _ _DECAL9_DOMAIN_WARPING
#pragma shader_feature_local _ _LTCGI
#pragma shader_feature_local _ _TESSELLATION
#pragma shader_feature_local _ _MATCAP0_DISTORTION0
diff --git a/globals.cginc b/globals.cginc
index 71147fb..f63453b 100644
--- a/globals.cginc
+++ b/globals.cginc
@@ -274,7 +274,13 @@ float MERGE(_Decal,n,_SDF_Threshold); \
float MERGE(_Decal,n,_SDF_Softness); \
float MERGE(_Decal,n,_SDF_Px_Range); \
float MERGE(_Decal,n,_Tiling_Mode); \
-float MERGE(_Decal,n,_UV_Select);
+float MERGE(_Decal,n,_UV_Select); \
+float MERGE(_Decal,n,_Domain_Warping_Enable_Static); \
+texture2D MERGE(_Decal,n,_Domain_Warping_Noise); \
+float MERGE(_Decal,n,_Domain_Warping_Strength); \
+float MERGE(_Decal,n,_Domain_Warping_Speed); \
+float MERGE(_Decal,n,_Domain_Warping_Octaves); \
+float MERGE(_Decal,n,_Domain_Warping_Scale);
#define DECAL_MASK_PROPERTIES(n) \
texture2D MERGE(_Decal,n,_Mask); \
diff --git a/tooner.shader b/tooner.shader
index a515288..2598770 100644
--- a/tooner.shader
+++ b/tooner.shader
@@ -146,6 +146,12 @@ Shader "yum_food/tooner"
_Decal0_Mask_Invert("Mask invert", Float) = 0.0
_Decal0_Tiling_Mode("Tiling mode", Range(0,1)) = 0
_Decal0_UV_Select("UV channel", Range(0,7)) = 0
+ _Decal0_Domain_Warping_Enable_Static("Enable domain warping", Float) = 0
+ _Decal0_Domain_Warping_Noise("Domain warping noise", 2D) = "black" {}
+ _Decal0_Domain_Warping_Strength("Domain warping noise strength", Float) = 0.05
+ _Decal0_Domain_Warping_Speed("Domain warping noise speed", Float) = .1
+ _Decal0_Domain_Warping_Octaves("Domain warping octaves", Float) = 5
+ _Decal0_Domain_Warping_Scale("Domain warping scale", Float) = .1
_Decal1_Enable("Enable decal", Float) = 0.0
_Decal1_Color("Base color", Color) = (1, 1, 1, 1)
@@ -164,6 +170,12 @@ Shader "yum_food/tooner"
_Decal1_Mask_Invert("Mask invert", Float) = 0.0
_Decal1_Tiling_Mode("Tiling mode", Range(0,1)) = 0
_Decal1_UV_Select("UV channel", Range(0,7)) = 0
+ _Decal1_Domain_Warping_Enable_Static("Enable domain warping", Float) = 0
+ _Decal1_Domain_Warping_Noise("Domain warping noise", 2D) = "black" {}
+ _Decal1_Domain_Warping_Strength("Domain warping noise strength", Float) = 0.05
+ _Decal1_Domain_Warping_Speed("Domain warping noise speed", Float) = .1
+ _Decal1_Domain_Warping_Octaves("Domain warping octaves", Float) = 5
+ _Decal1_Domain_Warping_Scale("Domain warping scale", Float) = .1
_Decal2_Enable("Enable decal", Float) = 0.0
_Decal2_Color("Base color", Color) = (1, 1, 1, 1)
@@ -182,6 +194,12 @@ Shader "yum_food/tooner"
_Decal2_Mask_Invert("Mask invert", Float) = 0.0
_Decal2_Tiling_Mode("Tiling mode", Range(0,1)) = 0
_Decal2_UV_Select("UV channel", Range(0,7)) = 0
+ _Decal2_Domain_Warping_Enable_Static("Enable domain warping", Float) = 0
+ _Decal2_Domain_Warping_Noise("Domain warping noise", 2D) = "black" {}
+ _Decal2_Domain_Warping_Strength("Domain warping noise strength", Float) = 0.05
+ _Decal2_Domain_Warping_Speed("Domain warping noise speed", Float) = .1
+ _Decal2_Domain_Warping_Octaves("Domain warping octaves", Float) = 5
+ _Decal2_Domain_Warping_Scale("Domain warping scale", Float) = .1
_Decal3_Enable("Enable decal", Float) = 0.0
_Decal3_Color("Base color", Color) = (1, 1, 1, 1)
@@ -200,6 +218,12 @@ Shader "yum_food/tooner"
_Decal3_Mask_Invert("Mask invert", Float) = 0.0
_Decal3_Tiling_Mode("Tiling mode", Range(0,1)) = 0
_Decal3_UV_Select("UV channel", Range(0,7)) = 0
+ _Decal3_Domain_Warping_Enable_Static("Enable domain warping", Float) = 0
+ _Decal3_Domain_Warping_Noise("Domain warping noise", 2D) = "black" {}
+ _Decal3_Domain_Warping_Strength("Domain warping noise strength", Float) = 0.05
+ _Decal3_Domain_Warping_Speed("Domain warping noise speed", Float) = .1
+ _Decal3_Domain_Warping_Octaves("Domain warping octaves", Float) = 5
+ _Decal3_Domain_Warping_Scale("Domain warping scale", Float) = .1
_Decal4_Enable("Enable decal", Float) = 0.0
_Decal4_Color("Base color", Color) = (1, 1, 1, 1)
@@ -218,6 +242,12 @@ Shader "yum_food/tooner"
_Decal4_Mask_Invert("Mask invert", Float) = 0.0
_Decal4_Tiling_Mode("Tiling mode", Range(0,1)) = 0
_Decal4_UV_Select("UV channel", Range(0,7)) = 0
+ _Decal4_Domain_Warping_Enable_Static("Enable domain warping", Float) = 0
+ _Decal4_Domain_Warping_Noise("Domain warping noise", 2D) = "black" {}
+ _Decal4_Domain_Warping_Strength("Domain warping noise strength", Float) = 0.05
+ _Decal4_Domain_Warping_Speed("Domain warping noise speed", Float) = .1
+ _Decal4_Domain_Warping_Octaves("Domain warping octaves", Float) = 5
+ _Decal4_Domain_Warping_Scale("Domain warping scale", Float) = .1
_Decal5_Enable("Enable decal", Float) = 0.0
_Decal5_Color("Base color", Color) = (1, 1, 1, 1)
@@ -236,6 +266,12 @@ Shader "yum_food/tooner"
_Decal5_Mask_Invert("Mask invert", Float) = 0.0
_Decal5_Tiling_Mode("Tiling mode", Range(0,1)) = 0
_Decal5_UV_Select("UV channel", Range(0,7)) = 0
+ _Decal5_Domain_Warping_Enable_Static("Enable domain warping", Float) = 0
+ _Decal5_Domain_Warping_Noise("Domain warping noise", 2D) = "black" {}
+ _Decal5_Domain_Warping_Strength("Domain warping noise strength", Float) = 0.05
+ _Decal5_Domain_Warping_Speed("Domain warping noise speed", Float) = .1
+ _Decal5_Domain_Warping_Octaves("Domain warping octaves", Float) = 5
+ _Decal5_Domain_Warping_Scale("Domain warping scale", Float) = .1
_Decal6_Enable("Enable decal", Float) = 0.0
_Decal6_Color("Base color", Color) = (1, 1, 1, 1)
@@ -254,6 +290,12 @@ Shader "yum_food/tooner"
_Decal6_Mask_Invert("Mask invert", Float) = 0.0
_Decal6_Tiling_Mode("Tiling mode", Range(0,1)) = 0
_Decal6_UV_Select("UV channel", Range(0,7)) = 0
+ _Decal6_Domain_Warping_Enable_Static("Enable domain warping", Float) = 0
+ _Decal6_Domain_Warping_Noise("Domain warping noise", 2D) = "black" {}
+ _Decal6_Domain_Warping_Strength("Domain warping noise strength", Float) = 0.05
+ _Decal6_Domain_Warping_Speed("Domain warping noise speed", Float) = .1
+ _Decal6_Domain_Warping_Octaves("Domain warping octaves", Float) = 5
+ _Decal6_Domain_Warping_Scale("Domain warping scale", Float) = .1
_Decal7_Enable("Enable decal", Float) = 0.0
_Decal7_Color("Base color", Color) = (1, 1, 1, 1)
@@ -272,6 +314,12 @@ Shader "yum_food/tooner"
_Decal7_Mask_Invert("Mask invert", Float) = 0.0
_Decal7_Tiling_Mode("Tiling mode", Range(0,1)) = 0
_Decal7_UV_Select("UV channel", Range(0,7)) = 0
+ _Decal7_Domain_Warping_Enable_Static("Enable domain warping", Float) = 0
+ _Decal7_Domain_Warping_Noise("Domain warping noise", 2D) = "black" {}
+ _Decal7_Domain_Warping_Strength("Domain warping noise strength", Float) = 0.05
+ _Decal7_Domain_Warping_Speed("Domain warping noise speed", Float) = .1
+ _Decal7_Domain_Warping_Octaves("Domain warping octaves", Float) = 5
+ _Decal7_Domain_Warping_Scale("Domain warping scale", Float) = .1
_Decal8_Enable("Enable decal", Float) = 0.0
_Decal8_Color("Base color", Color) = (1, 1, 1, 1)
@@ -290,6 +338,12 @@ Shader "yum_food/tooner"
_Decal8_Mask_Invert("Mask invert", Float) = 0.0
_Decal8_Tiling_Mode("Tiling mode", Range(0,1)) = 0
_Decal8_UV_Select("UV channel", Range(0,7)) = 0
+ _Decal8_Domain_Warping_Enable_Static("Enable domain warping", Float) = 0
+ _Decal8_Domain_Warping_Noise("Domain warping noise", 2D) = "black" {}
+ _Decal8_Domain_Warping_Strength("Domain warping noise strength", Float) = 0.05
+ _Decal8_Domain_Warping_Speed("Domain warping noise speed", Float) = .1
+ _Decal8_Domain_Warping_Octaves("Domain warping octaves", Float) = 5
+ _Decal8_Domain_Warping_Scale("Domain warping scale", Float) = .1
_Decal9_Enable("Enable decal", Float) = 0.0
_Decal9_Color("Base color", Color) = (1, 1, 1, 1)
@@ -308,6 +362,12 @@ Shader "yum_food/tooner"
_Decal9_Mask_Invert("Mask invert", Float) = 0.0
_Decal9_Tiling_Mode("Tiling mode", Range(0,1)) = 0
_Decal9_UV_Select("UV channel", Range(0,7)) = 0
+ _Decal9_Domain_Warping_Enable_Static("Enable domain warping", Float) = 0
+ _Decal9_Domain_Warping_Noise("Domain warping noise", 2D) = "black" {}
+ _Decal9_Domain_Warping_Strength("Domain warping strength", Float) = 0.05
+ _Decal9_Domain_Warping_Speed("Domain warping speed", Float) = .1
+ _Decal9_Domain_Warping_Octaves("Domain warping octaves", Float) = 5
+ _Decal9_Domain_Warping_Scale("Domain warping scale", Float) = .1
[NoScaleOffset] _EmissionMap("Emission map", 2D) = "black" {}
_EmissionColor("Emission color", Color) = (0, 0, 0)
@@ -958,6 +1018,7 @@ Shader "yum_food/tooner"
#include "tooner_lighting.cginc"
ENDCG
}
+ /*
Pass {
Tags {
"RenderType"="Opaque"
@@ -1038,6 +1099,7 @@ Shader "yum_food/tooner"
#include "mochie_shadow_caster.cginc"
ENDCG
}
+ */
}
CustomEditor "ToonerGUI"
}
diff --git a/tooner_lighting.cginc b/tooner_lighting.cginc
index 6c46085..e976132 100644
--- a/tooner_lighting.cginc
+++ b/tooner_lighting.cginc
@@ -975,6 +975,12 @@ struct DecalParams {
float sdf_threshold;
float sdf_softness;
float sdf_px_range;
+ bool domain_warping;
+ texture2D domain_warping_noise;
+ float domain_warping_strength;
+ float domain_warping_speed;
+ float domain_warping_octaves;
+ float domain_warping_scale;
};
void applyDecalImpl(
@@ -997,6 +1003,17 @@ void applyDecalImpl(
}
d0_uv = (p.tiling_mode == 0) ? saturate(d0_uv) : d0_uv;
+ float d0_uv_fwidth = -1;
+ if (p.domain_warping) {
+ p.domain_warping_octaves = min(p.domain_warping_octaves, 10);
+ for (uint ii = 0; ii < p.domain_warping_octaves; ii++) {
+ float2 warping_speed_vector = normalize(float2(97, 101));
+ float2 noise = p.domain_warping_noise.SampleLevel(linear_repeat_s, d0_uv * p.domain_warping_scale + _Time[0] * p.domain_warping_speed * warping_speed_vector, 0);
+ d0_uv += noise * p.domain_warping_strength;
+ }
+ d0_uv_fwidth = length(fwidth(d0_uv));
+ }
+
float4 d0_c = 0;
if (p.base_color_mode == 0) {
d0_c = p.tex.SampleBias(
@@ -1050,22 +1067,28 @@ void applyDecalImpl(
MERGE(d,n,_params).do_roughness = false; \
MERGE(d,n,_params).do_metallic = false; \
MERGE(d,n,_params).mask = 1; \
- MERGE(d,n,_params).color = MERGE(_Decal, n,_Color); \
- MERGE(d,n,_params).tex = MERGE(_Decal, n,_BaseColor); \
- MERGE(d,n,_params).tex_texelsize = MERGE(_Decal, n,_BaseColor_TexelSize); \
- MERGE(d,n,_params).tex_st = MERGE(_Decal, n,_BaseColor_ST); \
- MERGE(d,n,_params).roughness_tex = MERGE(_Decal, n,_Roughness); \
- MERGE(d,n,_params).metallic_tex = MERGE(_Decal, n,_Metallic); \
- MERGE(d,n,_params).emission_strength = MERGE(_Decal, n,_Emission_Strength); \
- MERGE(d,n,_params).angle = MERGE(_Decal, n,_Angle); \
- MERGE(d,n,_params).alpha_multiplier = MERGE(_Decal, n,_Alpha_Multiplier); \
- MERGE(d,n,_params).round_alpha_multiplier = MERGE(_Decal, n,_Round_Alpha_Multiplier); \
- MERGE(d,n,_params).uv_select = MERGE(_Decal, n,_UV_Select); \
- MERGE(d,n,_params).tiling_mode = MERGE(_Decal, n,_Tiling_Mode); \
- MERGE(d,n,_params).base_color_mode = MERGE(_Decal, n,_BaseColor_Mode); \
- MERGE(d,n,_params).sdf_threshold = MERGE(_Decal, n,_SDF_Threshold); \
- MERGE(d,n,_params).sdf_softness = MERGE(_Decal, n,_SDF_Softness); \
- MERGE(d,n,_params).sdf_px_range = MERGE(_Decal, n,_SDF_Px_Range);
+ MERGE(d,n,_params).color = MERGE(_Decal,n,_Color); \
+ MERGE(d,n,_params).tex = MERGE(_Decal,n,_BaseColor); \
+ MERGE(d,n,_params).tex_texelsize = MERGE(_Decal,n,_BaseColor_TexelSize); \
+ MERGE(d,n,_params).tex_st = MERGE(_Decal,n,_BaseColor_ST); \
+ MERGE(d,n,_params).roughness_tex = MERGE(_Decal,n,_Roughness); \
+ MERGE(d,n,_params).metallic_tex = MERGE(_Decal,n,_Metallic); \
+ MERGE(d,n,_params).emission_strength = MERGE(_Decal,n,_Emission_Strength); \
+ MERGE(d,n,_params).angle = MERGE(_Decal,n,_Angle); \
+ MERGE(d,n,_params).alpha_multiplier = MERGE(_Decal,n,_Alpha_Multiplier); \
+ MERGE(d,n,_params).round_alpha_multiplier = MERGE(_Decal,n,_Round_Alpha_Multiplier); \
+ MERGE(d,n,_params).uv_select = MERGE(_Decal,n,_UV_Select); \
+ MERGE(d,n,_params).tiling_mode = MERGE(_Decal,n,_Tiling_Mode); \
+ MERGE(d,n,_params).base_color_mode = MERGE(_Decal,n,_BaseColor_Mode); \
+ MERGE(d,n,_params).sdf_threshold = MERGE(_Decal,n,_SDF_Threshold); \
+ MERGE(d,n,_params).sdf_softness = MERGE(_Decal,n,_SDF_Softness); \
+ MERGE(d,n,_params).sdf_px_range = MERGE(_Decal,n,_SDF_Px_Range); \
+ MERGE(d,n,_params).domain_warping = MERGE(_Decal,n,_Domain_Warping_Enable_Static); \
+ MERGE(d,n,_params).domain_warping_noise = MERGE(_Decal,n,_Domain_Warping_Noise); \
+ MERGE(d,n,_params).domain_warping_strength = MERGE(_Decal,n,_Domain_Warping_Strength); \
+ MERGE(d,n,_params).domain_warping_speed = MERGE(_Decal,n,_Domain_Warping_Speed); \
+ MERGE(d,n,_params).domain_warping_octaves = MERGE(_Decal,n,_Domain_Warping_Octaves); \
+ MERGE(d,n,_params).domain_warping_scale = MERGE(_Decal,n,_Domain_Warping_Scale);
#define SETUP_DECAL_BASE(n) \
DecalParams MERGE(d,n,_params); \
@@ -1078,9 +1101,9 @@ void applyDecalImpl(
MERGE(d,n,_params).do_metallic = true;
#define SETUP_DECAL_MASK(n) \
- MERGE(d,n,_params).mask = MERGE(_Decal, n,_Mask).SampleLevel(linear_repeat_s, \
- get_uv_by_channel(i, MERGE(_Decal, n,_UV_Select)), 0); \
- MERGE(d,n,_params).mask = MERGE(_Decal, n,_Mask_Invert) ? 1.0 - MERGE(d,n,_params).mask : MERGE(d,n,_params).mask;
+ MERGE(d,n,_params).mask = MERGE(_Decal,n,_Mask).SampleLevel(linear_repeat_s, \
+ get_uv_by_channel(i, MERGE(_Decal,n,_UV_Select)), 0); \
+ MERGE(d,n,_params).mask = MERGE(_Decal,n,_Mask_Invert) ? 1.0 - MERGE(d,n,_params).mask : MERGE(d,n,_params).mask;
#define SETUP_DECAL_FINISH(n) \
applyDecalImpl(albedo, decal_emission, roughness, metallic, i, MERGE(d,n,_params));