#Hey all! I'm currently trying to use a

1 messages · Page 1 of 1 (latest)

tight pewter
#
public class LightMaskBlurPass : ScriptableRenderPass // Initial Pass that will sample Tilemap Layer as Texture, and Light Texture and returned the masked value.
    {
        private List<ShaderTagId> shaderTagsList = new List<ShaderTagId>();

        private FilteringSettings filteringSettings;
        private ProfilingSampler _profilingSampler;

        public RTHandle RT_LightMask;
        public RTHandle RT_BlurredLight;

        private LightSettings settings;

        public LightMaskBlurPass(LightSettings settings, string name) // PASS "CONSTRUCTOR"
        {
            this.settings = settings;

            filteringSettings = new FilteringSettings(RenderQueueRange.all, settings.layerMask);

            Debug.Log(LayerMask.LayerToName(settings.layerMask));

            shaderTagsList.Add(new ShaderTagId("Universal2D"));
            //shaderTagsList.Add(new ShaderTagId("SRPDefaultUnlit"));
            shaderTagsList.Add(new ShaderTagId("UniversalForward"));

            _profilingSampler = new ProfilingSampler(name);
        }

        public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
        {
            var colorDesc = renderingData.cameraData.cameraTargetDescriptor;
            colorDesc.depthBufferBits = 0;
            colorDesc.width /= settings.downsample;
            colorDesc.height /= settings.downsample;

            var colorDesc2 = renderingData.cameraData.cameraTargetDescriptor;
            colorDesc2.depthBufferBits = 0;

            RenderingUtils.ReAllocateIfNeeded(ref RT_LightMask, colorDesc, name: "RT_LightMask");
            RenderingUtils.ReAllocateIfNeeded(ref RT_BlurredLight, colorDesc, name: "RT_BlurredLight");

            ConfigureTarget(RT_LightMask);
            ConfigureClear(ClearFlag.Color, Color.black);
        }
        // Draw the mask of our "Ground" tag to our "RT_GroundMask".
        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {
            CommandBuffer cmd = CommandBufferPool.Get();
            using (new ProfilingScope(cmd, _profilingSampler))
            {
                context.ExecuteCommandBuffer(cmd);
                cmd.Clear();

                SortingCriteria sortingCriteria = SortingCriteria.CommonTransparent;
                DrawingSettings drawingSettings = CreateDrawingSettings(shaderTagsList, ref renderingData, sortingCriteria);

                // draw output of lightMaskMAT to rtMaskedLightTexture ?
                Blit(cmd, RT_LightMask, RT_LightMask, settings.lightMaskMAT, 0);

                settings.GaussianBlurShaderMAT.SetTexture("_MainTex", RT_LightMask);

                Blit(cmd, RT_LightMask, RT_BlurredLight, settings.GaussianBlurShaderMAT, 0);

                cmd.SetGlobalTexture("RT_LightMask_GLOBAL", RT_LightMask);

                cmd.SetGlobalTexture("RT_BlurredLight_GLOBAL", RT_BlurredLight);
            }
            context.ExecuteCommandBuffer(cmd);
            cmd.Clear();
            CommandBufferPool.Release(cmd);
        }
        public override void OnCameraCleanup(CommandBuffer cmd) { }
    }

    #endregion

    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
        renderer.EnqueuePass(P_GroundMask);
        //renderer.EnqueuePass(P_LightMask);
        renderer.EnqueuePass(P_LightMaskBlur);
    }
proper bison
#

First thing I'd guess is the vertex program used by the shader might not suitable for the Blit() call used by the renderer feature, which uses the Blitter API internally to draw a triangle.
That triangle only becomes a "fullscreen triangle" with a particular vertex shader, like the Vert one in the Blit.hlsl include file

#

Pass should also use ZWrite Off ZTest Always Blend Off Cull Off to avoid any other issues

tight pewter
#

Ahh, I see! I'm still learning how to actually write/understand HLSL shaders, is there anything in particular I should be changing in the shader itself to allow it to work with a Blit call?

