summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2025-05-26 17:30:05 -0700
committeryum <yum.food.vr@gmail.com>2025-05-26 17:30:05 -0700
commited7bb9bbfad50edb88d16005618f2487434d61c4 (patch)
tree136f126d5e148c39f2e90dc520e6c5b7bfa81140
parent5c54a56dd2416aaf82d7f5d56063c0a306574d19 (diff)
Add vrc light volumes, double decal slots
Light volumes: https://github.com/REDSIM/VRCLightVolumes
-rw-r--r--2ner.cginc3
-rw-r--r--2ner.shader254
-rw-r--r--LightVolumes.cginc503
-rw-r--r--decals.cginc193
-rw-r--r--features.cginc44
-rw-r--r--globals.cginc15
-rw-r--r--unigram_letter_grid.cginc75
-rw-r--r--yum_lighting.cginc35
8 files changed, 1052 insertions, 70 deletions
diff --git a/2ner.cginc b/2ner.cginc
index f37a45e..bac9ee6 100644
--- a/2ner.cginc
+++ b/2ner.cginc
@@ -280,6 +280,9 @@ float4 frag(v2f i, uint facing : SV_IsFrontFace
float4 lit = YumBRDF(i, l, pbr);
+ lit.rgb += LightVolumeSpecular(pbr.albedo, pbr.smoothness, pbr.metallic,
+ pbr.normal, l.view_dir, l.L00, l.L01r, l.L01g, l.L01b);
+
#if defined(_HARNACK_TRACING)
pbr.albedo = harnack_output.color;
pbr.smoothness = 0;
diff --git a/2ner.shader b/2ner.shader
index b6b435e..bb45042 100644
--- a/2ner.shader
+++ b/2ner.shader
@@ -297,7 +297,7 @@ Shader "yum_food/2ner"
_Decal0_MainTex("Base color", 2D) = "white" {}
_Decal0_Opacity("Opacity", Range(0, 1)) = 1.0
_Decal0_Angle("Angle", Range(0, 1)) = 0.0
- _Decal0_UV_Channel("UV channel", Range(0, 3)) = 0
+ _Decal0_UV_Channel("UV channel", Range(0, 3.1)) = 0
[ThryToggle(_DECAL0_TILING_MODE)] _Decal0_Tiling_Mode("Tiling mode", Float) = 0
[ThryToggle(_DECAL0_REPLACE_ALPHA)] _Decal0_Replace_Alpha_Mode("Replace alpha", Float) = 0
//ifex _Decal0_Normal_Enabled==0
@@ -358,7 +358,7 @@ Shader "yum_food/2ner"
_Decal1_MainTex("Base color", 2D) = "white" {}
_Decal1_Opacity("Opacity", Range(0, 1)) = 1.0
_Decal1_Angle("Angle", Range(0, 1)) = 0.0
- _Decal1_UV_Channel("UV channel", Range(0, 3)) = 0
+ _Decal1_UV_Channel("UV channel", Range(0, 3.1)) = 0
[ThryToggle(_DECAL1_TILING_MODE)] _Decal1_Tiling_Mode("Tiling mode", Float) = 0
[ThryToggle(_DECAL1_REPLACE_ALPHA)] _Decal1_Replace_Alpha_Mode("Replace alpha", Float) = 0
//ifex _Decal1_Normal_Enabled==0
@@ -419,7 +419,7 @@ Shader "yum_food/2ner"
_Decal2_MainTex("Base color", 2D) = "white" {}
_Decal2_Opacity("Opacity", Range(0, 1)) = 1.0
_Decal2_Angle("Angle", Range(0, 1)) = 0.0
- _Decal2_UV_Channel("UV channel", Range(0, 3)) = 0
+ _Decal2_UV_Channel("UV channel", Range(0, 3.1)) = 0
[ThryToggle(_DECAL2_TILING_MODE)] _Decal2_Tiling_Mode("Tiling mode", Float) = 0
[ThryToggle(_DECAL2_REPLACE_ALPHA)] _Decal2_Replace_Alpha_Mode("Replace alpha", Float) = 0
//ifex _Decal2_Normal_Enabled==0
@@ -480,7 +480,7 @@ Shader "yum_food/2ner"
_Decal3_MainTex("Base color", 2D) = "white" {}
_Decal3_Opacity("Opacity", Range(0, 1)) = 1.0
_Decal3_Angle("Angle", Range(0, 1)) = 0.0
- _Decal3_UV_Channel("UV channel", Range(0, 3)) = 0
+ _Decal3_UV_Channel("UV channel", Range(0, 3.1)) = 0
[ThryToggle(_DECAL3_TILING_MODE)] _Decal3_Tiling_Mode("Tiling mode", Float) = 0
[ThryToggle(_DECAL3_REPLACE_ALPHA)] _Decal3_Replace_Alpha_Mode("Replace alpha", Float) = 0
//ifex _Decal3_Normal_Enabled==0
@@ -534,6 +534,250 @@ Shader "yum_food/2ner"
//endex
[HideInInspector] m_end_Decal3("Decal 3", Float) = 0
//endex
+ //ifex _Decal4_Enabled==0
+ [HideInInspector] m_start_Decal4("Decal 4", Float) = 0
+ [ThryToggle(_DECAL4)] _Decal4_Enabled("Enable", Float) = 0
+ _Decal4_Color("Tint", Color) = (1, 1, 1, 1)
+ _Decal4_MainTex("Base color", 2D) = "white" {}
+ _Decal4_Opacity("Opacity", Range(0, 1)) = 1.0
+ _Decal4_Angle("Angle", Range(0, 1)) = 0.0
+ _Decal4_UV_Channel("UV channel", Range(0, 3.1)) = 0
+ [ThryToggle(_DECAL4_TILING_MODE)] _Decal4_Tiling_Mode("Tiling mode", Float) = 0
+ [ThryToggle(_DECAL4_REPLACE_ALPHA)] _Decal4_Replace_Alpha_Mode("Replace alpha", Float) = 0
+ //ifex _Decal4_Normal_Enabled==0
+ [HideInInspector] m_start_Decal4_Normal("Normal", Float) = 0
+ [ThryToggle(_DECAL4_NORMAL)] _Decal4_Normal_Enabled("Enable", Float) = 0
+ [Normal]_Decal4_Normal("Normal", 2D) = "bump" {}
+ _Decal4_Normal_Scale("Normal scale", Float) = 1.0
+ [HideInInspector] m_end_Decal4_Normal("Normal", Float) = 0
+ //endex
+ //ifex _Decal4_Reflections_Enabled==0
+ [HideInInspector] m_start_Decal4_Reflections("Reflections", Float) = 0
+ [ThryToggle(_DECAL4_REFLECTIONS)] _Decal4_Reflections_Enabled("Enable", Float) = 0
+ _Decal4_MetallicGlossMap("Metallic gloss map", 2D) = "white" {}
+ _Decal4_Smoothness("Smoothness", Range(0, 1)) = 0.5
+ _Decal4_Metallic("Metallic", Range(0, 1)) = 0.0
+ [HideInInspector] m_end_Decal4_Reflections("Reflections", Float) = 0
+ //endex
+ //ifex _Decal4_Domain_Warping_Enabled==0
+ [HideInInspector] m_start_Decal4_Domain_Warping("Domain warping", Float) = 0
+ [ThryToggle(_DECAL4_DOMAIN_WARPING)] _Decal4_Domain_Warping_Enabled("Enable", Float) = 0
+ _Decal4_Domain_Warping_Noise("Noise", 2D) = "black" {}
+ _Decal4_Domain_Warping_Octaves("Octaves", Float) = 1
+ _Decal4_Domain_Warping_Strength("Strength", Float) = 0.1
+ _Decal4_Domain_Warping_Scale("Scale", Float) = 0.1
+ _Decal4_Domain_Warping_Speed("Speed", Float) = 1.0
+ [HideInInspector] m_end_Decal4_Domain_Warping("Domain warping", Float) = 0
+ //endex
+ //ifex _Decal4_SDF_Enabled==0
+ [HideInInspector] m_start_Decal4_SDF("SDF mode", Float) = 0
+ [ThryToggle(_DECAL4_SDF)] _Decal4_SDF_Enabled("Enable", Float) = 0
+ _Decal4_SDF_Threshold("SDF threshold", Range(0, 1)) = 0.5
+ [MaterialToggle] _Decal4_SDF_Invert("SDF invert", Float) = 0
+ _Decal4_SDF_Softness("SDF softness", Range(0, 1)) = 0.01
+ _Decal4_SDF_Px_Range("SDF px range", Float) = 2
+ //ifex _Decal4_CMYK_Warping_Planes_Enabled==0
+ [HideInInspector] m_start_Decal4_CMYK_Warping_Planes("CMYK warping planes", Float) = 0
+ [ThryToggle(_DECAL4_CMYK_WARPING_PLANES)] _Decal4_CMYK_Warping_Planes_Enabled("Enable", Float) = 0
+ _Decal4_CMYK_Warping_Planes_Noise("Noise", 2D) = "black" {}
+ _Decal4_CMYK_Warping_Planes_Strength("Strength", Float) = 0.1
+ _Decal4_CMYK_Warping_Planes_Scale("Scale", Float) = 0.1
+ _Decal4_CMYK_Warping_Planes_Speed("Speed", Float) = 1.0
+ [HideInInspector] m_end_Decal4_CMYK_Warping_Planes("CMYK warping planes", Float) = 0
+ [HideInInspector] m_end_Decal4_SDF("SDF", Float) = 0
+ //endex
+ //endex
+ //ifex _Decal4_Mask_Enabled==0
+ [HideInInspector] m_start_Decal4_Mask("Mask", Float) = 0
+ [ThryToggle(_DECAL4_MASK)] _Decal4_Mask_Enabled("Enable", Float) = 0
+ _Decal4_Mask("Mask", 2D) = "white" {}
+ [HideInInspector] m_end_Decal4_Mask("Mask", Float) = 0
+ //endex
+ [HideInInspector] m_end_Decal4("Decal 4", Float) = 0
+ //endex
+ //ifex _Decal5_Enabled==0
+ [HideInInspector] m_start_Decal5("Decal 5", Float) = 0
+ [ThryToggle(_DECAL5)] _Decal5_Enabled("Enable", Float) = 0
+ _Decal5_Color("Tint", Color) = (1, 1, 1, 1)
+ _Decal5_MainTex("Base color", 2D) = "white" {}
+ _Decal5_Opacity("Opacity", Range(0, 1)) = 1.0
+ _Decal5_Angle("Angle", Range(0, 1)) = 0.0
+ _Decal5_UV_Channel("UV channel", Range(0, 3.1)) = 0
+ [ThryToggle(_DECAL5_TILING_MODE)] _Decal5_Tiling_Mode("Tiling mode", Float) = 0
+ [ThryToggle(_DECAL5_REPLACE_ALPHA)] _Decal5_Replace_Alpha_Mode("Replace alpha", Float) = 0
+ //ifex _Decal5_Normal_Enabled==0
+ [HideInInspector] m_start_Decal5_Normal("Normal", Float) = 0
+ [ThryToggle(_DECAL5_NORMAL)] _Decal5_Normal_Enabled("Enable", Float) = 0
+ [Normal]_Decal5_Normal("Normal", 2D) = "bump" {}
+ _Decal5_Normal_Scale("Normal scale", Float) = 1.0
+ [HideInInspector] m_end_Decal5_Normal("Normal", Float) = 0
+ //endex
+ //ifex _Decal5_Reflections_Enabled==0
+ [HideInInspector] m_start_Decal5_Reflections("Reflections", Float) = 0
+ [ThryToggle(_DECAL5_REFLECTIONS)] _Decal5_Reflections_Enabled("Enable", Float) = 0
+ _Decal5_MetallicGlossMap("Metallic gloss map", 2D) = "white" {}
+ _Decal5_Smoothness("Smoothness", Range(0, 1)) = 0.5
+ _Decal5_Metallic("Metallic", Range(0, 1)) = 0.0
+ [HideInInspector] m_end_Decal5_Reflections("Reflections", Float) = 0
+ //endex
+ //ifex _Decal5_Domain_Warping_Enabled==0
+ [HideInInspector] m_start_Decal5_Domain_Warping("Domain warping", Float) = 0
+ [ThryToggle(_DECAL5_DOMAIN_WARPING)] _Decal5_Domain_Warping_Enabled("Enable", Float) = 0
+ _Decal5_Domain_Warping_Noise("Noise", 2D) = "black" {}
+ _Decal5_Domain_Warping_Octaves("Octaves", Float) = 1
+ _Decal5_Domain_Warping_Strength("Strength", Float) = 0.1
+ _Decal5_Domain_Warping_Scale("Scale", Float) = 0.1
+ _Decal5_Domain_Warping_Speed("Speed", Float) = 1.0
+ [HideInInspector] m_end_Decal5_Domain_Warping("Domain warping", Float) = 0
+ //endex
+ //ifex _Decal5_SDF_Enabled==0
+ [HideInInspector] m_start_Decal5_SDF("SDF mode", Float) = 0
+ [ThryToggle(_DECAL5_SDF)] _Decal5_SDF_Enabled("Enable", Float) = 0
+ _Decal5_SDF_Threshold("SDF threshold", Range(0, 1)) = 0.5
+ [MaterialToggle] _Decal5_SDF_Invert("SDF invert", Float) = 0
+ _Decal5_SDF_Softness("SDF softness", Range(0, 1)) = 0.01
+ _Decal5_SDF_Px_Range("SDF px range", Float) = 2
+ //ifex _Decal5_CMYK_Warping_Planes_Enabled==0
+ [HideInInspector] m_start_Decal5_CMYK_Warping_Planes("CMYK warping planes", Float) = 0
+ [ThryToggle(_DECAL5_CMYK_WARPING_PLANES)] _Decal5_CMYK_Warping_Planes_Enabled("Enable", Float) = 0
+ _Decal5_CMYK_Warping_Planes_Noise("Noise", 2D) = "black" {}
+ _Decal5_CMYK_Warping_Planes_Strength("Strength", Float) = 0.1
+ _Decal5_CMYK_Warping_Planes_Scale("Scale", Float) = 0.1
+ _Decal5_CMYK_Warping_Planes_Speed("Speed", Float) = 1.0
+ [HideInInspector] m_end_Decal5_CMYK_Warping_Planes("CMYK warping planes", Float) = 0
+ [HideInInspector] m_end_Decal5_SDF("SDF", Float) = 0
+ //endex
+ //endex
+ //ifex _Decal6_Mask_Enabled==0
+ [HideInInspector] m_start_Decal6_Mask("Mask", Float) = 0
+ [ThryToggle(_DECAL6_MASK)] _Decal6_Mask_Enabled("Enable", Float) = 0
+ _Decal6_Mask("Mask", 2D) = "white" {}
+ [HideInInspector] m_end_Decal6_Mask("Mask", Float) = 0
+ //endex
+ [HideInInspector] m_end_Decal6("Decal 5", Float) = 0
+ //endex
+ //ifex _Decal6_Enabled==0
+ [HideInInspector] m_start_Decal6("Decal 6", Float) = 0
+ [ThryToggle(_DECAL6)] _Decal6_Enabled("Enable", Float) = 0
+ _Decal6_Color("Tint", Color) = (1, 1, 1, 1)
+ _Decal6_MainTex("Base color", 2D) = "white" {}
+ _Decal6_Opacity("Opacity", Range(0, 1)) = 1.0
+ _Decal6_Angle("Angle", Range(0, 1)) = 0.0
+ _Decal6_UV_Channel("UV channel", Range(0, 3.1)) = 0
+ [ThryToggle(_DECAL6_TILING_MODE)] _Decal6_Tiling_Mode("Tiling mode", Float) = 0
+ [ThryToggle(_DECAL6_REPLACE_ALPHA)] _Decal6_Replace_Alpha_Mode("Replace alpha", Float) = 0
+ //ifex _Decal6_Normal_Enabled==0
+ [HideInInspector] m_start_Decal6_Normal("Normal", Float) = 0
+ [ThryToggle(_DECAL6_NORMAL)] _Decal6_Normal_Enabled("Enable", Float) = 0
+ [Normal]_Decal6_Normal("Normal", 2D) = "bump" {}
+ _Decal6_Normal_Scale("Normal scale", Float) = 1.0
+ [HideInInspector] m_end_Decal6_Normal("Normal", Float) = 0
+ //endex
+ //ifex _Decal6_Reflections_Enabled==0
+ [HideInInspector] m_start_Decal6_Reflections("Reflections", Float) = 0
+ [ThryToggle(_DECAL6_REFLECTIONS)] _Decal6_Reflections_Enabled("Enable", Float) = 0
+ _Decal6_MetallicGlossMap("Metallic gloss map", 2D) = "white" {}
+ _Decal6_Smoothness("Smoothness", Range(0, 1)) = 0.5
+ _Decal6_Metallic("Metallic", Range(0, 1)) = 0.0
+ [HideInInspector] m_end_Decal6_Reflections("Reflections", Float) = 0
+ //endex
+ //ifex _Decal6_Domain_Warping_Enabled==0
+ [HideInInspector] m_start_Decal6_Domain_Warping("Domain warping", Float) = 0
+ [ThryToggle(_DECAL6_DOMAIN_WARPING)] _Decal6_Domain_Warping_Enabled("Enable", Float) = 0
+ _Decal6_Domain_Warping_Noise("Noise", 2D) = "black" {}
+ _Decal6_Domain_Warping_Octaves("Octaves", Float) = 1
+ _Decal6_Domain_Warping_Strength("Strength", Float) = 0.1
+ _Decal6_Domain_Warping_Scale("Scale", Float) = 0.1
+ _Decal6_Domain_Warping_Speed("Speed", Float) = 1.0
+ [HideInInspector] m_end_Decal6_Domain_Warping("Domain warping", Float) = 0
+ //endex
+ //ifex _Decal6_SDF_Enabled==0
+ [HideInInspector] m_start_Decal6_SDF("SDF mode", Float) = 0
+ [ThryToggle(_DECAL6_SDF)] _Decal6_SDF_Enabled("Enable", Float) = 0
+ _Decal6_SDF_Threshold("SDF threshold", Range(0, 1)) = 0.5
+ [MaterialToggle] _Decal6_SDF_Invert("SDF invert", Float) = 0
+ _Decal6_SDF_Softness("SDF softness", Range(0, 1)) = 0.01
+ _Decal6_SDF_Px_Range("SDF px range", Float) = 2
+ //ifex _Decal6_CMYK_Warping_Planes_Enabled==0
+ [HideInInspector] m_start_Decal6_CMYK_Warping_Planes("CMYK warping planes", Float) = 0
+ [ThryToggle(_DECAL6_CMYK_WARPING_PLANES)] _Decal6_CMYK_Warping_Planes_Enabled("Enable", Float) = 0
+ _Decal6_CMYK_Warping_Planes_Noise("Noise", 2D) = "black" {}
+ _Decal6_CMYK_Warping_Planes_Strength("Strength", Float) = 0.1
+ _Decal6_CMYK_Warping_Planes_Scale("Scale", Float) = 0.1
+ _Decal6_CMYK_Warping_Planes_Speed("Speed", Float) = 1.0
+ [HideInInspector] m_end_Decal6_CMYK_Warping_Planes("CMYK warping planes", Float) = 0
+ [HideInInspector] m_end_Decal6_SDF("SDF", Float) = 0
+ //endex
+ //endex
+ //ifex _Decal6_Mask_Enabled==0
+ [HideInInspector] m_start_Decal6_Mask("Mask", Float) = 0
+ [ThryToggle(_DECAL6_MASK)] _Decal6_Mask_Enabled("Enable", Float) = 0
+ _Decal6_Mask("Mask", 2D) = "white" {}
+ [HideInInspector] m_end_Decal6_Mask("Mask", Float) = 0
+ //endex
+ [HideInInspector] m_end_Decal6("Decal 6", Float) = 0
+ //endex
+ //ifex _Decal7_Enabled==0
+ [HideInInspector] m_start_Decal7("Decal 7", Float) = 0
+ [ThryToggle(_DECAL7)] _Decal7_Enabled("Enable", Float) = 0
+ _Decal7_Color("Tint", Color) = (1, 1, 1, 1)
+ _Decal7_MainTex("Base color", 2D) = "white" {}
+ _Decal7_Opacity("Opacity", Range(0, 1)) = 1.0
+ _Decal7_Angle("Angle", Range(0, 1)) = 0.0
+ _Decal7_UV_Channel("UV channel", Range(0, 3.1)) = 0
+ [ThryToggle(_DECAL7_TILING_MODE)] _Decal7_Tiling_Mode("Tiling mode", Float) = 0
+ [ThryToggle(_DECAL7_REPLACE_ALPHA)] _Decal7_Replace_Alpha_Mode("Replace alpha", Float) = 0
+ //ifex _Decal7_Normal_Enabled==0
+ [HideInInspector] m_start_Decal7_Normal("Normal", Float) = 0
+ [ThryToggle(_DECAL7_NORMAL)] _Decal7_Normal_Enabled("Enable", Float) = 0
+ [Normal]_Decal7_Normal("Normal", 2D) = "bump" {}
+ _Decal7_Normal_Scale("Normal scale", Float) = 1.0
+ [HideInInspector] m_end_Decal7_Normal("Normal", Float) = 0
+ //endex
+ //ifex _Decal7_Reflections_Enabled==0
+ [HideInInspector] m_start_Decal7_Reflections("Reflections", Float) = 0
+ [ThryToggle(_DECAL7_REFLECTIONS)] _Decal7_Reflections_Enabled("Enable", Float) = 0
+ _Decal7_MetallicGlossMap("Metallic gloss map", 2D) = "white" {}
+ _Decal7_Smoothness("Smoothness", Range(0, 1)) = 0.5
+ _Decal7_Metallic("Metallic", Range(0, 1)) = 0.0
+ [HideInInspector] m_end_Decal7_Reflections("Reflections", Float) = 0
+ //endex
+ //ifex _Decal7_Domain_Warping_Enabled==0
+ [HideInInspector] m_start_Decal7_Domain_Warping("Domain warping", Float) = 0
+ [ThryToggle(_DECAL7_DOMAIN_WARPING)] _Decal7_Domain_Warping_Enabled("Enable", Float) = 0
+ _Decal7_Domain_Warping_Noise("Noise", 2D) = "black" {}
+ _Decal7_Domain_Warping_Octaves("Octaves", Float) = 1
+ _Decal7_Domain_Warping_Strength("Strength", Float) = 0.1
+ _Decal7_Domain_Warping_Scale("Scale", Float) = 0.1
+ _Decal7_Domain_Warping_Speed("Speed", Float) = 1.0
+ [HideInInspector] m_end_Decal7_Domain_Warping("Domain warping", Float) = 0
+ //endex
+ //ifex _Decal7_SDF_Enabled==0
+ [HideInInspector] m_start_Decal7_SDF("SDF mode", Float) = 0
+ [ThryToggle(_DECAL7_SDF)] _Decal7_SDF_Enabled("Enable", Float) = 0
+ _Decal7_SDF_Threshold("SDF threshold", Range(0, 1)) = 0.5
+ [MaterialToggle] _Decal7_SDF_Invert("SDF invert", Float) = 0
+ _Decal7_SDF_Softness("SDF softness", Range(0, 1)) = 0.01
+ _Decal7_SDF_Px_Range("SDF px range", Float) = 2
+ //ifex _Decal7_CMYK_Warping_Planes_Enabled==0
+ [HideInInspector] m_start_Decal7_CMYK_Warping_Planes("CMYK warping planes", Float) = 0
+ [ThryToggle(_DECAL7_CMYK_WARPING_PLANES)] _Decal7_CMYK_Warping_Planes_Enabled("Enable", Float) = 0
+ _Decal7_CMYK_Warping_Planes_Noise("Noise", 2D) = "black" {}
+ _Decal7_CMYK_Warping_Planes_Strength("Strength", Float) = 0.1
+ _Decal7_CMYK_Warping_Planes_Scale("Scale", Float) = 0.1
+ _Decal7_CMYK_Warping_Planes_Speed("Speed", Float) = 1.0
+ [HideInInspector] m_end_Decal7_CMYK_Warping_Planes("CMYK warping planes", Float) = 0
+ [HideInInspector] m_end_Decal7_SDF("SDF", Float) = 0
+ //endex
+ //endex
+ //ifex _Decal7_Mask_Enabled==0
+ [HideInInspector] m_start_Decal7_Mask("Mask", Float) = 0
+ [ThryToggle(_DECAL7_MASK)] _Decal7_Mask_Enabled("Enable", Float) = 0
+ _Decal7_Mask("Mask", 2D) = "white" {}
+ [HideInInspector] m_end_Decal7_Mask("Mask", Float) = 0
+ //endex
+ [HideInInspector] m_end_Decal7("Decal 7", Float) = 0
+ //endex
[HideInInspector] m_end_Decals("Decals", Float) = 0
//ifex _3D_SDF_Enabled==0
@@ -541,7 +785,7 @@ Shader "yum_food/2ner"
[ThryToggle(_3D_SDF)] _3D_SDF_Enabled("Enable", Float) = 0
_3D_SDF_Texture("Texture", 3D) = "white" {}
_3D_SDF_ST("Scale and offset", Vector) = (1, 1, 0, 0)
- _3D_SDF_UV_Channel("UV channel", Range(0, 3)) = 0
+ _3D_SDF_UV_Channel("UV channel", Range(0, 3.1)) = 0
_3D_SDF_Thresholds("Thresholds", Vector) = (0.2, 0.4, 0.6, 0.8)
_3D_SDF_Color_0("Color 0", Color) = (1, 0, 0, 1)
_3D_SDF_Color_1("Color 1", Color) = (0, 1, 0, 1)
diff --git a/LightVolumes.cginc b/LightVolumes.cginc
new file mode 100644
index 0000000..d10a190
--- /dev/null
+++ b/LightVolumes.cginc
@@ -0,0 +1,503 @@
+/*
+MIT License
+
+Copyright (c) 2025 RED_SIM
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#ifndef VRC_LIGHT_VOLUMES_INCLUDED
+#define VRC_LIGHT_VOLUMES_INCLUDED
+
+// Are Light Volumes enabled on scene?
+uniform float _UdonLightVolumeEnabled;
+
+// All volumes count in scene
+uniform float _UdonLightVolumeCount;
+
+// Additive volumes max overdraw count
+uniform float _UdonLightVolumeAdditiveMaxOverdraw;
+
+// Additive volumes count
+uniform float _UdonLightVolumeAdditiveCount;
+
+// Should volumes be blended with lightprobes?
+uniform float _UdonLightVolumeProbesBlend;
+
+// Should volumes be with sharp edges when not blending with each other
+uniform float _UdonLightVolumeSharpBounds;
+
+// Main 3D Texture atlas
+uniform sampler3D _UdonLightVolume;
+
+// World to Local (-0.5, 0.5) UVW Matrix
+uniform float4x4 _UdonLightVolumeInvWorldMatrix[32];
+
+// L1 SH components rotation (relative to baked rotation)
+uniform float3 _UdonLightVolumeRotation[64];
+
+// Value that is needed to smoothly blend volumes ( BoundsScale / edgeSmooth )
+uniform float3 _UdonLightVolumeInvLocalEdgeSmooth[32];
+
+// AABB Bounds of islands on the 3D Texture atlas
+uniform float3 _UdonLightVolumeUvw[192];
+
+// Color multiplier (RGB) | If we actually need to rotate L1 components at all (A)
+uniform float4 _UdonLightVolumeColor[32];
+
+// Rotates vector by Matrix 2x3
+float3 LV_MultiplyVectorByMatrix2x3(float3 v, float3 r0, float3 r1) {
+ float3 r2 = cross(r0, r1);
+ return float3(dot(v, r0), dot(v, r1), dot(v, r2));
+}
+
+// Checks if local UVW point is in bounds from -0.5 to +0.5
+bool LV_PointLocalAABB(float3 localUVW){
+ return all(abs(localUVW) <= 0.5);
+}
+
+// Calculates local UVW using volume ID
+float3 LV_LocalFromVolume(uint volumeID, float3 worldPos) {
+ return mul(_UdonLightVolumeInvWorldMatrix[volumeID], float4(worldPos, 1.0)).xyz;
+}
+
+// Samples 3 SH textures and packing them into L1 channels
+void LV_SampleLightVolumeTex(float3 uvw0, float3 uvw1, float3 uvw2, out float3 L0, out float3 L1r, out float3 L1g, out float3 L1b) {
+ // Sampling 3D Atlas
+ float4 tex0 = tex3Dlod(_UdonLightVolume, float4(uvw0, 0));
+ float4 tex1 = tex3Dlod(_UdonLightVolume, float4(uvw1, 0));
+ float4 tex2 = tex3Dlod(_UdonLightVolume, float4(uvw2, 0));
+ // Packing final data
+ L0 = tex0.rgb;
+ L1r = float3(tex1.r, tex2.r, tex0.a);
+ L1g = float3(tex1.g, tex2.g, tex1.a);
+ L1b = float3(tex1.b, tex2.b, tex2.a);
+}
+
+// Bounds mask for a volume rotated in world space, using local UVW
+float LV_BoundsMask(float3 localUVW, float3 invLocalEdgeSmooth) {
+ float3 distToMin = (localUVW + 0.5) * invLocalEdgeSmooth;
+ float3 distToMax = (0.5 - localUVW) * invLocalEdgeSmooth;
+ float3 fade = saturate(min(distToMin, distToMax));
+ return fade.x * fade.y * fade.z;
+}
+
+// Default light probes SH components
+void LV_SampleLightProbe(out float3 L0, out float3 L1r, out float3 L1g, out float3 L1b) {
+ L0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
+ L1r = unity_SHAr.xyz;
+ L1g = unity_SHAg.xyz;
+ L1b = unity_SHAb.xyz;
+}
+
+// Default light probes L0 only
+float3 LV_SampleLightProbe_L0() {
+ return float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
+}
+
+// Linear single SH L1 channel evaluation
+float LV_EvaluateSH(float L0, float3 L1, float3 n) {
+ return L0 + dot(L1, n);
+}
+
+// Samples a Volume with ID and Local UVW
+void LV_SampleVolume(uint id, float3 localUVW, out float3 L0, out float3 L1r, out float3 L1g, out float3 L1b) {
+
+ // Additive UVW
+ uint uvwID = id * 6;
+ float3 uvwMin0 = _UdonLightVolumeUvw[uvwID].xyz;
+ float3 uvwScaled = saturate(localUVW + 0.5) * (_UdonLightVolumeUvw[uvwID + 1].xyz - uvwMin0);
+ float3 uvw0 = uvwMin0 + uvwScaled;
+ float3 uvw1 = _UdonLightVolumeUvw[uvwID + 2].xyz + uvwScaled;
+ float3 uvw2 = _UdonLightVolumeUvw[uvwID + 4].xyz + uvwScaled;
+
+ // Sample additive
+ LV_SampleLightVolumeTex(uvw0, uvw1, uvw2, L0, L1r, L1g, L1b);
+
+ // Color correction
+ float4 color = _UdonLightVolumeColor[id];
+ L0 = L0 * color.rgb;
+ L1r = L1r * color.r;
+ L1g = L1g * color.g;
+ L1b = L1b * color.b;
+
+ // Rotate if needed
+ if (color.a != 0) {
+ int id2 = id * 2;
+ float3 r0 = _UdonLightVolumeRotation[id2];
+ float3 r1 = _UdonLightVolumeRotation[id2 + 1];
+ L1r = LV_MultiplyVectorByMatrix2x3(L1r, r0, r1);
+ L1g = LV_MultiplyVectorByMatrix2x3(L1g, r0, r1);
+ L1b = LV_MultiplyVectorByMatrix2x3(L1b, r0, r1);
+ }
+
+}
+
+// Samples a Volume with ID and Local UVW, but L0 component only
+float3 LV_SampleVolume_L0(uint id, float3 localUVW) {
+ uint uvwID = id * 6;
+ float3 uvwMin0 = _UdonLightVolumeUvw[uvwID].xyz;
+ float3 uvw0 = saturate(localUVW + 0.5) * (_UdonLightVolumeUvw[uvwID + 1].xyz - uvwMin0) + uvwMin0;
+ return tex3Dlod(_UdonLightVolume, float4(uvw0, 0)).rgb * _UdonLightVolumeColor[id].rgb;
+}
+
+// Forms specular based on roughness
+float LV_DistributionGGX(float NoH, float roughness) {
+ float f = (roughness - 1) * ((roughness + 1) * (NoH * NoH)) + 1;
+ return (roughness * roughness) / ((float) 3.141592653589793f * f * f);
+}
+
+// Faster normalize
+float3 LV_Normalize(float3 v) {
+ return rsqrt(dot(v, v)) * v;
+}
+
+// Calculates speculars for light volumes or any SH L1 data
+float3 LightVolumeSpecular(float3 f0, float smoothness, float3 worldNormal, float3 viewDir, float3 L0, float3 L1r, float3 L1g, float3 L1b) {
+
+ float3 specColor = max(float3(dot(reflect(-L1r, worldNormal), viewDir), dot(reflect(-L1g, worldNormal), viewDir), dot(reflect(-L1b, worldNormal), viewDir)), 0);
+
+ float3 rDir = LV_Normalize(LV_Normalize(L1r) + viewDir);
+ float3 gDir = LV_Normalize(LV_Normalize(L1g) + viewDir);
+ float3 bDir = LV_Normalize(LV_Normalize(L1b) + viewDir);
+
+ float rNh = saturate(dot(worldNormal, rDir));
+ float gNh = saturate(dot(worldNormal, gDir));
+ float bNh = saturate(dot(worldNormal, bDir));
+
+ float roughness = 1 - smoothness;
+ float roughExp = roughness * roughness;
+
+ float rSpec = LV_DistributionGGX(rNh, roughExp);
+ float gSpec = LV_DistributionGGX(gNh, roughExp);
+ float bSpec = LV_DistributionGGX(bNh, roughExp);
+
+ float3 specs = (rSpec + gSpec + bSpec) * f0;
+ float3 coloredSpecs = specs * specColor;
+
+ float3 a = coloredSpecs + specs * L0;
+ float3 b = coloredSpecs * 4;
+
+ return max(lerp(a, b, smoothness), 0.0);
+
+}
+
+float3 LightVolumeSpecular(float3 albedo, float smoothness, float metallic, float3 worldNormal, float3 viewDir, float3 L0, float3 L1r, float3 L1g, float3 L1b) {
+
+ float3 specularf0 = lerp(0.04f, albedo, metallic);
+ return LightVolumeSpecular(specularf0, smoothness, worldNormal, viewDir, L0, L1r, L1g, L1b);
+}
+
+// Calculates speculars for light volumes or any SH L1 data, but simplified, with only one dominant direction
+float3 LightVolumeSpecularDominant(float3 f0, float smoothness, float3 worldNormal, float3 viewDir, float3 L0, float3 L1r, float3 L1g, float3 L1b) {
+
+ float3 dominantDir = L1r + L1g + L1b;
+ float3 dir = LV_Normalize(LV_Normalize(dominantDir) + viewDir);
+ float nh = saturate(dot(worldNormal, dir));
+
+ float roughness = 1 - smoothness;
+ float roughExp = roughness * roughness;
+
+ float spec = LV_DistributionGGX(nh, roughExp);
+
+ return max(spec * L0 * f0, 0.0) * 2;
+
+}
+
+float3 LightVolumeSpecularDominant(float3 albedo, float smoothness, float metallic, float3 worldNormal, float3 viewDir, float3 L0, float3 L1r, float3 L1g, float3 L1b) {
+
+ float3 specularf0 = lerp(0.04f, albedo, metallic);
+ return LightVolumeSpecularDominant(specularf0, smoothness, worldNormal, viewDir, L0, L1r, L1g, L1b);
+}
+
+// Calculate Light Volume Color based on all SH components provided and the world normal
+float3 LightVolumeEvaluate(float3 worldNormal, float3 L0, float3 L1r, float3 L1g, float3 L1b) {
+ return float3(LV_EvaluateSH(L0.r, L1r, worldNormal), LV_EvaluateSH(L0.g, L1g, worldNormal), LV_EvaluateSH(L0.b, L1b, worldNormal));
+}
+
+// Calculates SH components based on the world position
+void LightVolumeSH(float3 worldPos, out float3 L0, out float3 L1r, out float3 L1g, out float3 L1b) {
+
+ // Initializing output variables
+ L0 = float3(0, 0, 0);
+ L1r = float3(0, 0, 0);
+ L1g = float3(0, 0, 0);
+ L1b = float3(0, 0, 0);
+
+ // Fallback to default light probes if Light Volume are not enabled
+ if (!_UdonLightVolumeEnabled || _UdonLightVolumeCount == 0) {
+ LV_SampleLightProbe(L0, L1r, L1g, L1b);
+ return;
+ }
+
+ uint volumeID_A = -1; // Main, dominant volume ID
+ uint volumeID_B = -1; // Secondary volume ID to blend main with
+
+ float3 localUVW = float3(0, 0, 0); // Last local UVW to use in disabled Light Probes mode
+ float3 localUVW_A = float3(0, 0, 0); // Main local UVW for Y Axis and Free rotations
+ float3 localUVW_B = float3(0, 0, 0); // Secondary local UVW
+
+ // Are A and B volumes NOT found?
+ bool isNoA = true;
+ bool isNoB = true;
+
+ // Additive volumes variables
+ uint addVolumesCount = 0;
+ float3 L0_, L1r_, L1g_, L1b_;
+
+ // Iterating through all light volumes with simplified algorithm requiring Light Volumes to be sorted by weight in descending order
+ [loop]
+ for (uint id = 0; id < (uint) _UdonLightVolumeCount; id++) {
+ localUVW = LV_LocalFromVolume(id, worldPos);
+ if (LV_PointLocalAABB(localUVW)) { // Intersection test
+ if (id < (uint) _UdonLightVolumeAdditiveCount) { // Sampling additive volumes
+ if (addVolumesCount < (uint) _UdonLightVolumeAdditiveMaxOverdraw) {
+ LV_SampleVolume(id, localUVW, L0_, L1r_, L1g_, L1b_);
+ L0 += L0_;
+ L1r += L1r_;
+ L1g += L1g_;
+ L1b += L1b_;
+ addVolumesCount++;
+ }
+ } else if (isNoA) { // First, searching for volume A
+ volumeID_A = id;
+ localUVW_A = localUVW;
+ isNoA = false;
+ } else { // Next, searching for volume B if A found
+ volumeID_B = id;
+ localUVW_B = localUVW;
+ isNoB = false;
+ break;
+ }
+ }
+ }
+
+ // Volume A SH components and mask to blend volume sides
+ float3 L0_A = float3(1, 1, 1);
+ float3 L1r_A = float3(0, 0, 0);
+ float3 L1g_A = float3(0, 0, 0);
+ float3 L1b_A = float3(0, 0, 0);
+
+ // If no volumes found, using Light Probes as fallback
+ if (isNoA && _UdonLightVolumeProbesBlend) {
+ LV_SampleLightProbe(L0_, L1r_, L1g_, L1b_);
+ L0 += L0_;
+ L1r += L1r_;
+ L1g += L1g_;
+ L1b += L1b_;
+ return;
+ }
+
+ // Fallback to lowest weight light volume if outside of every volume
+ localUVW_A = isNoA ? localUVW : localUVW_A;
+ volumeID_A = isNoA ? _UdonLightVolumeCount - 1 : volumeID_A;
+
+ // Sampling Light Volume A
+ LV_SampleVolume(volumeID_A, localUVW_A, L0_A, L1r_A, L1g_A, L1b_A);
+
+ float mask = LV_BoundsMask(localUVW_A, _UdonLightVolumeInvLocalEdgeSmooth[volumeID_A]);
+ if (mask == 1 || isNoA || (_UdonLightVolumeSharpBounds && isNoB)) { // Returning SH A result if it's the center of mask or out of bounds
+ L0 += L0_A;
+ L1r += L1r_A;
+ L1g += L1g_A;
+ L1b += L1b_A;
+ return;
+ }
+
+ // Volume B SH components
+ float3 L0_B = float3(1, 1, 1);
+ float3 L1r_B = float3(0, 0, 0);
+ float3 L1g_B = float3(0, 0, 0);
+ float3 L1b_B = float3(0, 0, 0);
+
+ if (isNoB && _UdonLightVolumeProbesBlend) { // No Volume found and light volumes blending enabled
+
+ // Sample Light Probes B
+ LV_SampleLightProbe(L0_B, L1r_B, L1g_B, L1b_B);
+
+ } else { // Blending Volume A and Volume B
+
+ // If no volume b found, use last one found to fallback
+ localUVW_B = isNoB ? localUVW : localUVW_B;
+ volumeID_B = isNoB ? _UdonLightVolumeCount - 1 : volumeID_B;
+
+ // Sampling Light Volume B
+ LV_SampleVolume(volumeID_B, localUVW_B, L0_B, L1r_B, L1g_B, L1b_B);
+
+ }
+
+ // Lerping SH components
+ L0 += lerp(L0_B, L0_A, mask);
+ L1r += lerp(L1r_B, L1r_A, mask);
+ L1g += lerp(L1g_B, L1g_A, mask);
+ L1b += lerp(L1b_B, L1b_A, mask);
+
+}
+
+// Calculates SH components based on the world position but for additive volumes only
+void LightVolumeAdditiveSH(float3 worldPos, out float3 L0, out float3 L1r, out float3 L1g, out float3 L1b) {
+
+ // Initializing output variables
+ L0 = float3(0, 0, 0);
+ L1r = float3(0, 0, 0);
+ L1g = float3(0, 0, 0);
+ L1b = float3(0, 0, 0);
+
+ if (!_UdonLightVolumeEnabled || _UdonLightVolumeAdditiveCount == 0) return;
+
+ // Additive volumes variables
+ float3 localUVW = float3(0, 0, 0);
+ float3 L0_, L1r_, L1g_, L1b_;
+
+ // Max additive volumes to sample
+ uint count = min((uint) _UdonLightVolumeAdditiveCount, (uint) _UdonLightVolumeAdditiveMaxOverdraw);
+
+ // Iterating through all light volumes with simplified algorithm requiring Light Volumes to be sorted by weight in descending order
+ [loop]
+ for (uint id = 0; id < count; id++) {
+ localUVW = LV_LocalFromVolume(id, worldPos);
+ //Intersection test
+ if (LV_PointLocalAABB(localUVW)) {
+ LV_SampleVolume(id, localUVW, L0_, L1r_, L1g_, L1b_);
+ L0 += L0_;
+ L1r += L1r_;
+ L1g += L1g_;
+ L1b += L1b_;
+ }
+ }
+
+}
+
+// Calculates L0 components based on the world position
+float3 LightVolumeSH_L0(float3 worldPos) {
+
+ // Fallback to default light probes if Light Volume are not enabled
+ if (!_UdonLightVolumeEnabled || _UdonLightVolumeCount == 0) {
+ return LV_SampleLightProbe_L0();
+ }
+
+ float3 L0 = float3(0, 0, 0);
+
+ uint volumeID_A = -1; // Main, dominant volume ID
+ uint volumeID_B = -1; // Secondary volume ID to blend main with
+
+ float3 localUVW = float3(0, 0, 0); // Last local UVW to use in disabled Light Probes mode
+ float3 localUVW_A = float3(0, 0, 0); // Main local UVW for Y Axis and Free rotations
+ float3 localUVW_B = float3(0, 0, 0); // Secondary local UVW
+
+ // Are A and B volumes NOT found?
+ bool isNoA = true;
+ bool isNoB = true;
+
+ // Additive volumes variables
+ uint addVolumesCount = 0;
+
+ // Iterating through all light volumes with simplified algorithm requiring Light Volumes to be sorted by weight in descending order
+ [loop]
+ for (uint id = 0; id < (uint) _UdonLightVolumeCount; id++) {
+ localUVW = LV_LocalFromVolume(id, worldPos);
+ if (LV_PointLocalAABB(localUVW)) { // Intersection test
+ if (id < (uint) _UdonLightVolumeAdditiveCount) { // Sampling additive volumes
+ if (addVolumesCount < (uint) _UdonLightVolumeAdditiveMaxOverdraw) {
+ L0 += LV_SampleVolume_L0(id, localUVW);
+ addVolumesCount++;
+ }
+ } else if (isNoA) { // First, searching for volume A
+ volumeID_A = id;
+ localUVW_A = localUVW;
+ isNoA = false;
+ } else { // Next, searching for volume B if A found
+ volumeID_B = id;
+ localUVW_B = localUVW;
+ isNoB = false;
+ break;
+ }
+ }
+ }
+
+ // If no volumes found, using Light Probes as fallback
+ if (isNoA && _UdonLightVolumeProbesBlend) {
+ return L0 + LV_SampleLightProbe_L0();
+ }
+
+ // Fallback to lowest weight light volume if outside of every volume
+ localUVW_A = isNoA ? localUVW : localUVW_A;
+ volumeID_A = isNoA ? _UdonLightVolumeCount - 1 : volumeID_A;
+
+ // Sampling Light Volume A
+ float3 L0_A = LV_SampleVolume_L0(volumeID_A, localUVW_A);
+
+ float mask = LV_BoundsMask(localUVW_A, _UdonLightVolumeInvLocalEdgeSmooth[volumeID_A]);
+ if (mask == 1 || isNoA || (_UdonLightVolumeSharpBounds && isNoB)) { // Returning SH A result if it's the center of mask or out of bounds
+ return L0 + L0_A;
+ }
+
+ // Volume B L0
+ float3 L0_B = float3(1, 1, 1);
+
+ if (isNoB && _UdonLightVolumeProbesBlend) { // No Volume found and light volumes blending enabled
+
+ // Sample Light Probes B
+ L0_B = LV_SampleLightProbe_L0();
+
+ } else { // Blending Volume A and Volume B
+
+ // If no volume b found, use last one found to fallback
+ localUVW_B = isNoB ? localUVW : localUVW_B;
+ volumeID_B = isNoB ? _UdonLightVolumeCount - 1 : volumeID_B;
+
+ // Sampling Light Volume B
+ L0_B = LV_SampleVolume_L0(volumeID_B, localUVW_B);
+
+ }
+
+ // Lerping L0
+ return L0 + lerp(L0_B, L0_A, mask);
+
+}
+
+// Calculates L0 component based on the world position but for additive volumes only
+float3 LightVolumeAdditiveSH_L0(float3 worldPos) {
+
+ // Initializing output variables
+ float3 L0 = float3(0, 0, 0);
+
+ if (!_UdonLightVolumeEnabled || _UdonLightVolumeAdditiveCount == 0) return L0;
+
+ // Additive volumes variables
+ float3 localUVW = float3(0, 0, 0);
+
+ // Max additive volumes to sample
+ uint count = min((uint) _UdonLightVolumeAdditiveCount, (uint) _UdonLightVolumeAdditiveMaxOverdraw);
+
+ // Iterating through all light volumes with simplified algorithm requiring Light Volumes to be sorted by weight in descending order
+ [loop]
+ for (uint id = 0; id < count; id++) {
+ localUVW = LV_LocalFromVolume(id, worldPos);
+ //Intersection test
+ if (LV_PointLocalAABB(localUVW)) {
+ L0 += LV_SampleVolume_L0(id, localUVW);
+ }
+ }
+
+ return L0;
+
+}
+
+#endif
diff --git a/decals.cginc b/decals.cginc
index e40b9f1..cd71c73 100644
--- a/decals.cginc
+++ b/decals.cginc
@@ -121,13 +121,22 @@ float4 getCmykWarpingPlanesColor(DecalParams params, float2 uv) {
float4 decal_color2 = getDecalColor(params, warped_uv[1].xy);
float4 decal_color3 = getDecalColor(params, warped_uv[1].zw);
- float4 final_cmyk = float4(
- rgbToCmyk_C(decal_color0.rgb),
- rgbToCmyk_M(decal_color1.rgb),
- rgbToCmyk_Y(decal_color2.rgb),
- rgbToCmyk_K(decal_color3.rgb));
-
+ float4 plane_alphas = float4(
+ decal_color0.a,
+ decal_color1.a,
+ decal_color2.a,
+ decal_color3.a
+ );
+
+ float4 final_cmyk = plane_alphas;
float3 final_rgb = saturate(cmykToRgb(final_cmyk));
+ float eps = 1E-5;
+ final_rgb = lerp(
+ final_rgb,
+ params.color.rgb,
+ all(plane_alphas>eps)
+ );
+
return float4(final_rgb, saturate(decal_color0.a + decal_color1.a + decal_color2.a + decal_color3.a));
}
@@ -374,6 +383,178 @@ void applyDecals(in v2f i, inout float4 albedo, inout float3 normal_tangent, ino
#endif
}
#endif // _DECAL3
+ #if defined(_DECAL4)
+ {
+ INIT_DECAL_PARAMS(decal, _Decal4_);
+ APPLY_DECAL_SEC00_GENERIC(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #if defined(_DECAL4_DOMAIN_WARPING)
+ APPLY_DECAL_SEC00B_DOMAIN_WARPING_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC00B_DOMAIN_WARPING_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL4_SDF) && defined(_DECAL4_CMYK_WARPING_PLANES)
+ APPLY_DECAL_SEC01_SDF_ON_WARPING_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #elif defined(_DECAL4_SDF)
+ APPLY_DECAL_SEC01_SDF_ON_WARPING_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC01_SDF_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL4_TILING_MODE)
+ APPLY_DECAL_SEC02_CLAMP_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC02_CLAMP_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL4_MASK)
+ APPLY_DECAL_SEC03_MASK_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC03_MASK_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL4_REPLACE_ALPHA)
+ APPLY_DECAL_SEC04_BLEND_MODE_REPLACE(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC04_BLEND_MODE_ALPHA_BLEND(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL4_NORMAL)
+ APPLY_DECAL_SEC05_NORMAL_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC05_NORMAL_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL4_REFLECTIONS)
+ APPLY_DECAL_SEC06_REFLECTIONS_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC06_REFLECTIONS_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ }
+ #endif // _DECAL4
+ #if defined(_DECAL5)
+ {
+ INIT_DECAL_PARAMS(decal, _Decal5_);
+ APPLY_DECAL_SEC00_GENERIC(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #if defined(_DECAL5_DOMAIN_WARPING)
+ APPLY_DECAL_SEC00B_DOMAIN_WARPING_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC00B_DOMAIN_WARPING_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL5_SDF) && defined(_DECAL5_CMYK_WARPING_PLANES)
+ APPLY_DECAL_SEC01_SDF_ON_WARPING_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #elif defined(_DECAL5_SDF)
+ APPLY_DECAL_SEC01_SDF_ON_WARPING_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC01_SDF_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL5_TILING_MODE)
+ APPLY_DECAL_SEC02_CLAMP_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC02_CLAMP_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL5_MASK)
+ APPLY_DECAL_SEC03_MASK_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC03_MASK_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL5_REPLACE_ALPHA)
+ APPLY_DECAL_SEC04_BLEND_MODE_REPLACE(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC04_BLEND_MODE_ALPHA_BLEND(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL5_NORMAL)
+ APPLY_DECAL_SEC05_NORMAL_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC05_NORMAL_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL5_REFLECTIONS)
+ APPLY_DECAL_SEC06_REFLECTIONS_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC06_REFLECTIONS_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ }
+ #endif // _DECAL5
+ #if defined(_DECAL6)
+ {
+ INIT_DECAL_PARAMS(decal, _Decal6_);
+ APPLY_DECAL_SEC00_GENERIC(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #if defined(_DECAL6_DOMAIN_WARPING)
+ APPLY_DECAL_SEC00B_DOMAIN_WARPING_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC00B_DOMAIN_WARPING_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL6_SDF) && defined(_DECAL6_CMYK_WARPING_PLANES)
+ APPLY_DECAL_SEC01_SDF_ON_WARPING_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #elif defined(_DECAL6_SDF)
+ APPLY_DECAL_SEC01_SDF_ON_WARPING_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC01_SDF_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL6_TILING_MODE)
+ APPLY_DECAL_SEC02_CLAMP_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC02_CLAMP_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL6_MASK)
+ APPLY_DECAL_SEC03_MASK_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC03_MASK_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL6_REPLACE_ALPHA)
+ APPLY_DECAL_SEC04_BLEND_MODE_REPLACE(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC04_BLEND_MODE_ALPHA_BLEND(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL6_NORMAL)
+ APPLY_DECAL_SEC05_NORMAL_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC05_NORMAL_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL6_REFLECTIONS)
+ APPLY_DECAL_SEC06_REFLECTIONS_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC06_REFLECTIONS_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ }
+ #endif // _DECAL6
+ #if defined(_DECAL7)
+ {
+ INIT_DECAL_PARAMS(decal, _Decal7_);
+ APPLY_DECAL_SEC00_GENERIC(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #if defined(_DECAL7_DOMAIN_WARPING)
+ APPLY_DECAL_SEC00B_DOMAIN_WARPING_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC00B_DOMAIN_WARPING_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL7_SDF) && defined(_DECAL7_CMYK_WARPING_PLANES)
+ APPLY_DECAL_SEC01_SDF_ON_WARPING_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #elif defined(_DECAL7_SDF)
+ APPLY_DECAL_SEC01_SDF_ON_WARPING_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC01_SDF_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL7_TILING_MODE)
+ APPLY_DECAL_SEC02_CLAMP_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC02_CLAMP_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL7_MASK)
+ APPLY_DECAL_SEC03_MASK_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC03_MASK_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL7_REPLACE_ALPHA)
+ APPLY_DECAL_SEC04_BLEND_MODE_REPLACE(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC04_BLEND_MODE_ALPHA_BLEND(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL7_NORMAL)
+ APPLY_DECAL_SEC05_NORMAL_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC05_NORMAL_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ #if defined(_DECAL7_REFLECTIONS)
+ APPLY_DECAL_SEC06_REFLECTIONS_ON(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #else
+ APPLY_DECAL_SEC06_REFLECTIONS_OFF(i, albedo, normal_tangent, metallic, smoothness, decal);
+ #endif
+ }
+ #endif // _DECAL7
}
#endif // __DECALS
diff --git a/features.cginc b/features.cginc
index 67605f3..e29471f 100644
--- a/features.cginc
+++ b/features.cginc
@@ -155,6 +155,50 @@
#pragma shader_feature_local _DECAL3_CMYK_WARPING_PLANES
#pragma shader_feature_local _DECAL3_DOMAIN_WARPING
//endex
+//ifex _Decal4_Enabled==0
+#pragma shader_feature_local _DECAL4
+#pragma shader_feature_local _DECAL4_NORMAL
+#pragma shader_feature_local _DECAL4_REFLECTIONS
+#pragma shader_feature_local _DECAL4_SDF
+#pragma shader_feature_local _DECAL4_MASK
+#pragma shader_feature_local _DECAL4_TILING_MODE
+#pragma shader_feature_local _DECAL4_REPLACE_ALPHA
+#pragma shader_feature_local _DECAL4_CMYK_WARPING_PLANES
+#pragma shader_feature_local _DECAL4_DOMAIN_WARPING
+//endex
+//ifex _Decal5_Enabled==0
+#pragma shader_feature_local _DECAL5
+#pragma shader_feature_local _DECAL5_NORMAL
+#pragma shader_feature_local _DECAL5_REFLECTIONS
+#pragma shader_feature_local _DECAL5_SDF
+#pragma shader_feature_local _DECAL5_MASK
+#pragma shader_feature_local _DECAL5_TILING_MODE
+#pragma shader_feature_local _DECAL5_REPLACE_ALPHA
+#pragma shader_feature_local _DECAL5_CMYK_WARPING_PLANES
+#pragma shader_feature_local _DECAL5_DOMAIN_WARPING
+//endex
+//ifex _Decal6_Enabled==0
+#pragma shader_feature_local _DECAL6
+#pragma shader_feature_local _DECAL6_NORMAL
+#pragma shader_feature_local _DECAL6_REFLECTIONS
+#pragma shader_feature_local _DECAL6_SDF
+#pragma shader_feature_local _DECAL6_MASK
+#pragma shader_feature_local _DECAL6_TILING_MODE
+#pragma shader_feature_local _DECAL6_REPLACE_ALPHA
+#pragma shader_feature_local _DECAL6_CMYK_WARPING_PLANES
+#pragma shader_feature_local _DECAL6_DOMAIN_WARPING
+//endex
+//ifex _Decal7_Enabled==0
+#pragma shader_feature_local _DECAL7
+#pragma shader_feature_local _DECAL7_NORMAL
+#pragma shader_feature_local _DECAL7_REFLECTIONS
+#pragma shader_feature_local _DECAL7_SDF
+#pragma shader_feature_local _DECAL7_MASK
+#pragma shader_feature_local _DECAL7_TILING_MODE
+#pragma shader_feature_local _DECAL7_REPLACE_ALPHA
+#pragma shader_feature_local _DECAL7_CMYK_WARPING_PLANES
+#pragma shader_feature_local _DECAL7_DOMAIN_WARPING
+//endex
//ifex _3D_SDF_Enabled==0
#pragma shader_feature_local _3D_SDF
diff --git a/globals.cginc b/globals.cginc
index 599098f..2f09881 100644
--- a/globals.cginc
+++ b/globals.cginc
@@ -283,18 +283,27 @@ float _Decal##n##_Domain_Warping_Speed;
#if defined(_DECAL0)
DECLARE_DECAL_VARIABLES(0)
#endif
-
#if defined(_DECAL1)
DECLARE_DECAL_VARIABLES(1)
#endif
-
#if defined(_DECAL2)
DECLARE_DECAL_VARIABLES(2)
#endif
-
#if defined(_DECAL3)
DECLARE_DECAL_VARIABLES(3)
#endif
+#if defined(_DECAL4)
+DECLARE_DECAL_VARIABLES(4)
+#endif
+#if defined(_DECAL5)
+DECLARE_DECAL_VARIABLES(5)
+#endif
+#if defined(_DECAL6)
+DECLARE_DECAL_VARIABLES(6)
+#endif
+#if defined(_DECAL7)
+DECLARE_DECAL_VARIABLES(7)
+#endif
#if defined(_VERTEX_DOMAIN_WARPING)
texture3D _Vertex_Domain_Warping_Noise;
diff --git a/unigram_letter_grid.cginc b/unigram_letter_grid.cginc
index dcae4db..e2f65dd 100644
--- a/unigram_letter_grid.cginc
+++ b/unigram_letter_grid.cginc
@@ -8,6 +8,7 @@
#include "globals.cginc"
#include "interpolators.cginc"
#include "math.cginc"
+#include "oklab.cginc"
#include "texture_utils.cginc"
// ULG = unigram letter grid
@@ -1017,9 +1018,10 @@ void GetBlock(uint which_block, out uint data[ULG_BLOCK_WIDTH]) {
// location where this block of tokens begins.
void GetTokens(uint screen_ptr,
out uint block_ptr,
- out uint tokens[ULG_BLOCK_WIDTH]) {
+ out uint tokens[ULG_BLOCK_WIDTH],
+ out uint which_block) {
block_ptr = floor(_Unigram_Letter_Visual_Pointers[0]+FUDGE_AMOUNT);
- uint which_block = 0;
+ which_block = 0;
[loop]
for (uint i = 1; i < ULG_NUM_BLOCKS; i++) {
uint next_ptr = floor(_Unigram_Letter_Visual_Pointers[i]+FUDGE_AMOUNT);
@@ -1094,10 +1096,10 @@ uint GetTokenChar(uint token_offset, uint nth)
#if defined(ULG_VP) && defined(ULG_D0) && defined(ULG_D1)
// Get the character which covers the screen position.
-uint GetChar(uint screen_ptr) {
+uint GetChar(uint screen_ptr, out uint which_block, out uint which_datum) {
uint block_ptr;
uint tokens[ULG_BLOCK_WIDTH];
- GetTokens(screen_ptr, block_ptr, tokens);
+ GetTokens(screen_ptr, block_ptr, tokens, which_block);
// Begin scanning at the start of the block.
uint start = block_ptr;
// The current token is rendered starting at this location.
@@ -1111,6 +1113,7 @@ uint GetChar(uint screen_ptr) {
bool got_match = false;
[loop]
for (uint i = 0; i < ULG_BLOCK_WIDTH; i++) {
+ which_datum = i;
TokenLengthOffset(tokens[i], token_length, token_offset);
if (token_length == 0) {
continue;
@@ -1164,53 +1167,8 @@ UnigramLetterGridOutput UnigramLetterGrid(v2f i, bool facing) {
uint flat_cell_pos = UnfoldIndex(cell_pos, grid_res);
-#if 1
- float c = GetChar(flat_cell_pos);
-#elif 0
- float token_offset=65536;
- float c = GetTokenChar(token_offset, cell_pos.x);
-#elif 0
- float offset = 0;
- [branch]
- if (i.uv01.x < 0) {
- offset = 1;
- }
- float c0 = _Unigram_Letter_Visual_Pointers[cell_pos.x+offset] + '0';
- float c1 = _Unigram_Letter_Data_Byte00[cell_pos.x+offset] + '0';
- float c2 = _Unigram_Letter_Data_Byte01[cell_pos.x+offset] + '0';
- float c;
- switch (cell_pos.y % 3) {
- case 0:
- c = c0;
- break;
- case 1:
- c = c1;
- break;
- case 2:
- c = c2;
- break;
- }
-#else
- // DEBUG: show the token offset and length for the first 4 tokens.
- uint tok_len, tok_off;
- TokenLengthOffset(cell_pos.y, tok_len, tok_off);
- float c;
- switch (cell_pos.x % 4) {
- case 0:
- c = tok_off & 0xff;
- break;
- case 1:
- c = (tok_off >> 8) & 0xff;
- break;
- case 2:
- c = (tok_off >> 16) & 0xff;
- break;
- case 3:
- c = tok_len;
- break;
- }
- c += '0';
-#endif
+ uint which_block, which_datum;
+ float c = GetChar(flat_cell_pos, which_block, which_datum);
float3 msd = renderInBox(c, uv, cell_uv, _Unigram_Letter_Grid_Glyphs, font_res).rgb;
float sd = median(msd);
@@ -1236,6 +1194,21 @@ UnigramLetterGridOutput UnigramLetterGrid(v2f i, bool facing) {
output.roughness = 1;
output.emission = 0;
+ // Visualize which block is being rendered.
+ {
+ float eps = 1.2E-1;
+ bool in_range = (cell_uv.x < eps || cell_uv.y < eps || 1.0 - cell_uv.x < eps || 1.0 - cell_uv.y < eps);
+ if (in_range)
+ {
+ float hue = which_datum * 0.3f;
+ hue += (which_block % 2) * 0.5f;
+ hue = frac(hue);
+ hue *= TAU;
+ output.albedo.rgb = OKLCHtoLRGB(float3(0.8, 0.2, hue));
+ output.albedo.a = 1;
+ }
+ }
+
return output;
}
diff --git a/yum_lighting.cginc b/yum_lighting.cginc
index b2a7952..d7afcef 100644
--- a/yum_lighting.cginc
+++ b/yum_lighting.cginc
@@ -7,6 +7,7 @@
#include "UnityLightingCommon.cginc"
#include "features.cginc"
+#include "LightVolumes.cginc"
#include "poi.cginc"
#include "yum_pbr.cginc"
@@ -55,6 +56,10 @@ struct YumLighting {
float NoL_wrapped_d; // diffuse
#endif
float attenuation;
+ float3 L00;
+ float3 L01r;
+ float3 L01g;
+ float3 L01b;
};
float getShadowAttenuation(v2f i)
@@ -152,7 +157,7 @@ float3 getIndirectSpecular(v2f i, YumPbr pbr, float3 view_dir, float diffuse_lum
#endif
}
-float3 yumSH9(float4 n) {
+float3 yumSH9(float4 n, float3 worldPos, inout YumLighting light) {
#if defined(YUM_SH9_STANDARD)
// Unity gives us the first three bands (L0-L2) of SH coefficients as follows:
// unity_SHA*.w: L0 coefficients
@@ -184,29 +189,49 @@ float3 yumSH9(float4 n) {
L21 * n.x * n.z +
L22 * (n.x * n.x - n.y * n.y);
+ light.L00 = L00;
+ light.L01r = unity_SHAr.xyz;
+ light.L01g = unity_SHAg.xyz;
+ light.L01b = unity_SHAb.xyz;
+
return L0 + L1 + L2;
+#elif 1
+ // Light volumes. We omit the L01 contribution since flat shading looks
+ // better on avatars.
+ LightVolumeSH(worldPos, light.L00, light.L01r, light.L01g, light.L01b);
+ return LightVolumeEvaluate(n.xyz, light.L00,
+ _UdonLightVolumeEnabled ? light.L01r : 0,
+ _UdonLightVolumeEnabled ? light.L01g : 0,
+ _UdonLightVolumeEnabled ? light.L01b : 0);
#else
// On non-photorealistic avatars, simply using the diffuse component looks
// better. *shruge*
float3 L00 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
+
+ light.L00 = L00;
+ light.L01r = unity_SHAr.xyz;
+ light.L01g = unity_SHAg.xyz;
+ light.L01b = unity_SHAb.xyz;
+
return L00;
#endif
}
-float4 getIndirectDiffuse(v2f i, float4 vertexLightColor) {
+float4 getIndirectDiffuse(v2f i, float4 vertexLightColor,
+ inout YumLighting light) {
float4 diffuse = vertexLightColor;
#if defined(FORWARD_BASE_PASS)
#if defined(LIGHTMAP_ON)
diffuse.xyz = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, i.uv2));
#else
- diffuse.xyz += max(0, yumSH9(float4(0, 0, 0, 1)));
+ diffuse.xyz += max(0, yumSH9(float4(i.normal, 0), i.worldPos, light));
#endif
#endif
return diffuse;
}
YumLighting GetYumLighting(v2f i, YumPbr pbr) {
- YumLighting light;
+ YumLighting light = (YumLighting) 0;
// normalize has no visibile impact in test scene
light.view_dir = -i.eyeVec.xyz;
@@ -216,7 +241,7 @@ YumLighting GetYumLighting(v2f i, YumPbr pbr) {
light.direct = _LightColor0.rgb;
// TODO filament's spherical harmonics look nicer than this.
// See FilamentLightIndirect.cginc::UnityGI_Irradiance in filamented.
- light.diffuse = getIndirectDiffuse(i, /*vertexLightColor=*/0);
+ light.diffuse = getIndirectDiffuse(i, /*vertexLightColor=*/0, light);
#if defined(_MIN_BRIGHTNESS)
light.diffuse = max(_Min_Brightness, light.diffuse);
#endif