Shader-Properties not animating when using stencil mask

Hi, I recently made a shader with shader graph and stumbled across the problem, that it can not be used as a UI component , since the Unity Mask isn’t working anymore.

I thought I fixed the problem by adding Stencil properties and stuff to the raw shader code as you can see in my post linked above. However, I just found out, that the shader properties won’t animate anymore when masked, and I’m completely lost how this can be?

Take a look:
yvscl8
As you can see the shader seems to be frozen in time, when I turn on the Mask component in the parent object.

Here is the shader code:

Shader "2DGlow"
{
    Properties
    {
        [NoScaleOffset]_MainTex("MainTex", 2D) = "white" {}
        _GlowIntensity("Glow Intensity", Range(0, 1)) = 0
        [NonModifiableTextureData][NoScaleOffset]_SampleTexture2D_D69F3F9D_Texture_1("Texture2D", 2D) = "white" {}
 
        // Added to make it work with Unity Masks:
        _StencilComp ("Stencil Comparison", Float) = 8
        _Stencil ("Stencil ID", Float) = 0
        _StencilOp ("Stencil Operation", Float) = 0
        _StencilWriteMask ("Stencil Write Mask", Float) = 255
        _StencilReadMask ("Stencil Read Mask", Float) = 255
        _ColorMask ("Color Mask", Float) = 15
        // end
    }
    SubShader
    {
        Tags
        {
            "RenderPipeline"="UniversalPipeline"
            "RenderType"="Transparent"
            "Queue"="Transparent+0"
        }
    
        // Added to make it work with Unity Masks:
        Stencil
        {
            Ref [_Stencil]
            Comp [_StencilComp]
            Pass [_StencilOp]
            ReadMask [_StencilReadMask]
            WriteMask [_StencilWriteMask]
        }
    
        ColorMask [_ColorMask]
        // end
    
        Pass
        {
            // Render State
            Blend SrcAlpha OneMinusSrcAlpha, One OneMinusSrcAlpha
            Cull Off
            ZTest LEqual
            ZWrite Off
            // ColorMask: <None>
    
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
    
            // --------------------------------------------------
            // Pass
    
            // Pragmas
            #pragma prefer_hlslcc gles
            #pragma exclude_renderers d3d11_9x
            #pragma target 2.0
    
            // Keywords
            #pragma multi_compile _ ETC1_EXTERNAL_ALPHA
            // GraphKeywords: <None>
        
            // Defines
            #define _SURFACE_TYPE_TRANSPARENT 1
            #define ATTRIBUTES_NEED_NORMAL
            #define ATTRIBUTES_NEED_TANGENT
            #define ATTRIBUTES_NEED_TEXCOORD0
            #define ATTRIBUTES_NEED_COLOR
            #define VARYINGS_NEED_TEXCOORD0
            #define VARYINGS_NEED_COLOR
            #define SHADERPASS_SPRITEUNLIT
    
            // Includes
            #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl"
    
            // --------------------------------------------------
            // Graph
    
            // Graph Properties
            CBUFFER_START(UnityPerMaterial)
            float _GlowIntensity;
            CBUFFER_END
            TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); float4 _MainTex_TexelSize;
            SAMPLER(_SampleTexture2D_E430CDDC_Sampler_3_Linear_Repeat);
            TEXTURE2D(_SampleTexture2D_D69F3F9D_Texture_1); SAMPLER(sampler_SampleTexture2D_D69F3F9D_Texture_1); float4 _SampleTexture2D_D69F3F9D_Texture_1_TexelSize;
            SAMPLER(_SampleTexture2D_D69F3F9D_Sampler_3_Linear_Repeat);
    
            // Graph Functions
        
            void Unity_Remap_float(float In, float2 InMinMax, float2 OutMinMax, out float Out)
            {
                Out = OutMinMax.x + (In - InMinMax.x) * (OutMinMax.y - OutMinMax.x) / (InMinMax.y - InMinMax.x);
            }
        
            void Unity_Multiply_float(float A, float B, out float Out)
            {
                Out = A * B;
            }
        
            void Unity_Combine_float(float R, float G, float B, float A, out float4 RGBA, out float3 RGB, out float2 RG)
            {
                RGBA = float4(R, G, B, A);
                RGB = float3(R, G, B);
                RG = float2(R, G);
            }
        
            void Unity_Add_float4(float4 A, float4 B, out float4 Out)
            {
                Out = A + B;
            }
    
            // Graph Vertex
            // GraphVertex: <None>
        
            // Graph Pixel
            struct SurfaceDescriptionInputs
            {
                float4 uv0;
            };
        
            struct SurfaceDescription
            {
                float4 Color;
            };
        
            SurfaceDescription SurfaceDescriptionFunction(SurfaceDescriptionInputs IN)
            {
                SurfaceDescription surface = (SurfaceDescription)0;
                float4 _SampleTexture2D_E430CDDC_RGBA_0 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uv0.xy);
                float _SampleTexture2D_E430CDDC_R_4 = _SampleTexture2D_E430CDDC_RGBA_0.r;
                float _SampleTexture2D_E430CDDC_G_5 = _SampleTexture2D_E430CDDC_RGBA_0.g;
                float _SampleTexture2D_E430CDDC_B_6 = _SampleTexture2D_E430CDDC_RGBA_0.b;
                float _SampleTexture2D_E430CDDC_A_7 = _SampleTexture2D_E430CDDC_RGBA_0.a;
                float _Property_1A4E7584_Out_0 = _GlowIntensity;
                float _Remap_C6250819_Out_3;
                Unity_Remap_float(_Property_1A4E7584_Out_0, float2 (0, 1), float2 (1, 2), _Remap_C6250819_Out_3);
                float _Multiply_E38790AD_Out_2;
                Unity_Multiply_float(_SampleTexture2D_E430CDDC_R_4, _Remap_C6250819_Out_3, _Multiply_E38790AD_Out_2);
                float _Multiply_C56E1A7_Out_2;
                Unity_Multiply_float(_SampleTexture2D_E430CDDC_G_5, _Remap_C6250819_Out_3, _Multiply_C56E1A7_Out_2);
                float _Multiply_EBC221C4_Out_2;
                Unity_Multiply_float(_SampleTexture2D_E430CDDC_B_6, _Remap_C6250819_Out_3, _Multiply_EBC221C4_Out_2);
                float4 _Combine_38C0EFDE_RGBA_4;
                float3 _Combine_38C0EFDE_RGB_5;
                float2 _Combine_38C0EFDE_RG_6;
                Unity_Combine_float(_Multiply_E38790AD_Out_2, _Multiply_C56E1A7_Out_2, _Multiply_EBC221C4_Out_2, _SampleTexture2D_E430CDDC_A_7, _Combine_38C0EFDE_RGBA_4, _Combine_38C0EFDE_RGB_5, _Combine_38C0EFDE_RG_6);
                float4 _SampleTexture2D_D69F3F9D_RGBA_0 = SAMPLE_TEXTURE2D(_SampleTexture2D_D69F3F9D_Texture_1, sampler_SampleTexture2D_D69F3F9D_Texture_1, IN.uv0.xy);
                float _SampleTexture2D_D69F3F9D_R_4 = _SampleTexture2D_D69F3F9D_RGBA_0.r;
                float _SampleTexture2D_D69F3F9D_G_5 = _SampleTexture2D_D69F3F9D_RGBA_0.g;
                float _SampleTexture2D_D69F3F9D_B_6 = _SampleTexture2D_D69F3F9D_RGBA_0.b;
                float _SampleTexture2D_D69F3F9D_A_7 = _SampleTexture2D_D69F3F9D_RGBA_0.a;
                float _Multiply_DE6F6CD6_Out_2;
                Unity_Multiply_float(_SampleTexture2D_D69F3F9D_R_4, _Property_1A4E7584_Out_0, _Multiply_DE6F6CD6_Out_2);
                float _Multiply_C07DAB61_Out_2;
                Unity_Multiply_float(_SampleTexture2D_D69F3F9D_G_5, _Property_1A4E7584_Out_0, _Multiply_C07DAB61_Out_2);
                float _Multiply_83A1ADD1_Out_2;
                Unity_Multiply_float(_SampleTexture2D_D69F3F9D_B_6, _Property_1A4E7584_Out_0, _Multiply_83A1ADD1_Out_2);
                float _Multiply_DE613504_Out_2;
                Unity_Multiply_float(_SampleTexture2D_E430CDDC_A_7, _Property_1A4E7584_Out_0, _Multiply_DE613504_Out_2);
                float4 _Combine_83894105_RGBA_4;
                float3 _Combine_83894105_RGB_5;
                float2 _Combine_83894105_RG_6;
                Unity_Combine_float(_Multiply_DE6F6CD6_Out_2, _Multiply_C07DAB61_Out_2, _Multiply_83A1ADD1_Out_2, _Multiply_DE613504_Out_2, _Combine_83894105_RGBA_4, _Combine_83894105_RGB_5, _Combine_83894105_RG_6);
                float4 _Add_EAB34B46_Out_2;
                Unity_Add_float4(_Combine_38C0EFDE_RGBA_4, _Combine_83894105_RGBA_4, _Add_EAB34B46_Out_2);
                surface.Color = _Add_EAB34B46_Out_2;
                return surface;
            }
    
            // --------------------------------------------------
            // Structs and Packing
    
            // Generated Type: Attributes
            struct Attributes
            {
                float3 positionOS : POSITION;
                float3 normalOS : NORMAL;
                float4 tangentOS : TANGENT;
                float4 uv0 : TEXCOORD0;
                float4 color : COLOR;
                #if UNITY_ANY_INSTANCING_ENABLED
                uint instanceID : INSTANCEID_SEMANTIC;
                #endif
            };
    
            // Generated Type: Varyings
            struct Varyings
            {
                float4 positionCS : SV_POSITION;
                float4 texCoord0;
                float4 color;
                #if UNITY_ANY_INSTANCING_ENABLED
                uint instanceID : CUSTOM_INSTANCE_ID;
                #endif
                #if (defined(UNITY_STEREO_INSTANCING_ENABLED))
                uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;
                #endif
                #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))
                uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;
                #endif
                #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)
                FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;
                #endif
            };
        
            // Generated Type: PackedVaryings
            struct PackedVaryings
            {
                float4 positionCS : SV_POSITION;
                #if UNITY_ANY_INSTANCING_ENABLED
                uint instanceID : CUSTOM_INSTANCE_ID;
                #endif
                float4 interp00 : TEXCOORD0;
                float4 interp01 : TEXCOORD1;
                #if (defined(UNITY_STEREO_INSTANCING_ENABLED))
                uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;
                #endif
                #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))
                uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;
                #endif
                #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)
                FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;
                #endif
            };
        
            // Packed Type: Varyings
            PackedVaryings PackVaryings(Varyings input)
            {
                PackedVaryings output = (PackedVaryings)0;
                output.positionCS = input.positionCS;
                output.interp00.xyzw = input.texCoord0;
                output.interp01.xyzw = input.color;
                #if UNITY_ANY_INSTANCING_ENABLED
                output.instanceID = input.instanceID;
                #endif
                #if (defined(UNITY_STEREO_INSTANCING_ENABLED))
                output.stereoTargetEyeIndexAsRTArrayIdx = input.stereoTargetEyeIndexAsRTArrayIdx;
                #endif
                #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))
                output.stereoTargetEyeIndexAsBlendIdx0 = input.stereoTargetEyeIndexAsBlendIdx0;
                #endif
                #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)
                output.cullFace = input.cullFace;
                #endif
                return output;
            }
        
            // Unpacked Type: Varyings
            Varyings UnpackVaryings(PackedVaryings input)
            {
                Varyings output = (Varyings)0;
                output.positionCS = input.positionCS;
                output.texCoord0 = input.interp00.xyzw;
                output.color = input.interp01.xyzw;
                #if UNITY_ANY_INSTANCING_ENABLED
                output.instanceID = input.instanceID;
                #endif
                #if (defined(UNITY_STEREO_INSTANCING_ENABLED))
                output.stereoTargetEyeIndexAsRTArrayIdx = input.stereoTargetEyeIndexAsRTArrayIdx;
                #endif
                #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))
                output.stereoTargetEyeIndexAsBlendIdx0 = input.stereoTargetEyeIndexAsBlendIdx0;
                #endif
                #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)
                output.cullFace = input.cullFace;
                #endif
                return output;
            }
    
            // --------------------------------------------------
            // Build Graph Inputs
    
            SurfaceDescriptionInputs BuildSurfaceDescriptionInputs(Varyings input)
            {
                SurfaceDescriptionInputs output;
                ZERO_INITIALIZE(SurfaceDescriptionInputs, output);
        
        
        
        
        
                output.uv0 =                         input.texCoord0;
            #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)
            #define BUILD_SURFACE_DESCRIPTION_INPUTS_OUTPUT_FACESIGN output.FaceSign =                    IS_FRONT_VFACE(input.cullFace, true, false);
            #else
            #define BUILD_SURFACE_DESCRIPTION_INPUTS_OUTPUT_FACESIGN
            #endif
            #undef BUILD_SURFACE_DESCRIPTION_INPUTS_OUTPUT_FACESIGN
        
                return output;
            }
        
    
            // --------------------------------------------------
            // Main
    
            #include "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Varyings.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/SpriteUnlitPass.hlsl"
    
            ENDHLSL
        }
    
    }
    FallBack "Hidden/Shader Graph/FallbackError"
}