#
Shader "GaussianBlur"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
        _Spread("Standard Deviation (Spread)", Float) = 0
        _GridSize("Grid Size", Integer) = 1
    }
    SubShader
    {
         Tags
         {
              "RenderType" = "Opaque"
              "RenderPipeline" = "UniversalPipeline"
         }

        HLSLINCLUDE

        #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
        #define E 2.71828f

        sampler2D _MainTex;

        CBUFFER_START(UnityPerMaterial)
            float4 _MainTex_TexelSize;
            uint _GridSize;
            float _Spread;
        CBUFFER_END

        float gaussian(int x)
        {
            float sigmaSqu = _Spread * _Spread;
           return (1 / sqrt(TWO_PI * sigmaSqu)) * pow(E, -(x * x) / (2 * sigmaSqu));
        }
        
        struct appdata
        {
          float4 positionOS : Position;
           float2 uv : TEXCOORD0;
        };

        struct v2f
        {
            float4 positionCS : SV_Position;
            float2 uv : TEXCOORD0;
        };

        v2f vert(appdata v)
        {
            v2f o;
            o.positionCS = TransformObjectToHClip(v.positionOS.xyz);
            o.uv = v.uv;
            return o;
        }

        ENDHLSL

        Pass
        {
            Name "Horizontal"

            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag_horizontal

            float4 frag_horizontal(v2f i) : SV_Target
            {
                float3 col = float3(0.0f, 0.0f, 0.0f);
                float gridSum = 0.0f;

                int upper = ((_GridSize - 1) / 2);
                int lower = -upper;

                for (int x = lower; x <= upper; ++x)
                {
                    float gauss = gaussian(x);
                    gridSum += gauss;
                    float2 uv = i.uv + float2(_MainTex_TexelSize.x * x, 0.0f);
                    col += gauss * tex2D(_MainTex, uv).xyz;
                }

                col /= gridSum;
                return float4(col, 1.0f);
            }

            ENDHLSL
        }
        Pass
        {
            Name "Vertical"

            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag_horizontal

            float4 frag_horizontal(v2f i) : SV_Target
            {
                float3 col = float3(0.0f, 0.0f, 0.0f);
                float gridSum = 0.0f;

                int upper = ((_GridSize - 1) / 2);
                int lower = -upper;

                for (int y = lower; y <= upper; ++y)
                {
                    float gauss = gaussian(y);
                    gridSum += gauss;
                    float2 uv = i.uv + float2(_MainTex_TexelSize.y * y, 0.0f);
                    col += gauss * tex2D(_MainTex, uv).xyz;
                }

                col /= gridSum;
                return float4(col, 1.0f);
            }

            ENDHLSL
        }
    }
}
proper bison
#

Mostly just that vertex shader in the include file I mentioned. It avoids using the typical World->Clip space transformations (via model, view and projection matrices), instead outputting specific vertex postions based on the vertex ID

tight pewter
#

Okay sure, I'll look into it!

tight pewter
proper bison
#

e.g.

