Skip to main content
GameDev.net gamedev.net
🔒 Locked

SSAO Problem

Started by ArThor Jun 27, 2015 at 9:20 PM 0 replies 3.6k views
Original Post
ArThor
ArThor

Hi All,

I am trying to implement SSAO as described here but it is not working as shown below:

vomS1AR.jpg

The scene is just two planes and I'm hoping to get shadowing in the corner of them. I am unsure if the view space normals are correct, the output is not what I was expecting, here are the shaders generating the Position and Normal inputs.


//Vertex Shader to generate Position & Normal in viewspace.

#version 440

layout(location = 0)in vec4 vert;
layout(location = 1)in vec4 normal;

out vec3 positionFrg;
out vec3 normalFrg;

uniform mat4 projectionMtx;
uniform mat4 viewMtx;
uniform mat4 modelMtx;

void main()
{
	positionFrg = (viewMtx * vec4(vert.xyz,1)).xyz;
	normalFrg = (viewMtx * vec4(normal.xyz,0)).xyz;

	gl_Position = projectionMtx * viewMtx * modelMtx * vert;
}

//Fragment Shader:
#version 440

in vec3 positionFrg;
in vec3 normalFrg;

void main()
{
	gl_FragData[0] = vec4(positionFrg, 0.0f);
	gl_FragData[1] = vec4(normalize(normalFrg), 0.0f);
}

I don't think I've done anything wrong above, unless I'm missing something obvious.

Below is the SSAO shader code, it is pretty much the same as in the article, adjusted to compile in GLSL and a few changed variable names.


//Vertex Shader

#version 440

layout(location = 0)in vec4 vert;
layout(location = 1)in vec4 texCoord;

out vec2 texCoordFrg;

void main()
{
	texCoordFrg = texCoord.xy;
	gl_Position = vert;
}

//Fragment Shader:

#version 440

uniform sampler2D posInput;
uniform sampler2D nmlInput;
uniform sampler2D rndInput;

float random_size = 64.0f;
float g_sample_rad = 0.5f;
float g_intensity = 3.0f;
float g_scale = 1.0f;
float g_bias = 0.5f;

vec2 g_screen_size = vec2(800.0f, 600.0f);

in vec2 texCoordFrg;

out vec3 frgCol;

vec3 getPosition(vec2 uv)
{
	return texture2D(posInput,uv).xyz;
}

vec3 getNormal(vec2 uv)
{
	return(normalize(texture2D(nmlInput, uv).xyz * 2.0f - 1.0f));
}

vec2 getRandom(vec2 uv)
{
	vec2 coords = vec2(g_screen_size.x * uv.x, g_screen_size.y * uv.y);
	return(normalize(texture2D(rndInput, coords / random_size).xy * 2.0f - 1.0f));
}

float doAmbientOcclusion(vec2 tcoord, vec2 uv, vec3 p, vec3 cnorm)
{
	vec3 diff = getPosition(tcoord + uv) - p;
	const vec3 v = normalize(diff);
	const float d = length(diff)*g_scale;
	return(max(0.0,dot(cnorm,v)-g_bias)*(1.0/(1.0+d))*g_intensity);
}

void main()
{
	float o = 1.0f;
	vec2 vec[4];			
	vec[0] = vec2(1.0f,0);
	vec[1] = vec2(-1.0f,0);
	vec[2] = vec2(0,1.0f);
	vec[3] = vec2(0,-1.0f);

	vec3 p = getPosition(texCoordFrg.xy);
	vec3 n = getNormal(texCoordFrg.xy);
	vec2 rand = getRandom(texCoordFrg.xy);

	float ao = 0.0f;
	float rad = g_sample_rad / p.z;

	//**SSAO Calculation**//
	int iterations = 4;
	for (int j = 0; j < iterations; ++j)
	{
	  vec2 coord1 = reflect(vec[j],rand)*rad;
	  vec2 coord2 = vec2( coord1.x * 0.707 - coord1.y * 0.707, coord1.x * 0.707 + coord1.y * 0.707 );
  
	  ao += doAmbientOcclusion( texCoordFrg.xy, coord1 * 0.25, p, n);
	  ao += doAmbientOcclusion( texCoordFrg.xy, coord2 * 0.5, p, n);
	  ao += doAmbientOcclusion( texCoordFrg.xy, coord1 * 0.75, p, n);
	  ao += doAmbientOcclusion( texCoordFrg.xy, coord2, p, n);
	}

	ao/= float(iterations*4.0);
	//**END**//

	//Do stuff here with your occlusion value âaoâ: modulate ambient lighting, write it to a buffer for later //use, etc.
	frgCol = vec3(ao,ao,ao);
	//frgCol = vec3(rand,0.0f);
	
}

I suspect I am missing some important difference between GLSL and the original article that I am not taking into account, however I don't know what it is.

Can anyone spot the problem or point me in the right direction? I've been making no progress for good half a day and any help would be greatly appreciated.

ArThor
ArThor

I have managed to resolve this myself, the main issue was the buffer I used to store the positions and normals was rgba8 instead of rgb16/32f clamping the position and normal values. A copy and paste error...

Thanks to anyone who thought about it though.

Topic Locked

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

Sign in to reply to this topic.