#Circular Blur Shader Question

1 messages · Page 1 of 1 (latest)

eternal flower
#

Demonstration of "Single tile" masked light (pre blur)

#

Horizontal Blur Pass Applied (Notice rectangular expansion)

#

Finally Vertical Blur Pass Applied (Final blur pass)

#

Goal // Ideal result (circular/gradual falloff blur)

#

Blur Pass (Horizontal, both use essentially the same script different axis)

#
void HorizontalBlur_float(UnityTexture2D Texture, float2 UV, float Blur, float BlurWeight, UnitySamplerState Sampler, out float3 Out_RGB, out float Out_Alpha)
{
    float4 col = float4(0.0, 0.0, 0.0, 0.0);
    float kernelSum = 0.0;

    float aspectRatioFactor = _MaskedLightTexture_TexelSize.x / _MaskedLightTexture_TexelSize.y;

    float upper = ((Blur - 1) / 2);
    float lower = -upper;

    for (float x = lower; x <= upper; ++x)
    {
        kernelSum += BlurWeight;

        float2 offset = float2(_MaskedLightTexture_TexelSize.x * x, 0.0);
        col += Texture.Sample(Sampler, UV + offset) * BlurWeight;
    }

    col /= kernelSum;

    Out_RGB = float3(col.r, col.g, col.b);
    Out_Alpha = col.a;
}
#

^ The "BlurWeight" doesn't actually affect the blur at all seemingly, still working on that. However, that is my current effective blur shader!

#

^ How the shader currently performs on a semi-realistic scene, as you can probably see it's quite blocky and finnicky!

#

Need to still clamp the light intensity to be 1 at the max as the light values multiply over 1 creating the ugly overly-bright spots.

#

^ How Starbound handles single block lighting, as you can see although there is a single tile-wide light source the effective range is circular, while mine is square.

eternal flower
#

^ My initial masking (Pre-Blur) outputs like this, my current idea could be to simply create a shader that somehow rounds the edges which would soften the edges of the lighting, however I can't really find any way to do that via shaders.

#

Heading to bed now, thought I'd leave this question here as it's been stumping me pretty bad for a couple hours just in-case anyone has any suggestions to possibly help push me in the right direction! I'll make sure to follow up if anyone responds in the morning, thanks all! sadok 🫶

arctic hill
#

I think what you have currently is a "box blur". Gaussian uses different weights per pixel - e.g. https://danielilett.com/2023-06-01-tut6-6-gaussian-blur/, see how a gaussian(x) function is used - the result being added to the sum and multiplied by sample result. I think it's also common to precompute these weights and store them in a static array, but that probably assumes a fixed loop size.

I think that should be more rounded, though not sure by how much given the input is quite blocky. You could also try rendering that to a lower resolution by adjusting the size of the RTHandle. RenderingUtils.ReAllocateIfNeeded has an overload including a Vector2 scaleFactor. Also maybe use FilterMode.Bilinear (in that function and Sampler State in shader graph) as that may help smooth the pixels too.

eternal flower
eternal flower
# arctic hill I think what you have currently is a "box blur". Gaussian uses different weights...

Hey, so I've done my best to update the gaussian blur to the most up-to-date renderer feature syntax (RTHandle mainly), and on my blit when passing in my "masked" light texture to Daniel's blur shader, I seem to get a fully red output from the shader's blit? I'm unsure if it is due to HLSL's _MainTex not accepting RTHandles properly, but it is quite confusing. It seems to assume the "_MainTex" is a red texture when it should be being passed my cutout light texture as shown in the black/white screenshot above.

#

The texture is properly being initiated and is grabbed via a "Global Texture" grab, I do believe the issue stems from my lack of HLSL knowledge as-far as how _MainTex is handled upon a blit.

#
cmd.Blit(globalLightMaskTexture, rtBlurTex, material, 0);
cmd.Blit(rtBlurTex, globalLightMaskTexture, material, 1);
eternal flower