Pass {
ZWrite Off ZTest Always Blend Off Cull Off
Name "Horizontal"
HLSLPROGRAM

and similarly for the Vertical
You might also be able to put it inside SubShader and it'll automatically use that for all passes, not sure though.

tight pewter
tight pewter
# tight pewter ```c Shader "GaussianBlur" { Properties { _MainTex("Texture", 2D...

Nothing really visibly happened as likely expected, but I still am yet to get this to "work" as a fullscreen shader to work with a blit, is there something I need to do directly with the shader code itself to render to a fullscreen texture to be compatible with the blit? Or is there some way to create a "Fullscreen" .shader file in some way?

tight pewter
proper bison
# tight pewter Is there a way to use a different Vertex program in some way? I unfortunately am...

Your current shader uses #pragma vertex vert, with vert() defined in the HLSLINCLUDE block, which includes that code in all passes.
As that shader uses the input positionOS and TransformObjectToHClip it's not suitable for fullscreen drawing when using the Blitter API (which Blit() in feature uses)

You could add

#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"

After the other Core.hlsl include line inside the HLSLPROGRAM, remove the current appdata, v2f and vert function and use #pragma vertex Vert in the passes instead. That Vert is defined in that Blit.hlsl include file.

#

May also need some other changes, like anywhere there is v2f you'd now use Varyings as that's what the include file has named that struct instead

#

i.uv would also be i.texcoord

tight pewter
#

Okay perfect! I'll try all of that, I really appreciate it!

#

Would the fragment portion stay the same? I assume that is a part of Core opposed to the Blit hlsl?

#pragma vertex Vert
#pragma fragment frag_horizontal
proper bison
#

The fragment functions are defined in the pass just below that, but yes they'd stay the same (except for the other minor changes I mentioned above) since they handle the blurring you want

tight pewter
#

it worked!

#

It's blurring properly as expected I believe! Thank you so so so much for your help. That was driving me crazy the past few days haha! You really are a shader legend!

#

I think I understand the way HLSL shaders work a little bit more now, I think troubleshooting in the future is likely to be much easier too!

proper bison
#

Might not be super important, but if you want to understand what that Vert function is doing this is an answer I've given elsewhere :

The renderer feature Blit() function just draws a triangle, it doesn't say where (which is why just using positionOS input doesn't draw anything), only that 3 vertices need to be drawn.
It's the shader that uses the vertex ID to determine the positions of those vertices.
You need to use GetFullScreenTriangleVertexPosition(input.vertexID) resulting in vertices at (-1, -1), (3, -1) and (-1, 3) (clipspace xy)

tight pewter
#

Oh nevermind, the UV that the fullscreen shader doesn't have I assume.

#

Which gives the basic shader vertex data which is required to draw the fragments using it?

proper bison
#

UVs are probably important too but yeah the cmd.DrawProcedural call that the Blitter API ends up using doesn't pass any vertex data

#

Thats why the Vert program uses the vertexID (0, 1 and 2) to calculate the clipspace positions and uv/texcoord

#

The UV is only for mapping the texture though. It didn't even get that far in this case, as the previous vertex shaders didn't end up producing any fragments - as it probably tried to draw the triangle with inputs of (0,0,0), (0,0,0) and (0,0,0)

tight pewter
#

Ahh I see, that makes a lot of sense!

proper bison
#

And the result was only black, because the feature used ConfigureClear(ClearFlag.Color, Color.black);

tight pewter
#

Appreciate the explanation, I am really trying to learn and understand shaders as a whole currently. understanding how to differenciate a fullscreen shader is very very helpful as I typically (in shader graph) would just use it when nothing else was working haha.

tight pewter
#

That is what particularly confused me, but I unfortunately didn't get any response on why that may have been so I assume likely it was a case of needing to restart Unity or something.

proper bison
#

Oh probably because that ConfigureClear would be clearing what is set by ConfigureTarget, which is RT_LightMask in this case, not the Blurred one

tight pewter
# proper bison Ah okay, also not sure why then

Yeah it really was throwing me off, I had initially assumed it was something to do with vertex not actually drawing to my material at all, thus not allowing for anything to be drawn, but since nothing was clearing I was thinking I was maybe creating the RTHandle wrong.

proper bison
#

Probably defaults to black as that's just what the target is initalised as

tight pewter
#

Would that mean the "blank" space on my LightMask should have been blue for example opposed to black?

#

Because I think I had checked that too but I can't remember for sure haha.

proper bison
tight pewter
#

I do think shader graph does give you at-least a decent grasp as to how they work to some degree and I think understanding the basics of that does get me in a decent headspace for it. I'll definitely try to continue learning and trying to understand/write my own HLSL shaders, they seem pretty fun to learn.

tight pewter
# proper bison Your current shader uses `#pragma vertex vert`, with vert() defined in the HLSLI...

