Skip to main content
gamedev.net
🔒 Locked

Blur Shader problem

Started by Wraiyth Jan 9, 2007 at 10:00 PM 5 replies 1.4k views
Original Post
Wraiyth
Wraiyth
I've been working on a shader to blur the screen based on an alpha image (trying to get a sort of large blur on the outside moving into totally clear, a sort of dreamy look). Sort of like this http://nudel.omega2k3.de/blur_gradient.jpg The shader I have so far Pixel Shader
#include "common_ps_fxc.h"

sampler fb	: register( s0 ); //frontbuffer
sampler alpha	: register( s1 ); //alphasampler

const HALF sampledist	: register(c0);
const HALF2 samples[8] = {
   -1, -1,
    0, -1,
    1, -1,
   -1,  0,
    1,  0,
   -1,  1,
    0,  1,
    1,  1,
};

HALF4 main( HALF2 iTexCoord : TEXCOORD0 ) : COLOR
{
	float4 color = tex2D(fb, iTexCoord);
	float4 bnw = tex2D(alpha, iTexCoord);
	float4 avg = color;
	for (int i = 0; i < 8; i++){
		avg += tex2D(fb, iTexCoord + sampledist * samples);
	}
	avg /= 9;
	return lerp(avg, color, bnw);	
	
} 
Vertex Shader
#include "common_vs_fxc.h"

struct VS_INPUT
{
	float3 vPos				: POSITION;
	float2 vBaseTexCoord			: TEXCOORD0;
};

struct VS_OUTPUT
{
	float4 vProjPos				: POSITION;	
	float2 vBaseTexCoord0			: TEXCOORD0;
};

VS_OUTPUT main( const VS_INPUT v )
{
	VS_OUTPUT o = ( VS_OUTPUT )0;

	float4 vProjPos = float4( v.vPos, 1.0f );
	o.vProjPos = vProjPos;
	o.vBaseTexCoord0 = v.vBaseTexCoord;
	return o;
}
The problem is that the resulting image I get doesn't blur, but rather produces a ghosting effect in the area thats meant to blur http://www.wraiyth.com/files/nf/blurimage.jpg Anyone got any suggestions or ideas as to why its doing that and not blurring/
Wraiyth
Wraiyth
0.05
Sc4Freak
Sc4Freak
Hmm, I don't know what the problem is, sorry. But, just keep in mind that at a resolution of 800x600, you'll be sampling pixels up to 40 pixels away.
Schrompf
Schrompf
Like Sc4Freak said: texture coords are from 0 to 1 for the whole image. If you offset your texture coords by 1 or -1, you don't step one pixel right or left but instead one full image right or left. You have to scale all coord offsets by 1 / Width or 1 / Height.
----------
Gonna try that "Indie" stuff I keep hearing about. Let's start with Splatter.
TheAdmiral
TheAdmiral
The sampdist variable is half of the problem. The other half is texel-pixel mapping. Assuming that the render-buffer is 800x600 (as in the image), a 1x1 sample mismatch will transform (by 0.05) to a 40x30 screen offset, which is exactly what is observed in the image.

In order to get a uniform 3x3 pixel blur kernel, you should decouple the horizontal and vertical sampling offsets and set them to 1/800 and 1/600 respectively, as Schrompf suggested. This will limit the translation to a pixel in each direction. To eliminate the offsetting altogether, you will also need to offset the texture coordinates by -1/2 a pixel in each dimension, as explained in this article (Edit: I've assumed you're using Direct3D. I'm not sure if OpenGL uses the same sampling algorithm).

Once this is done, you may be disappointed by the results. On such a high resolution, a 3x3 blur kernel gives almost unnoticeable results. The most common way to perform a more significant blur is to downsample the image prior to blurring, then upsample it back before blending.
With so many stages involved, you may prefer to separate the blurring and blending stages into separate shaders (or even use the FFP for blending):

1. Copy the back-buffer to a smaller (say 256x256 or even smaller) render-texture, using a bilinear sampler.
2. Render the downsampled image to another buffer of the same size, applying your blur fliter (or perhaps one with a larger kernel, to give better results).
3. Blend the result with the back-buffer, using your greyscale Gaussian splat as an alpha channel.

With a little care, you can combine the first two stages. Not only does this give better results, but it costs you far less in terms of fillrate, as that reasonably costly blur shader is far happier running 256² times than 800x600 times. Happier by a factor of 7 [smile].

Admiral
Ring3 Circus - Diary of a programmer, journal of a hacker.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.