Jump to content
  • Advertisement
Sign in to follow this  
GeneralQuery

SSAO Issue

This topic is 2597 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm implementing this article using GLSL and a different G Buffer layout. More specifically, I'm getting the view space position by using the method I normally use by sampling the depth buffer, getting the NDCs, unprojecting them and then dividing by w. Now, when I modified the code from the article to work with GLSL and my layout, I get dark artefacts when the view space normal points at (or nearly at) the camera, i.e. (0,0,1) or there abouts, as seen in these pics here:

Bunny Right
FSgMu.png

Bunny Left
T86IG.png

Bunny Centre
0NN29.png

I'm really stumped as to the source of the problem and I've got a feeling the answer is going to be really obvious. Anyway, I hate to do a code dump and expect people to do the work for me but I'll include it anyway in case people want to spot any glaring errors:

[source]
varying vec2 oTexCoords; // Texture coords of screen aligned quad

uniform mat4x4 mtxInvProj; // Inverse of projection matrix

uniform sampler2D iTexDepth; // Depth buffer values in [0,1] range
uniform sampler2D iTexNormal;
uniform sampler2D iTexRandom;

vec2 g_screen_size = vec2(1280.0, 720.0);

float random_size = 64.0; // Random texture = 64x64
float g_sample_rad = 0.5; // Between 0.5 and 2.0
float g_intensity = 3.0;
float g_scale = 1.5; // Between 1.0 and 2.0
float g_bias = 0.05; // Negative values should give "incorrect" results, but sometimes look good

float UnpackSigned(float Value)
{
return (2.0f * Value - 1.0f);
}

vec2 UnpackSigned(vec2 Value)
{
return (2.0f * Value - 1.0f);
}

vec3 UnpackSigned(vec3 Value)
{
return (2.0f * Value - 1.0f);
}

float getDepth(in vec2 uv)
{
return UnpackSigned(texture2D(iTexDepth, oTexCoords).r);
}

vec3 getPosition(in vec2 uv) // uv.z = linear depth
{
float Depth = getDepth(uv);

vec4 Position = vec4(uv.x * 2.0f - 1.0f, (uv.y * 2.0f - 1.0f), Depth, 1.0);

Position = mtxInvProj * Position;
Position /= Position.w;

return Position.xyz;
}

vec3 getNormal(in vec2 uv)
{
vec3 Normal = UnpackSigned(texture2D(iTexNormal, uv).xyz);

return normalize(Normal);
}

vec2 getRandom(in vec2 uv)
{
vec2 Random = UnpackSigned(texture2D(iTexRandom, g_screen_size * uv / random_size).xy);

return normalize(Random);
}

float doAmbientOcclusion(in vec2 tcoord, in vec2 uv, in vec3 p, in 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()
{
const vec2 vec[4] = {vec2(1,0),vec2(-1,0),
vec2(0,1),vec2(0,-1)};

vec3 p = getPosition(oTexCoords);
vec3 n = getNormal(oTexCoords);
vec2 rand = getRandom(oTexCoords);

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(oTexCoords,coord1*0.25, p, n);
ao += doAmbientOcclusion(oTexCoords,coord2*0.5, p, n);
ao += doAmbientOcclusion(oTexCoords,coord1*0.75, p, n);
ao += doAmbientOcclusion(oTexCoords,coord2, p, n);
}
ao/=float(iterations)*4.0;

gl_FragColor = vec4(ao);
}

[/source]

Share this post


Link to post
Share on other sites
Advertisement
Does the article use left-handed coordinates? If that's the case, then view space normals pointing towards the camera will have negative Z (not positive Z, as in your case) and that might be throwing off something in the shader. Same with depth values, which will be positive for a left-handed coordinate system and negative in a right-handed.

Share this post


Link to post
Share on other sites
Never mind, I followed this tutorial and everything works perfectly. It's a derivative of the original GameDev tutorial I linked to above albeit in GLSL so I'll study the two to find out where I went wrong originally. Thanks anyway for the suggestions :D

Edit: it was this line that was causing the problem:

[source]
ao/=float(iterations)*4.0;
[/source]

It needed to be changed to:

[source]
ao = 1.0 - ao / (float(iterations)*4.0);
[/source]

So yea, it was a left/right problem. Although in bother implementations I have a ghost of the random texture map that's "stuck" to the screen. Any ideas?

Random Texture Artefacts

F0scz.png

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!