Hey, sorry to reopen this but I just had a tiny question related to the new package replacing some of the Core package definitions, while I am doubtful it is related unfortunately my Gaussian blur isn't seeming to draw a vertical pass, and I've tried a few things so I am just wondering if that would be correlated at all? The horizontal is working perfectly fine, but it's clearly not drawing a vertical pass unfortunately. I was just wondering if you'd have any obvious reason as to why that could be, if not that's totally fine! Just trying to cover all my bases haha!

#
Pass
        {
            ZWrite Off ZTest Always Blend Off Cull Off
            Name "Horizontal"

            HLSLPROGRAM
            #pragma vertex Vert
            #pragma fragment frag_horizontal

            float4 frag_horizontal(Varyings i) : SV_Target
            {
                float3 col = float3(0.0f, 0.0f, 0.0f);
                float gridSum = 0.0f;

                int upper = ((_GridSize - 1) / 2);
                int lower = -upper;

                for (int x = lower; x <= upper; ++x)
                {
                    float gauss = gaussian(x);
                    gridSum += gauss;
                    float2 uv = i.texcoord + float2(_MainTex_TexelSize.x * x, 0.0f);
                    col += gauss * tex2D(_MainTex, uv).xyz;
                }

                col /= gridSum;
                return float4(col, 1.0f);
            }

            ENDHLSL
        }
        Pass
        {
            ZWrite Off ZTest Always Blend Off Cull Off
            Name "Vertical"

            HLSLPROGRAM
            #pragma vertex Vert
            #pragma fragment frag_vertical

            float4 frag_vertical(Varyings i) : SV_Target
            {
                float3 col = float3(0.0f, 0.0f, 0.0f);
                float gridSum = 0.0f;

                int upper = ((_GridSize - 1) / 2);
                int lower = -upper;

                for (int y = lower; y <= upper; ++y)
                {
                    float gauss = gaussian(y);
                    gridSum += gauss;
                    float2 uv = i.texcoord + float2(0.0f, _MainTex_TexelSize.y * y);
                    col += gauss * tex2D(_MainTex, uv).xyz;
                }

                col /= gridSum;
                return float4(col, 1.0f);
            }

            ENDHLSL
        }

my initial thought was that my vertical pass was actually incorrectly adjusting the X axis in the

float2 uv = i.texcoord + float2(0.0f, _MainTex_TexelSize.y * y);

line however, even after fixing it to alter the Vertical axis it still is only horizontally blurring unfortunately!

proper bison
#

atm I think the feature is only using pass 0, while it should be calling each pass, something like

Blit(cmd, RT_LightMask, RT_Temp, settings.GaussianBlurShaderMAT, 0);
Blit(cmd, RT_Temp, RT_BlurredLight, settings.GaussianBlurShaderMAT, 1);
tight pewter
#

That would make a ton of sense haha, appreciate your blisteringly fast response!

proper bison
#

Basically yeah. I think if -1 was used it would render all passes, but incorrectly - as the result of the first pass needs to be the input to the second so needs to be done in this way

tight pewter
# proper bison Basically yeah. I think if `-1` was used it would render all passes, but incorre...

Ahh I see! I really appreciate it. One more thing I also recently noticed, and has kind of stumped me I am currently drawing my tilemap to a Texture to then be used as a mask, but since I am also altering the material the tilemap uses, it is actually drawing the shaded result of the tilemap, rather than just the base texture. Would it be better to draw the "shadow" to a full screen volume or something similar instead?

#

While it should just be the grayish area and the black, however unfortunately the "light" is showing through as it's a part of the material.

proper bison
#

Are you using a lit material as the override? Maybe it should be an unlit one

tight pewter
#

One thing I am still noticing is a pretty constant flashing on and off of my material, I assume it's from reallocating the texture every frame, but I am unsure of what the root cause is.

tight pewter
# tight pewter

it seems to happen mostly when something actively happens eg: (moving mouse, scrolling, moving camera etc).

tight pewter
proper bison