And this is how I animate it:

        public static void Glow(this Image img, float duration = 2f, float intensity = .5f, Ease ease = Ease.OutQuad,
            int loops = 2, LoopType loopType = LoopType.Yoyo)
        {
            Material originalMaterial = img.material;
            img.material = GlowMaterial;
        
            int glowIntensityProperty = Shader.PropertyToID("_GlowIntensity");

            duration /= 2;
            float tmp = 0;
                DOTween.To(() => tmp, x => tmp = x, intensity, duration)
                .SetEase(ease)
                .SetLoops(loops, loopType)
                .OnUpdate(() => { img.material.SetFloat(glowIntensityProperty, tmp); })
                .OnComplete(() =>
                {
                    img.material = originalMaterial;
                });
        }

I guess I need a real pro here, any yep – I know, shader graph is creating a lot of unnecessary things, but I’m not enough into shader programming to remove stuff and really know what I’m doing :frowning:

I hope there is a soul out there that can help! :s

3 Likes

First findings:
if I observe the img.material for the animated float by calling img.materialForRendering.GetFloat("_GlowIntensity"), I can see that the float is properly animating, even though the rendered object is not (as seen in the video).

However if I do the same with img.materialForRendering I can see the exact behaviour as on screen. The value is frozen whenever I activate the Mask component!
But how can this be? I don’t understand :frowning:

2 Likes

Solve:
I ended up setting the float on the materialForRendering even though the docs states that it’s readonly

So my shader animation script now does this:
img.materialForRendering.SetFloat(glowIntensityProperty, tmp);

2 Likes

THANK YOU! I needed this so badly so now I can officially animate shaders while having it crop during scrollview!

Thank you so much.

Cheers! Worked for me. Gave my shader an Alpha Threshold, doesn’t really update outside of playmode, so had to do what NoBlauch mentioned in their last message there to see the Alpha Clipping update in play mode.
Saying that as a heads up to others to not be immediately discouraged if it’s not working right away, test in play mode!