From 0264f5e767b0b54e82b7c11457b491be555be577 Mon Sep 17 00:00:00 2001 From: yum Date: Wed, 26 Feb 2025 01:18:09 -0800 Subject: Add glitter and more masked stencil channels --- 2ner.cginc | 46 ++++++-- 2ner.shader | 348 +++++++++++++++++++++++++++++++++++++++++++++++++-------- features.cginc | 16 +++ glitter.cginc | 87 +++++++++++++++ globals.cginc | 46 ++++++-- math.cginc | 9 ++ quilez.cginc | 8 ++ yum_pbr.cginc | 42 ++++++- 8 files changed, 531 insertions(+), 71 deletions(-) create mode 100644 glitter.cginc diff --git a/2ner.cginc b/2ner.cginc index f0efe83..75a1711 100644 --- a/2ner.cginc +++ b/2ner.cginc @@ -21,12 +21,33 @@ v2f vert(appdata v) { // hide outlines when not locked. return (v2f) (0.0/0.0); #endif -#if defined(MASKED_STENCIL_PASS) - float masked_stencil_mask = _Masked_Stencil_Mask.SampleLevel(linear_repeat_s, v.uv01, 0); - if (masked_stencil_mask < 0.5) { +#if defined(MASKED_STENCIL1_PASS) + float masked_stencil1_mask = _Masked_Stencil1_Mask.SampleLevel(linear_repeat_s, v.uv01, 0); + if (masked_stencil1_mask < 0.5) { return (v2f) (0.0/0.0); } #endif +#if defined(MASKED_STENCIL2_PASS) + float masked_stencil2_mask = _Masked_Stencil2_Mask.SampleLevel(linear_repeat_s, v.uv01, 0); + if (masked_stencil2_mask < 0.5) { + return (v2f) (0.0/0.0); + } +#endif +#if defined(MASKED_STENCIL3_PASS) + float masked_stencil3_mask = _Masked_Stencil3_Mask.SampleLevel(linear_repeat_s, v.uv01, 0); + if (masked_stencil3_mask < 0.5) { + return (v2f) (0.0/0.0); + } +#endif +#if defined(MASKED_STENCIL4_PASS) + float masked_stencil4_mask = _Masked_Stencil4_Mask.SampleLevel(linear_repeat_s, v.uv01, 0); + if (masked_stencil4_mask < 0.5) { + return (v2f) (0.0/0.0); + } +#endif +#if defined(EXTRA_STENCIL_COLOR_PASS) && !defined(_EXTRA_STENCIL_COLOR_PASS) + return (v2f) (0.0/0.0); +#endif v2f o; @@ -38,6 +59,7 @@ v2f vert(appdata v) { #if defined(OUTLINE_PASS) #if defined(_OUTLINE_MASK) float thickness = _Outline_Mask.SampleLevel(linear_repeat_s, v.uv01, 0); + thickness = (_Outline_Mask_Invert == 0 ? thickness : 1 - thickness); #else float thickness = 1; #endif @@ -65,7 +87,7 @@ v2f vert(appdata v) { #endif #if defined(_FOCAL_LENGTH_CONTROL) - UNITY_BRANCH + [branch] if (_Focal_Length_Enabled_Dynamic) { float4 fl_worldPos_unscaled = mul(unity_ObjectToWorld, v.vertex); float4 fl_viewPos_unscaled = mul(UNITY_MATRIX_V, fl_worldPos_unscaled); @@ -90,6 +112,7 @@ v2f vert(appdata v) { o.worldPos = mul(unity_ObjectToWorld, v.vertex); o.objPos = v.vertex; o.eyeVec.xyz = normalize(o.worldPos - _WorldSpaceCameraPos); + o.eyeVec.w = 1; // These are used to convert normals from tangent space to world space. o.normal = UnityObjectToWorldNormal(v.normal); @@ -136,7 +159,7 @@ float4 frag(v2f i) : SV_Target { pbr.normal = eye_effect_00.normal; #endif - UNITY_BRANCH + [branch] if (_Mode == 1) { clip(pbr.albedo.a - _Clip); pbr.albedo.a = 1; @@ -146,23 +169,24 @@ float4 frag(v2f i) : SV_Target { pbr.albedo = _ExtraStencilColor; #endif -#if defined(FORWARD_BASE_PASS) - applyMatcapsAndRimLighting(i, pbr); -#endif - #if defined(FORWARD_BASE_PASS) || defined(FORWARD_ADD_PASS) || defined(OUTLINE_PASS) || defined(EXTRA_STENCIL_COLOR_PASS) YumLighting l = GetYumLighting(i, pbr); +#if defined(FORWARD_BASE_PASS) + applyMatcapsAndRimLighting(i, l, pbr); + pbr.albedo.rgb = max(0, pbr.albedo.rgb); +#endif + float4 lit = YumBRDF(i, l, pbr); -#if defined(_EMISSION) +#if defined(_EMISSION) || (defined(_GLITTER) && defined(FORWARD_BASE_PASS)) lit.rgb += pbr.emission; #endif UNITY_EXTRACT_FOG_FROM_EYE_VEC(i); UNITY_APPLY_FOG(_unity_fogCoord, lit.rgb); return lit; -#elif defined(SHADOW_CASTER_PASS) || defined(MASKED_STENCIL_PASS) +#elif defined(SHADOW_CASTER_PASS) || defined(MASKED_STENCIL1_PASS) || defined(MASKED_STENCIL2_PASS) || defined(MASKED_STENCIL3_PASS) || defined(MASKED_STENCIL4_PASS) return 0; #endif } diff --git a/2ner.shader b/2ner.shader index 4476282..23cbd74 100644 --- a/2ner.shader +++ b/2ner.shader @@ -80,6 +80,7 @@ Shader "yum_food/2ner" [HideInInspector] m_start_OutlinesMask("Mask", Float) = 0 [ThryToggle(_OUTLINE_MASK)]_Outline_Mask_Enabled("Enable", Float) = 0 _Outline_Mask("Thickness mask", 2D) = "white" {} + _Outline_Mask_Invert("Invert", Float) = 0 [HideInInspector] m_end_OutlinesMask("Mask", Float) = 0 [HideInInspector] m_end_Outlines("Outlines", Float) = 0 //endex @@ -281,33 +282,120 @@ Shader "yum_food/2ner" [HideInInspector] m_end_SSFD("SSFD", Float) = 0 //endex - //ifex _Masked_Stencil_Enabled==0 - [HideInInspector] m_start_Masked_Stencil("Masked stencil", Float) = 0 - [ThryToggle(_)] _Masked_Stencil_Enabled("Enable", Float) = 0 - [ThryWideEnum(Simple, 0, Front Face vs Back Face, 1)] _MaskedStencilType ("Stencil Type", Float) = 0 - _Masked_Stencil_Mask("Mask", 2D) = "white" {} - [IntRange] _MaskedStencilRef ("Stencil Reference Value", Range(0, 255)) = 0 - [IntRange] _MaskedStencilReadMask ("Stencil ReadMask Value", Range(0, 255)) = 255 - [IntRange] _MaskedStencilWriteMask ("Stencil WriteMask Value", Range(0, 255)) = 255 - [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencilPassOp ("Stencil Pass Op--{condition_showS:(_StencilType==0)}", Float) = 0 - [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencilFailOp ("Stencil Fail Op--{condition_showS:(_StencilType==0)}", Float) = 0 - [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencilZFailOp ("Stencil ZFail Op--{condition_showS:(_StencilType==0)}", Float) = 0 - [Enum(UnityEngine.Rendering.CompareFunction)] _MaskedStencilCompareFunction ("Stencil Compare Function--{condition_showS:(_StencilType==0)}", Float) = 8 - [HideInInspector] m_start_MaskedStencilPassBackOptions("Back--{condition_showS:(_MaskedStencilType==1)}", Float) = 0 + //ifex _Masked_Stencil1_Enabled==0 + [HideInInspector] m_start_Masked_Stencil1("Masked stencil 1", Float) = 0 + [ThryToggle(_)] _Masked_Stencil1_Enabled("Enable", Float) = 0 + [ThryWideEnum(Simple, 0, Front Face vs Back Face, 1)] _Stencil1Type ("Stencil Type", Float) = 0 + _Masked_Stencil1_Mask("Mask", 2D) = "white" {} + [IntRange] _MaskedStencil1Ref ("Stencil Reference Value", Range(0, 255)) = 0 + [IntRange] _MaskedStencil1ReadMask ("Stencil ReadMask Value", Range(0, 255)) = 255 + [IntRange] _MaskedStencil1WriteMask ("Stencil WriteMask Value", Range(0, 255)) = 255 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil1PassOp ("Stencil Pass Op--{condition_showS:(_Stencil1Type==0)}", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil1FailOp ("Stencil Fail Op--{condition_showS:(_Stencil1Type==0)}", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil1ZFailOp ("Stencil ZFail Op--{condition_showS:(_Stencil1Type==0)}", Float) = 0 + [Enum(UnityEngine.Rendering.CompareFunction)] _MaskedStencil1CompareFunction ("Stencil Compare Function--{condition_showS:(_Stencil1Type==0)}", Float) = 8 + [HideInInspector] m_start_MaskedStencil1PassBackOptions("Back--{condition_showS:(_Stencil1Type==1)}", Float) = 0 [Helpbox(1)] _FFBFStencilHelp0 ("Front Face and Back Face Stencils only work when locked in due to Unity's Stencil managment", Int) = 0 - [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencilBackPassOp ("Back Pass Op", Float) = 0 - [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencilBackFailOp ("Back Fail Op", Float) = 0 - [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencilBackZFailOp ("Back ZFail Op", Float) = 0 - [Enum(UnityEngine.Rendering.CompareFunction)] _MaskedStencilBackCompareFunction ("Back Compare Function", Float) = 8 - [HideInInspector] m_end_MaskedStencilPassBackOptions("Back", Float) = 0 - [HideInInspector] m_start_MaskedStencilPassFrontOptions("Front--{condition_showS:(_MaskedStencilType==1)}", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil1BackPassOp ("Back Pass Op", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil1BackFailOp ("Back Fail Op", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil1BackZFailOp ("Back ZFail Op", Float) = 0 + [Enum(UnityEngine.Rendering.CompareFunction)] _MaskedStencil1BackCompareFunction ("Back Compare Function", Float) = 8 + [HideInInspector] m_end_MaskedStencil1PassBackOptions("Back", Float) = 0 + [HideInInspector] m_start_MaskedStencil1PassFrontOptions("Front--{condition_showS:(_Stencil1Type==1)}", Float) = 0 [Helpbox(1)] _FFBFStencilHelp1 ("Front Face and Back Face Stencils only work when locked in due to Unity's Stencil managment", Int) = 0 - [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencilFrontPassOp ("Front Pass Op", Float) = 0 - [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencilFrontFailOp ("Front Fail Op", Float) = 0 - [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencilFrontZFailOp ("Front ZFail Op", Float) = 0 - [Enum(UnityEngine.Rendering.CompareFunction)] _MaskedStencilFrontCompareFunction ("Front Compare Function", Float) = 8 - [HideInInspector] m_end_MaskedStencilPassFrontOptions("Front", Float) = 0 - [HideInInspector] m_end_Masked_Stencil("Masked stencil", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil1FrontPassOp ("Front Pass Op", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil1FrontFailOp ("Front Fail Op", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil1FrontZFailOp ("Front ZFail Op", Float) = 0 + [Enum(UnityEngine.Rendering.CompareFunction)] _MaskedStencil1FrontCompareFunction ("Front Compare Function", Float) = 8 + [HideInInspector] m_end_MaskedStencil1PassFrontOptions("Front", Float) = 0 + [HideInInspector] m_end_Masked_Stencil1("Masked stencil 1", Float) = 0 + //endex + + //ifex _Masked_Stencil2_Enabled==0 + [HideInInspector] m_start_Masked_Stencil2("Masked stencil 2", Float) = 0 + [ThryToggle(_)] _Masked_Stencil2_Enabled("Enable", Float) = 0 + [ThryWideEnum(Simple, 0, Front Face vs Back Face, 1)] _Stencil2Type ("Stencil Type", Float) = 0 + _Masked_Stencil2_Mask("Mask", 2D) = "white" {} + [IntRange] _MaskedStencil2Ref ("Stencil Reference Value", Range(0, 255)) = 0 + [IntRange] _MaskedStencil2ReadMask ("Stencil ReadMask Value", Range(0, 255)) = 255 + [IntRange] _MaskedStencil2WriteMask ("Stencil WriteMask Value", Range(0, 255)) = 255 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil2PassOp ("Stencil Pass Op--{condition_showS:(_Stencil2Type==0)}", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil2FailOp ("Stencil Fail Op--{condition_showS:(_Stencil2Type==0)}", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil2ZFailOp ("Stencil ZFail Op--{condition_showS:(_Stencil2Type==0)}", Float) = 0 + [Enum(UnityEngine.Rendering.CompareFunction)] _MaskedStencil2CompareFunction ("Stencil Compare Function--{condition_showS:(_Stencil2Type==0)}", Float) = 8 + [HideInInspector] m_start_MaskedStencil2PassBackOptions("Back--{condition_showS:(_Stencil2Type==1)}", Float) = 0 + [Helpbox(1)] _FFBFStencilHelp0 ("Front Face and Back Face Stencils only work when locked in due to Unity's Stencil managment", Int) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil2BackPassOp ("Back Pass Op", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil2BackFailOp ("Back Fail Op", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil2BackZFailOp ("Back ZFail Op", Float) = 0 + [Enum(UnityEngine.Rendering.CompareFunction)] _MaskedStencil2BackCompareFunction ("Back Compare Function", Float) = 8 + [HideInInspector] m_end_MaskedStencil2PassBackOptions("Back", Float) = 0 + [HideInInspector] m_start_MaskedStencil2PassFrontOptions("Front--{condition_showS:(_Stencil2Type==1)}", Float) = 0 + [Helpbox(1)] _FFBFStencilHelp1 ("Front Face and Back Face Stencils only work when locked in due to Unity's Stencil managment", Int) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil2FrontPassOp ("Front Pass Op", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil2FrontFailOp ("Front Fail Op", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil2FrontZFailOp ("Front ZFail Op", Float) = 0 + [Enum(UnityEngine.Rendering.CompareFunction)] _MaskedStencil2FrontCompareFunction ("Front Compare Function", Float) = 8 + [HideInInspector] m_end_MaskedStencil2PassFrontOptions("Front", Float) = 0 + [HideInInspector] m_end_Masked_Stencil2("Masked stencil 2", Float) = 0 + //endex + + //ifex _Masked_Stencil3_Enabled==0 + [HideInInspector] m_start_Masked_Stencil3("Masked stencil 3", Float) = 0 + [ThryToggle(_)] _Masked_Stencil3_Enabled("Enable", Float) = 0 + [ThryWideEnum(Simple, 0, Front Face vs Back Face, 1)] _Stencil3Type ("Stencil Type", Float) = 0 + _Masked_Stencil3_Mask("Mask", 2D) = "white" {} + [IntRange] _MaskedStencil3Ref ("Stencil Reference Value", Range(0, 255)) = 0 + [IntRange] _MaskedStencil3ReadMask ("Stencil ReadMask Value", Range(0, 255)) = 255 + [IntRange] _MaskedStencil3WriteMask ("Stencil WriteMask Value", Range(0, 255)) = 255 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil3PassOp ("Stencil Pass Op--{condition_showS:(_Stencil3Type==0)}", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil3FailOp ("Stencil Fail Op--{condition_showS:(_Stencil3Type==0)}", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil3ZFailOp ("Stencil ZFail Op--{condition_showS:(_Stencil3Type==0)}", Float) = 0 + [Enum(UnityEngine.Rendering.CompareFunction)] _MaskedStencil3CompareFunction ("Stencil Compare Function--{condition_showS:(_Stencil3Type==0)}", Float) = 8 + [HideInInspector] m_start_MaskedStencil3PassBackOptions("Back--{condition_showS:(_Stencil3Type==1)}", Float) = 0 + [Helpbox(1)] _FFBFStencilHelp0 ("Front Face and Back Face Stencils only work when locked in due to Unity's Stencil managment", Int) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil3BackPassOp ("Back Pass Op", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil3BackFailOp ("Back Fail Op", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil3BackZFailOp ("Back ZFail Op", Float) = 0 + [Enum(UnityEngine.Rendering.CompareFunction)] _MaskedStencil3BackCompareFunction ("Back Compare Function", Float) = 8 + [HideInInspector] m_end_MaskedStencil3PassBackOptions("Back", Float) = 0 + [HideInInspector] m_start_MaskedStencil3PassFrontOptions("Front--{condition_showS:(_Stencil3Type==1)}", Float) = 0 + [Helpbox(1)] _FFBFStencilHelp1 ("Front Face and Back Face Stencils only work when locked in due to Unity's Stencil managment", Int) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil3FrontPassOp ("Front Pass Op", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil3FrontFailOp ("Front Fail Op", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil3FrontZFailOp ("Front ZFail Op", Float) = 0 + [Enum(UnityEngine.Rendering.CompareFunction)] _MaskedStencil3FrontCompareFunction ("Front Compare Function", Float) = 8 + [HideInInspector] m_end_MaskedStencil3PassFrontOptions("Front", Float) = 0 + [HideInInspector] m_end_Masked_Stencil3("Masked stencil 3", Float) = 0 + //endex + + //ifex _Masked_Stencil4_Enabled==0 + [HideInInspector] m_start_Masked_Stencil4("Masked stencil 4", Float) = 0 + [ThryToggle(_)] _Masked_Stencil4_Enabled("Enable", Float) = 0 + [ThryWideEnum(Simple, 0, Front Face vs Back Face, 1)] _Stencil4Type ("Stencil Type", Float) = 0 + _Masked_Stencil4_Mask("Mask", 2D) = "white" {} + [IntRange] _MaskedStencil4Ref ("Stencil Reference Value", Range(0, 255)) = 0 + [IntRange] _MaskedStencil4ReadMask ("Stencil ReadMask Value", Range(0, 255)) = 255 + [IntRange] _MaskedStencil4WriteMask ("Stencil WriteMask Value", Range(0, 255)) = 255 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil4PassOp ("Stencil Pass Op--{condition_showS:(_Stencil4Type==0)}", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil4FailOp ("Stencil Fail Op--{condition_showS:(_Stencil4Type==0)}", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil4ZFailOp ("Stencil ZFail Op--{condition_showS:(_Stencil4Type==0)}", Float) = 0 + [Enum(UnityEngine.Rendering.CompareFunction)] _MaskedStencil4CompareFunction ("Stencil Compare Function--{condition_showS:(_Stencil4Type==0)}", Float) = 8 + [HideInInspector] m_start_MaskedStencil4PassBackOptions("Back--{condition_showS:(_Stencil4Type==1)}", Float) = 0 + [Helpbox(1)] _FFBFStencilHelp0 ("Front Face and Back Face Stencils only work when locked in due to Unity's Stencil managment", Int) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil4BackPassOp ("Back Pass Op", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil4BackFailOp ("Back Fail Op", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil4BackZFailOp ("Back ZFail Op", Float) = 0 + [Enum(UnityEngine.Rendering.CompareFunction)] _MaskedStencil4BackCompareFunction ("Back Compare Function", Float) = 8 + [HideInInspector] m_end_MaskedStencil4PassBackOptions("Back", Float) = 0 + [HideInInspector] m_start_MaskedStencil4PassFrontOptions("Front--{condition_showS:(_Stencil4Type==1)}", Float) = 0 + [Helpbox(1)] _FFBFStencilHelp1 ("Front Face and Back Face Stencils only work when locked in due to Unity's Stencil managment", Int) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil4FrontPassOp ("Front Pass Op", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil4FrontFailOp ("Front Fail Op", Float) = 0 + [Enum(UnityEngine.Rendering.StencilOp)] _MaskedStencil4FrontZFailOp ("Front ZFail Op", Float) = 0 + [Enum(UnityEngine.Rendering.CompareFunction)] _MaskedStencil4FrontCompareFunction ("Front Compare Function", Float) = 8 + [HideInInspector] m_end_MaskedStencil4PassFrontOptions("Front", Float) = 0 + [HideInInspector] m_end_Masked_Stencil4("Masked stencil 4", Float) = 0 //endex //ifex _Stencil_Enabled==0 @@ -403,6 +491,35 @@ Shader "yum_food/2ner" [HideInInspector] m_end_Focal_Length_Control("Focal Length Control", Float) = 0 //endex + //ifex _Glitter_Enabled==0 + [HideInInspector] m_start_Glitter("Glitter", Float) = 0 + [ThryToggle(_GLITTER)] _Glitter_Enabled("Enable", Float) = 0 + [HDR] _Glitter_Color("Color", Color) = (1, 1, 1, 1) + _Glitter_Emission("Emission", Color) = (1, 1, 1, 1) + _Glitter_Layers("Layers", Range(1, 5)) = 1 + _Glitter_Grid_Size("Grid size", Float) = 1 + _Glitter_Size("Size", Range(0, 1)) = 1 + _Glitter_Major_Minor_Ratio("Major/minor ratio", Range(0, 1)) = 1 + _Glitter_Angle_Randomization_Range("Angle randomization", Range(0, 1)) = 1 + _Glitter_Center_Randomization_Range("Center randomization", Range(0, 1)) = 1 + _Glitter_Size_Randomization_Range("Size randomization", Range(0, 1)) = 0.4 + _Glitter_Existence_Chance("Existence chance", Range(0, 1)) = 0.1 + //ifex _Glitter_Angle_Limit_Enabled==0 + [HideInInspector] m_start_Glitter_Angle_Limit("Angle limit", Float) = 0 + [ThryToggle(_GLITTER_ANGLE_LIMIT)] _Glitter_Angle_Limit_Enabled("Enable", Float) = 0 + _Glitter_Angle_Limit("Limit", Range(0.001, 1)) = 1 + _Glitter_Angle_Limit_Transition_Width("Transition width", Range(0, 1)) = 0.1 + [HideInInspector] m_end_Glitter_Angle_Limit("Angle limit", Float) = 0 + //endex + //ifex _Glitter_Mask_Enabled==0 + [HideInInspector] m_start_Glitter_Mask("Mask", Float) = 0 + [ThryToggle(_GLITTER_MASK)] _Glitter_Mask_Enabled("Enable", Float) = 0 + _Glitter_Mask("Mask", 2D) = "white" {} + [HideInInspector] m_end_Glitter_Mask("Mask", Float) = 0 + //endex + [HideInInspector] m_end_Glitter("Glitter", Float) = 0 + //endex + [HideInInspector] m_lightingOptions("Lighting Options", Float) = 0 //ifex _Receive_Shadows_Enabled==0 [HideInInspector] m_start_Shadow_Receiving("Receive shadows", Float) = 0 @@ -498,9 +615,9 @@ Shader "yum_food/2ner" SubShader { Tags { "RenderType" = "Opaque" "Queue" = "Geometry" "VRCFallback" = "Standard" } - //ifex _Masked_Stencil_Enabled==0 + //ifex _Masked_Stencil1_Enabled==0 Pass { - Name "MASKEDSTENCIL" + Name "MASKEDSTENCIL1" Tags { "LightMode" = "ForwardBase" } //BlendOp [_BlendOp], [_BlendOpAlpha] //Blend [_SrcBlend] [_DstBlend], [_SrcBlendAlpha] [_DstBlendAlpha] @@ -510,26 +627,167 @@ Shader "yum_food/2ner" Stencil { - Ref [_MaskedStencilRef] - ReadMask [_MaskedStencilReadMask] - WriteMask [_MaskedStencilWriteMask] - //ifex _MaskedStencilType==1 - Comp [_MaskedStencilCompareFunction] - Pass [_MaskedStencilPassOp] - Fail [_MaskedStencilFailOp] - ZFail [_MaskedStencilZFailOp] + Ref [_MaskedStencil1Ref] + ReadMask [_MaskedStencil1ReadMask] + WriteMask [_MaskedStencil1WriteMask] + //ifex _Stencil1Type==1 + Comp [_MaskedStencil1CompareFunction] + Pass [_MaskedStencil1PassOp] + Fail [_MaskedStencil1FailOp] + ZFail [_MaskedStencil1ZFailOp] //endex - //ifex _MaskedStencilType==0 - CompBack [_MaskedStencilBackCompareFunction] - PassBack [_MaskedStencilBackPassOp] - FailBack [_MaskedStencilBackFailOp] - ZFailBack [_MaskedStencilBackZFailOp] + //ifex _Stencil1Type==0 + CompBack [_MaskedStencil1BackCompareFunction] + PassBack [_MaskedStencil1BackPassOp] + FailBack [_MaskedStencil1BackFailOp] + ZFailBack [_MaskedStencil1BackZFailOp] - CompFront [_MaskedStencilFrontCompareFunction] - PassFront [_MaskedStencilFrontPassOp] - FailFront [_MaskedStencilFrontFailOp] - ZFailFront [_MaskedStencilFrontZFailOp] + CompFront [_MaskedStencil1FrontCompareFunction] + PassFront [_MaskedStencil1FrontPassOp] + FailFront [_MaskedStencil1FrontFailOp] + ZFailFront [_MaskedStencil1FrontZFailOp] + //endex + } + + CGPROGRAM + #pragma target 5.0 + #pragma multi_compile_instancing + #pragma vertex vert + #pragma fragment frag + + #define MASKED_STENCIL1_PASS + + #include "2ner.cginc" + ENDCG + } + //endex + //ifex _Masked_Stencil2_Enabled==0 + Pass { + Name "MASKEDSTENCIL2" + Tags { "LightMode" = "ForwardBase" } + //BlendOp [_BlendOp], [_BlendOpAlpha] + //Blend [_SrcBlend] [_DstBlend], [_SrcBlendAlpha] [_DstBlendAlpha] + //Cull [_Cull] + ZWrite Off + ZTest LEqual + + Stencil + { + Ref [_MaskedStencil2Ref] + ReadMask [_MaskedStencil2ReadMask] + WriteMask [_MaskedStencil2WriteMask] + //ifex _Stencil2Type==1 + Comp [_MaskedStencil2CompareFunction] + Pass [_MaskedStencil2PassOp] + Fail [_MaskedStencil2FailOp] + ZFail [_MaskedStencil2ZFailOp] + //endex + + //ifex _Stencil2Type==0 + CompBack [_MaskedStencil2BackCompareFunction] + PassBack [_MaskedStencil2BackPassOp] + FailBack [_MaskedStencil2BackFailOp] + ZFailBack [_MaskedStencil2BackZFailOp] + + CompFront [_MaskedStencil2FrontCompareFunction] + PassFront [_MaskedStencil2FrontPassOp] + FailFront [_MaskedStencil2FrontFailOp] + ZFailFront [_MaskedStencil2FrontZFailOp] + //endex + } + + CGPROGRAM + #pragma target 5.0 + #pragma multi_compile_instancing + #pragma vertex vert + #pragma fragment frag + + #define MASKED_STENCIL2_PASS + + #include "2ner.cginc" + ENDCG + } + //endex + //ifex _Masked_Stencil3_Enabled==0 + Pass { + Name "MASKEDSTENCIL3" + Tags { "LightMode" = "ForwardBase" } + //BlendOp [_BlendOp], [_BlendOpAlpha] + //Blend [_SrcBlend] [_DstBlend], [_SrcBlendAlpha] [_DstBlendAlpha] + //Cull [_Cull] + ZWrite Off + ZTest LEqual + + Stencil + { + Ref [_MaskedStencil3Ref] + ReadMask [_MaskedStencil3ReadMask] + WriteMask [_MaskedStencil3WriteMask] + //ifex _Stencil3Type==1 + Comp [_MaskedStencil3CompareFunction] + Pass [_MaskedStencil3PassOp] + Fail [_MaskedStencil3FailOp] + ZFail [_MaskedStencil3ZFailOp] + //endex + + //ifex _Stencil3Type==0 + CompBack [_MaskedStencil3BackCompareFunction] + PassBack [_MaskedStencil3BackPassOp] + FailBack [_MaskedStencil3BackFailOp] + ZFailBack [_MaskedStencil3BackZFailOp] + + CompFront [_MaskedStencil3FrontCompareFunction] + PassFront [_MaskedStencil3FrontPassOp] + FailFront [_MaskedStencil3FrontFailOp] + ZFailFront [_MaskedStencil3FrontZFailOp] + //endex + } + + CGPROGRAM + #pragma target 5.0 + #pragma multi_compile_instancing + #pragma vertex vert + #pragma fragment frag + + #define MASKED_STENCIL3_PASS + + #include "2ner.cginc" + ENDCG + } + //endex + //ifex _Masked_Stencil4_Enabled==0 + Pass { + Name "MASKEDSTENCIL4" + Tags { "LightMode" = "ForwardBase" } + //BlendOp [_BlendOp], [_BlendOpAlpha] + //Blend [_SrcBlend] [_DstBlend], [_SrcBlendAlpha] [_DstBlendAlpha] + //Cull [_Cull] + ZWrite Off + ZTest LEqual + + Stencil + { + Ref [_MaskedStencil4Ref] + ReadMask [_MaskedStencil4ReadMask] + WriteMask [_MaskedStencil4WriteMask] + //ifex _Stencil4Type==1 + Comp [_MaskedStencil4CompareFunction] + Pass [_MaskedStencil4PassOp] + Fail [_MaskedStencil4FailOp] + ZFail [_MaskedStencil4ZFailOp] + //endex + + //ifex _Stencil4Type==0 + CompBack [_MaskedStencil4BackCompareFunction] + PassBack [_MaskedStencil4BackPassOp] + FailBack [_MaskedStencil4BackFailOp] + ZFailBack [_MaskedStencil4BackZFailOp] + + CompFront [_MaskedStencil4FrontCompareFunction] + PassFront [_MaskedStencil4FrontPassOp] + FailFront [_MaskedStencil4FrontFailOp] + ZFailFront [_MaskedStencil4FrontZFailOp] //endex } @@ -539,7 +797,7 @@ Shader "yum_food/2ner" #pragma vertex vert #pragma fragment frag - #define MASKED_STENCIL_PASS + #define MASKED_STENCIL4_PASS #include "2ner.cginc" ENDCG diff --git a/features.cginc b/features.cginc index 4c818f8..3635f7a 100644 --- a/features.cginc +++ b/features.cginc @@ -99,5 +99,21 @@ #pragma shader_feature_local _FOCAL_LENGTH_CONTROL //endex +//ifex _Glitter_Enabled==0 +#pragma shader_feature_local _GLITTER +//endex + +//ifex _Glitter_Emission_Enabled==0 +#pragma shader_feature_local _GLITTER_EMISSION +//endex + +//ifex _Glitter_Angle_Limit_Enabled==0 +#pragma shader_feature_local _GLITTER_ANGLE_LIMIT +//endex + +//ifex _Glitter_Mask_Enabled==0 +#pragma shader_feature_local _GLITTER_MASK +//endex + #endif // __FEATURES_INC diff --git a/glitter.cginc b/glitter.cginc new file mode 100644 index 0000000..2f7a796 --- /dev/null +++ b/glitter.cginc @@ -0,0 +1,87 @@ +#ifndef __GLITTER_INC +#define __GLITTER_INC + +#include "math.cginc" +#include "pema99.cginc" +#include "quilez.cginc" + +struct GlitterParams { + float4 color; + float layers; + float cell_size; + float size; + float major_minor_ratio; + float angle_randomization_range; + float center_randomization_range; + float size_randomization_range; + float existence_chance; +#if defined(_GLITTER_ANGLE_LIMIT) + float angle_limit; + float angle_limit_transition_width; +#endif +#if defined(_GLITTER_MASK) + float mask; +#endif +}; + +static const float2 glitter_offset_vectors[6] = { + float2(0.0, 1.0), // 0 degrees + float2(0.866025, 0.5), // 60 degrees + float2(0.866025, -0.5), // 120 degrees + float2(0.0, -1.0), // 180 degrees + float2(-0.866025, -0.5), // 240 degrees + float2(-0.866025, 0.5) // 300 degrees +}; + + +float4 getGlitter(v2f i, GlitterParams params, float3 normal) { + float c_acc = 0; + [loop] + for (uint layer_i = 0; layer_i < params.layers; layer_i++) { + float2 p = i.uv01.xy + glitter_offset_vectors[layer_i] * params.cell_size * 0.5; + + float3 cell_id = float3(floor(p / params.cell_size), layer_i); + float cell_rand = rand3(cell_id*.0001); + float cell_rand2 = rand3((cell_id+1)*.0001); + p = glsl_mod(p, params.cell_size); + p -= params.cell_size * 0.5; + // Apply center randomization + p.x += (cell_rand * 2 - 1) * params.center_randomization_range * (params.cell_size * (1 - params.size)) * 0.5; + // Apply angle randomization + float2x2 p_rot = float2x2( + cos(cell_rand * TAU * params.angle_randomization_range), -sin(cell_rand * TAU * params.angle_randomization_range), + sin(cell_rand * TAU * params.angle_randomization_range), cos(cell_rand * TAU * params.angle_randomization_range) + ); + p = mul(p_rot, p); + + // Draw ellipses + // First arg is position to evaluate distance at. We project onto z=0. + // Second arg is the size of the ellipse. We set z to cell size because I + // think setting it to 0 would probably create fucked up curvature. + float3 size = float3(params.size * float2(params.major_minor_ratio, 1) * params.cell_size * 0.5, params.cell_size); + // Apply size randomization + size *= (1 - cell_rand * params.size_randomization_range); + // TODO find a good 2d ellipse sdf + float d = distance_from_ellipsoid(float3(p, 0), size); + // TODO antialias using fwidth + float c = (d < 0) * params.color.a; + c *= (cell_rand2 < params.existence_chance); + c_acc = c + (1 - c) * c_acc; + } +#if defined(_GLITTER_ANGLE_LIMIT) + float VdotN = dot(-i.eyeVec.xyz, normal); + float angle_mask = smoothstep( + cos(params.angle_limit * PI), + cos(params.angle_limit * (1 - params.angle_limit_transition_width) * PI), + VdotN); + c_acc *= angle_mask; +#endif +#if defined(_GLITTER_MASK) + c_acc *= params.mask; +#endif + return float4(params.color.rgb, c_acc); +} + +#endif // __GLITTER_INC + + diff --git a/globals.cginc b/globals.cginc index d86620b..6a42a32 100644 --- a/globals.cginc +++ b/globals.cginc @@ -73,6 +73,7 @@ float4 _Outline_Color; float _Outline_Width; #if defined(_OUTLINE_MASK) texture2D _Outline_Mask; +float _Outline_Mask_Invert; #endif #endif @@ -206,16 +207,21 @@ float4 _LTCGI_SpecularColor; float4 _LTCGI_DiffuseColor; #endif // _LTCGI -#if defined(MASKED_STENCIL_PASS) -texture2D _Masked_Stencil_Mask; -float _Masked_Stencil_Ref; -float _Masked_Stencil_Read_Mask; -float _Masked_Stencil_Write_Mask; -float _Masked_Stencil_Compare_Function; -float _Masked_Stencil_Pass_Op; -float _Masked_Stencil_Fail_Op; -float _Masked_Stencil_Z_Fail_Op; -#endif // MASKED_STENCIL_PASS +#if defined(MASKED_STENCIL1_PASS) +texture2D _Masked_Stencil1_Mask; +#endif // MASKED_STENCIL1_PASS + +#if defined(MASKED_STENCIL2_PASS) +texture2D _Masked_Stencil2_Mask; +#endif // MASKED_STENCIL2_PASS + +#if defined(MASKED_STENCIL3_PASS) +texture2D _Masked_Stencil3_Mask; +#endif // MASKED_STENCIL3_PASS + +#if defined(MASKED_STENCIL4_PASS) +texture2D _Masked_Stencil4_Mask; +#endif // MASKED_STENCIL4_PASS #if defined(EXTRA_STENCIL_COLOR_PASS) float4 _ExtraStencilColor; @@ -226,4 +232,24 @@ float _Focal_Length_Enabled_Dynamic; float _Focal_Length_Multiplier; #endif // _FOCAL_LENGTH_CONTROL +#if defined(_GLITTER) +float4 _Glitter_Color; +float3 _Glitter_Emission; +float _Glitter_Layers; +float _Glitter_Grid_Size; +float _Glitter_Size; +float _Glitter_Major_Minor_Ratio; +float _Glitter_Angle_Randomization_Range; +float _Glitter_Center_Randomization_Range; +float _Glitter_Size_Randomization_Range; +float _Glitter_Existence_Chance; +#if defined(_GLITTER_ANGLE_LIMIT) +float _Glitter_Angle_Limit; +float _Glitter_Angle_Limit_Transition_Width; +#endif // _GLITTER_ANGLE_LIMIT +#if defined(_GLITTER_MASK) +texture2D _Glitter_Mask; +#endif // _GLITTER_MASK +#endif // _GLITTER + #endif // __GLOBALS_INC diff --git a/math.cginc b/math.cginc index f3af30a..85fe4ea 100644 --- a/math.cginc +++ b/math.cginc @@ -5,7 +5,9 @@ #define PI 3.14159265358979323846264 #define TAU (2 * PI) +#define HALF_PI (PI * 0.5) #define PHI 1.618033989 +#define SQRT_2_RCP 0.707106781 float pow5(float x) { @@ -175,6 +177,13 @@ void domainWarp3Normals(inout float3 normal, inout float3 tangent, float3 basePo tangent = normalize(mul(J, tangent)); } +// Alpha blend `dst` onto `src`. +// Imagine two transparent planes. We're rendering a situation where you're +// looking through `front` at `behind`. +float4 alphaBlend(float4 behind, float4 front) { + return float4(front.rgb * front.a + behind.rgb * (1 - front.a), front.a + behind.a * (1 - front.a)); +} + #endif // __MATH_INC diff --git a/quilez.cginc b/quilez.cginc index e478db1..c9ac477 100644 --- a/quilez.cginc +++ b/quilez.cginc @@ -147,6 +147,14 @@ float distance_from_capsule(float3 p, float3 a, float3 b, float r) return length( pa - ba*h ) - r; } +// https://iquilezles.org/articles/ellipsoids/ +float distance_from_ellipsoid(float3 p, float3 r) +{ + float k1 = length(p/r); + float k2 = length(p/(r*r)); + return k1*(k1-1.0)/k2; +} + /* float sdHexPrism( vec3 p, vec2 h ) { diff --git a/yum_pbr.cginc b/yum_pbr.cginc index a01bc63..ce1c411 100644 --- a/yum_pbr.cginc +++ b/yum_pbr.cginc @@ -3,6 +3,7 @@ #include "features.cginc" #include "filamented.cginc" +#include "glitter.cginc" #include "globals.cginc" #include "math.cginc" #include "texture_utils.cginc" @@ -10,7 +11,7 @@ struct YumPbr { float4 albedo; float3 normal; -#if defined(_EMISSION) +#if defined(_EMISSION) || (defined(_GLITTER) && defined(FORWARD_BASE_PASS)) float3 emission; #endif float smoothness; @@ -38,20 +39,51 @@ YumPbr GetYumPbr(v2f i) { UV_SCOFF(i, _MainTex_ST, /*which_channel=*/0)) * _Color; #endif -#if defined(_ALPHA_MULTIPLIER) - result.albedo.a = saturate(result.albedo.a * _Alpha_Multiplier); -#endif - float3 normal_raw = UnpackScaleNormal( tex2D(_BumpMap, UV_SCOFF(i, _BumpMap_ST, /*which_channel=*/0)), _BumpScale); float3x3 tangentToWorld = float3x3(i.tangent, i.binormal, i.normal); result.normal = normalize(mul(normal_raw, tangentToWorld)); +#if defined(FORWARD_BASE_PASS) && defined(_GLITTER) + GlitterParams glitter_p; + glitter_p.color = _Glitter_Color; + glitter_p.layers = _Glitter_Layers; + glitter_p.cell_size = _Glitter_Grid_Size; + glitter_p.size = _Glitter_Size; + glitter_p.major_minor_ratio = _Glitter_Major_Minor_Ratio; + glitter_p.angle_randomization_range = _Glitter_Angle_Randomization_Range; + glitter_p.center_randomization_range = _Glitter_Center_Randomization_Range; + glitter_p.size_randomization_range = _Glitter_Size_Randomization_Range; + glitter_p.existence_chance = _Glitter_Existence_Chance; +#if defined(_GLITTER_ANGLE_LIMIT) + glitter_p.angle_limit = _Glitter_Angle_Limit; + glitter_p.angle_limit_transition_width = _Glitter_Angle_Limit_Transition_Width; +#endif +#if defined(_GLITTER_MASK) + glitter_p.mask = _Glitter_Mask.SampleLevel(linear_repeat_s, i.uv01.xy, 0); +#endif + float4 glitter_albedo = getGlitter(i, glitter_p, result.normal); + result.albedo = alphaBlend(result.albedo, glitter_albedo); +#endif + +#if defined(_ALPHA_MULTIPLIER) + result.albedo.a = saturate(result.albedo.a * _Alpha_Multiplier); +#endif + #if defined(_EMISSION) result.emission = tex2D(_EmissionMap, UV_SCOFF(i, _EmissionMap_ST, /*which_channel=*/0)) * _EmissionColor; #endif +#if defined(FORWARD_BASE_PASS) && defined(_GLITTER) + float3 gitter_emission = glitter_albedo.rgb * glitter_albedo.a * _Glitter_Emission; +#if defined(_EMISSION) + result.emission += gitter_emission; +#else + result.emission = gitter_emission; +#endif +#endif + #if defined(_METALLICS) float4 metallic_gloss = tex2D(_MetallicGlossMap, UV_SCOFF(i, _MetallicGlossMap_ST, /*which_channel=*/0)); float metallic = metallic_gloss.r * _Metallic; -- cgit v1.2.3