diff options
| -rw-r--r-- | 2ner.cginc | 3 | ||||
| -rw-r--r-- | 2ner.shader | 254 | ||||
| -rw-r--r-- | LightVolumes.cginc | 503 | ||||
| -rw-r--r-- | decals.cginc | 193 | ||||
| -rw-r--r-- | features.cginc | 44 | ||||
| -rw-r--r-- | globals.cginc | 15 | ||||
| -rw-r--r-- | unigram_letter_grid.cginc | 75 | ||||
| -rw-r--r-- | yum_lighting.cginc | 35 |
8 files changed, 1052 insertions, 70 deletions
@@ -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
|
