#Circular Blur Shader Question
1 messages · Page 1 of 1 (latest)
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.
^ 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!
🫶
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.
Ah, alright! I am currently downsampling which does create a larger/smoother blur. But I haven't considered the box blur thing, I'll look into it appreciate it!
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);
my HLSL shader makes the assumption that the "source" being passed to the material is recognized as _MainTex via the HLSL shader.