Two Pass Gaussian Blur Different from a One Pass Gaussian Blur

Started by
1 comment, last by harshman_chris 11 years ago

So I am working on Gaussian Blurring of my scene, both with a single pass and a 2 pass, the problem is they look very different and they shouldn't because it is computationally the same.

I have attached sample images of the two blur's and the 3 fragment shaders. The images are normally more blurred but I made them full screen up from 1/4 screen size so you can see them.

Screenshots:

One Pass Blur

[attachment=14369:OnePassBlur.png]

Two Pass Blur

[attachment=14370:TwoPassBlur.png]

Shaders:

One Pass:


#version 330

in vec2 uv1;

out vec4 colour;

uniform sampler2D brightpassInput;

uniform vec2 pixelSize;

vec2 uv0[25];
float weights[25];

vec3 GuassianBlur()
{
	vec3 result = vec3(0.0);

	for(int i = 0; i < 25; i++)
	{
		result += texture2D(brightpassInput,uv0).rgb * weights;
	}

	return result;
}

void CalculateUvs_Weights()
{
	// Top Row
	uv0[0] = uv1 + vec2(-pixelSize.x*2,pixelSize.y*2);
	uv0[1] = uv1 + vec2(-pixelSize.x,pixelSize.y*2);
	uv0[2] = uv1 + vec2(0,pixelSize.y*2);
	uv0[3] = uv1 + vec2(pixelSize.x,pixelSize.y*2);
	uv0[4] = uv1 + vec2(pixelSize.x*2,pixelSize.y*2);

	// Mid Top Row
	uv0[5] = uv1 + vec2(-pixelSize.x*2,pixelSize.y);
	uv0[6] = uv1 + vec2(-pixelSize.x,pixelSize.y);
	uv0[7] = uv1 + vec2(0,pixelSize.y);
	uv0[8] = uv1 + vec2(pixelSize.x,pixelSize.y);
	uv0[9] = uv1 + vec2(pixelSize.x*2,pixelSize.y);

	//Mid Row
	uv0[10] = uv1 + vec2(-pixelSize.x*2,0);
	uv0[11] = uv1 + vec2(-pixelSize.x,0);
	uv0[12] = uv1 + vec2(0,0);
	uv0[13] = uv1 + vec2(pixelSize.x,0);
	uv0[14] = uv1 + vec2(pixelSize.x*2,0);

	//Mid Bottom Row
	uv0[15] = uv1 + vec2(-pixelSize.x*2,-pixelSize.y);
	uv0[16] = uv1 + vec2(-pixelSize.x,-pixelSize.y);
	uv0[17] = uv1 + vec2(0,-pixelSize.y);
	uv0[18] = uv1 + vec2(pixelSize.x,-pixelSize.y);
	uv0[19] = uv1 + vec2(pixelSize.x*2,-pixelSize.y);

	//Bottom Row
	uv0[20] = uv1 + vec2(-pixelSize.x*2,-pixelSize.y*2);
	uv0[21] = uv1 + vec2(-pixelSize.x,-pixelSize.y*2);
	uv0[22] = uv1 + vec2(0,-pixelSize.y*2);
	uv0[23] = uv1 + vec2(pixelSize.x,-pixelSize.y*2);
	uv0[24] = uv1 + vec2(pixelSize.x*2,-pixelSize.y*2);

	weights[0] = 0.00078633;
	weights[1] = 0.00655965;
	weights[2] = 0.01330373;
	weights[3] = 0.00655965;
	weights[4] = 0.00078633;
	
	// Mid To
	weights[5] = 0.00655965;
	weights[6] = 0.05472157;
	weights[7] = 0.11098164;
	weights[8] = 0.05472157;
	weights[9] = 0.00655965;
	
	//Mid Row
	weights[10] = 0.01330373;
	weights[11] = 0.11098164;
	weights[12] = 0.22508352;
	weights[13] = 0.11098164;
	weights[14] = 0.01330373;
	
	//Mid Bot
	weights[15] = 0.00655965;
	weights[16] = 0.05472157;
	weights[17] = 0.11098164;
	weights[18] = 0.05472157;
	weights[19] = 0.00655965;
	
	//Bottom 
	weights[20] = 0.00078633;
	weights[21] = 0.00655965;
	weights[22] = 0.01330373;
	weights[23] = 0.00655965;
	weights[24] = 0.00078633;
}

void main()
{
	CalculateUvs_Weights();
	colour.rgb = GuassianBlur();
}

Two Pass X:


#version 330

vec2 uv0[5];
float weights[5];

in vec2 uv1;

out vec4 colour;

uniform sampler2D brightpassInput;

uniform vec2 pixelSize;

vec3 GuassianBlur()
{
	vec3 result = vec3(0.0);

	for(int i = 0; i < 5; i++)
	{
		result += texture2D(brightpassInput,uv0).rgb * weights;
	}

	return result;
}

void CalculateUvs_Weights()
{
	uv0[0] = uv1 + vec2(-pixelSize.x*2,0);
	uv0[1] = uv1 + vec2(-pixelSize.x,0);
	uv0[2] = uv1 + vec2(0,0);
	uv0[3] = uv1 + vec2(pixelSize.x,0);
	uv0[4] = uv1 + vec2(pixelSize.x*2,0);

	weights[0] = 0.01330373;
	weights[1] = 0.11098164;
	weights[2] = 0.22508352;
	weights[3] = 0.11098164;
	weights[4] = 0.01330373;
}

void main()
{
	CalculateUvs_Weights();
	colour.rgb = GuassianBlur();
}

Two Pass Y:


#version 330

vec2 uv0[5];
float weights[5];

in vec2 uv1;

out vec4 colour;

uniform sampler2D brightpassInput;

uniform vec2 pixelSize;

vec3 GuassianBlur()
{
	vec3 result = vec3(0.0);

	for(int i = 0; i < 5; i++)
	{
		result += texture2D(brightpassInput,uv0).rgb * weights;
	}

	return result;
}

void CalculateUvs_Weights()
{
	uv0[0] = uv1 + vec2(0,pixelSize.y*2);
	uv0[1] = uv1 + vec2(0,pixelSize.y);
	uv0[2] = uv1 + vec2(0,0);
	uv0[3] = uv1 + vec2(0,-pixelSize.y);
	uv0[4] = uv1 + vec2(0,-pixelSize.y*2);

	weights[0] = 0.01330373;
	weights[1] = 0.11098164;
	weights[2] = 0.22508352;
	weights[3] = 0.11098164;
	weights[4] = 0.01330373;
}

void main()
{
	CalculateUvs_Weights();
	colour.rgb = GuassianBlur();
}

Advertisement

Your weights for the one pass solution are normlized (sums up to 1), whereas the two pass version is not normalized. Try to normalize them by


	weights[0] = 0.01330373 / 0.47365426;
	weights[1] = 0.11098164 / 0.47365426;
	weights[2] = 0.22508352 / 0.47365426;
	weights[3] = 0.11098164 / 0.47365426;
	weights[4] = 0.01330373 / 0.47365426;

Your weights for the one pass solution are normlized (sums up to 1), whereas the two pass version is not normalized. Try to normalize them by


	weights[0] = 0.01330373 / 0.47365426;
	weights[1] = 0.11098164 / 0.47365426;
	weights[2] = 0.22508352 / 0.47365426;
	weights[3] = 0.11098164 / 0.47365426;
	weights[4] = 0.01330373 / 0.47365426;

Thank you that fixed it.

This topic is closed to new replies.

Advertisement