Jump to content
  • Advertisement
Sign in to follow this  
orenk

SSAO seems strange, help needed...

This topic is 3775 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 created SSAO effect but its seems very strange, i hope that some one will tell me whats wrong because i cant see any problem with my code. first i see the edges of the triangles popping out second, there is white line at the corners, where it needs to be black/shaded triangles edges: Image Hosted by ImageShack.us<br/>By orenk2k at 2008-07-15 white lines: Image Hosted by ImageShack.us<br/>By orenk2k at 2008-07-15 here is the depth shader: Vertex shader
REAL4 vPositionView = mul(In.vPosition, g_matWorldView);
Output.fDepth = length(vPositionView.xyz);
Output.vNormal = mul((In.dwNormal)*2-1, (REAL3x3)g_matWorldView);
Output.vNormal = normalize(Output.vNormal);

Pixel shader
return REAL4(In.vNormal.x, In.vNormal.y, In.vNormal.z, In.fDepth);

frustum corner calc (in client side)
FLOAT farY = tanf(m_pCamera->GetFov() / 2) * m_pCamera->GetFarPlane();
FLOAT farX = farY * m_pCamera->GetAspect();
D3DXVECTOR4 vCorner(farX, farY, m_pCamera->GetFarPlane(), 0.0f);
// note: camera fov in radians

SSAO Shader: Vertex shader:
In.vPosition.xy = sign( In.vPosition.xy);
Output.vPosition = REAL4( In.vPosition.xy, 0.0f, 1.0f);
Output.vTexCoords = In.vTexCoords;
Output.vViewDirToFrustumCorner = REAL3(In.vPosition.xy,1)*g_vDirection.xyz; 
// note: g_vDirection = vCorner computed in client side

Pixel shader:

//reconstruct eye-space position from the depth buffer
REAL depth = tex2D(DepthSampler, In.vTexCoords).a;
REAL3 se = depth * normalize(In.vViewDirToFrustumCorner);

REAL3 randNormal = tex2D( RandNormalSampler, In.vTexCoords*20).rgb;
REAL3 normal = tex2D(DepthSampler, In.vTexCoords).xyz;   

const int num_samples = 16;
REAL finalColor = 0.0f;
for (int i = 0; i < num_samples; i++)
{
	REAL3 ray = reflect(samples.xyz, randNormal);
	
	// add view space normal and bias  
	ray += normal * g_fNormalBias;	    
	ray *= g_fSampleRadius;
	    
	// new (view-space) sample in a sphere of sampleRadius
	REAL4 sample = REAL4(se + ray, 1.0f);

	//determine clip-space locations of our current sample point
	REAL4 ss = mul(sample, g_matProjection);

	//determine the texture coordinate of our current sample point
	REAL2 sampleTexCoord = 0.5f * (ss.xy/ss.w) + REAL2(0.5f, 0.5f);
	sampleTexCoord.y = 1.0 - sampleTexCoord.y;	
	    
	//read the depth of our sample point from the depth buffer
	REAL sampleDepth = tex2D(DepthSampler, sampleTexCoord).a;
		
	//compute our occulusion factor
	REAL depth_diff = depth - sampleDepth;
	REAL occlusion = g_fDistanceScale * max(depth_diff, 0.0f);
	finalColor += 1.0 / (1.0f + (occlusion * occlusion) * 0.1);
}
	
REAL col = finalColor/num_samples;
return REAL4(col, col, col, 1.0f);

Share this post


Link to post
Share on other sites
Advertisement
I can't see any obvious errors, but:

1) why does finalColor += 1.0 / (1.0f + (occlusion * occlusion) * 0.1); have that multiply by 0.1? What if you remove it?

2) for the depth shader, what happens if you interpolate the view-space position to the pixel shader and then take the length there? I believe that's why you can actually "see" the triangle edges

3) what does g_fDistanceScale look like?

Share this post


Link to post
Share on other sites
Quote:
Original post by agi_shi
I can't see any obvious errors, but:

1) why does finalColor += 1.0 / (1.0f + (occlusion * occlusion) * 0.1); have that multiply by 0.1? What if you remove it?

2) for the depth shader, what happens if you interpolate the view-space position to the pixel shader and then take the length there? I believe that's why you can actually "see" the triangle edges

3) what does g_fDistanceScale look like?


hi 'agi_shi' thanks for replaying
i read your thread with geoff wilson on gamedev, i hope you could help me as much as you help him :)
i also saw your 'disorder engine' pics, the ssao look very good, how did you do it?
1. the 0.1 is a scale factor on the depth diff, this allows me to control how it will influence the result.
if i remove it the scene will be brighter.
2. i tried that but it did not give me better results
3. fDistanceScale is scale factor like in (1), allows me to control it from the app, basically i can remove the 0.1 from finalColor += ... and set fDistanceScale = 0.1 you are right - this will save me a mul :)

Share this post


Link to post
Share on other sites
Quote:
Original post by orenk
Quote:
Original post by agi_shi
I can't see any obvious errors, but:

1) why does finalColor += 1.0 / (1.0f + (occlusion * occlusion) * 0.1); have that multiply by 0.1? What if you remove it?

2) for the depth shader, what happens if you interpolate the view-space position to the pixel shader and then take the length there? I believe that's why you can actually "see" the triangle edges

3) what does g_fDistanceScale look like?


hi 'agi_shi' thanks for replaying
i read your thread with geoff wilson on gamedev, i hope you could help me as much as you help him :)

I'll try [smile]
Quote:

i also saw your 'disorder engine' pics, the ssao look very good, how did you do it?

I released my SSAO as a complete demo over at Ogre3D's forums: here. Feel free to inspect and dissect the source [grin]. The ssao shader itself is found in /data/ssao.cg - the code is infact very, very similar to your's, and that is why I cannot spot any obvious errors.
Quote:

1. the 0.1 is a scale factor on the depth diff, this allows me to control how it will influence the result.
if i remove it the scene will be brighter.

I believe you should remove it and only play with the distance scale.
Quote:

2. i tried that but it did not give me better results

Alright, just checking, because I usually encounter odd depth discontinuities by interpolate the depth instead of the view-space vector.
Quote:

3. fDistanceScale is scale factor like in (1), allows me to control it from the app, basically i can remove the 0.1 from finalColor += ... and set fDistanceScale = 0.1 you are right - this will save me a mul :)

What units are you using? 1 unit = 1 meter, or 1 unit = 1 inch, or..? My scene uses meters, and my distance scale is ~50 units.

Like I said, though, I can't really spot any obvious errors in there that would just "pop out", you know what I mean? And thus, something that would help us make sure that the data you're feeding your SSAO is correct:
1) a screen shot of se - just output se.xyzz to the final colour for debugging
2) a screen shot of In.vViewDirToFrustumCorner - same way as above
3) a screen shot of normal - again, same way

Anyways, good luck!

Share this post


Link to post
Share on other sites
hi
yes i know what you mean ;)

0. my units is inches (i'm using q4 editor - they use inches)
1. se.xyzz
Image Hosted by ImageShack.us<br/>By orenk2k at 2008-07-17

2. In.vViewDirToFrustumCorner.xyzz - look the same as 1

3. normal.xyzz
Image Hosted by ImageShack.us<br/>By orenk2k at 2008-07-17

Share this post


Link to post
Share on other sites
Aha! The problem is your far corner calculation. It should indeed have those 4 quadrants, but they should have single-component colours (such as [1,0,0] or [0,1,0], but in your case you have [1,1,1] or [1,0,1] and so on). Like this:


Your normals look fine. Now about what is wrong with your corner, I honestly don't know, since I don't calculate it that way. getFrustumCorners() holds my hand for me [grin]. See if you have some type of function like that available to you, if you're working with some kind of framework. Then what I do, is I pass the 4 far frustum corners as the NORMAL attributes of the 4 vertices - so there's no calculations going on, I simply pass the NORMAL as the camera-to-pixel ray.

As for se.xyzz - it should indeed look similar to the ray, but it should be in a gradient of the depth. For example:


Also, check your depth output. Simply output depth.xxxx / N, where N is some constant so that you get a lager range of depths in the smaller [0..1] range of colours (otherwise you'll only see whatever is 1 inch in front of you, since the higher colours will get clamped to 1).

Share this post


Link to post
Share on other sites
hi
i can see the problem now, no gradient of depth that i could see, its just the same as the 'se'
i'm using my own engine, so i need to make my own functions.
1. what exactly the function 'getFrustumCorners' do? is it calculate the 8 vertices pos the lies at the near and far planes? (4 near and 4 far)
2. assuming i have that function, is the order of corner vertices mater? do i need to map them in a certain order to full screen quad vertices?

Share this post


Link to post
Share on other sites
You only need the 4 far corners of the frustum. As far as the order, the vertices of your quad need to be mapped to the corresponding corner of the frustum. So the top-right vertex gets the the top-right corner, etc.

Share this post


Link to post
Share on other sites
ok, thanks (agi, mjp) i think i have some material to work with ;)
i try it out in hope it will fix the problem

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!