the best ssao ive seen

Started by
237 comments, last by Paksas 12 years, 5 months ago
I think it's my gfx card dying. Think it has some heat damage because in some games especially in summer, I get really weird artifacts like vertices stretching across the screen. It only shows up sometimes. I managed to export the sponza model to .x and this is the result with a directional light.

http://img32.imageshack.us/img32/8/ssaoj.jpg

Thanks for the help and for coming up with this implementation :D Now I have to try get some better performance as you can see from the framerate.
Advertisement
Quote:Original post by Shael
I think it's my gfx card dying. Think it has some heat damage because in some games especially in summer, I get really weird artifacts like vertices stretching across the screen. It only shows up sometimes. I managed to export the sponza model to .x and this is the result with a directional light.

http://img32.imageshack.us/img32/8/ssaoj.jpg

Thanks for the help and for coming up with this implementation :D Now I have to try get some better performance as you can see from the framerate.


:S sorry about your gfx card. Mine sometimes dies and my screen turns purple. But it happens only form time to time and it works well usually.

About the performance, try to change the number of iterations with this:
int iterations = lerp(5.0,1.0,p.z/g_far_clip);

where g_far_clip is your far clipping plane distance and p.z is the z position of the pixel. This enables some sort of LOD system, where far away pixels receive less attention (less iterations). It works pretty well for me, in the crytek´s sponza scene the gain is almost 50 fps. The drawback is that distant objects get coarser occlusion, but it is barely noticeable.

EDIT: you can also change the sample coor computation to this:
float2 coord1 = reflect(vec[j],rand)*g_sample_rad/max(40.0,p.z);

doing the max(40.0,p.z), reduces the sampling radius for objects near the camera. This will give you an extra boost on closeups. "40.0" is the minimum distance at which the radius begins to shrink.
Great work :), and as you were advised you should definitely publish that...

Keep it up!

Atef
In the RM project, I understand the g_buffer_pos, but what is the g_buffer_posb?
"But who prays for Satan? Who, in eighteen centuries, has had the common humanity to pray for the one sinner that needed it most?" --Mark Twain

~~~~~~~~~~~~~~~Looking for a high-performance, easy to use, and lightweight math library? http://www.cmldev.net/ (note: I'm not associated with that project; just a user)
Quote:Original post by Prune
In the RM project, I understand the g_buffer_pos, but what is the g_buffer_posb?


The position of back faces. It is used to compute occlusion due to surfaces facing away from the camera.
depth seems to be assigned a value twice in the fill_front pass:

float depth = (length(i.camera_position.xyz) - g_near_clip) / (g_far_clip - g_near_clip);
depth = length(i.camera_position.xyz);

So which should be used?

BTW, in trying to convert this to an OpenGL project instead of DirectX, I seem unable to add multiple render targets to a pass... the option becomes disabled once a single target is added. Can anyone clue me in how to do this in RM? It also looks like output to the 32F render targets is clamped to [0,1] in OpenGL mode in RM

[Edited by - Prune on March 22, 2010 6:29:45 PM]
"But who prays for Satan? Who, in eighteen centuries, has had the common humanity to pray for the one sinner that needed it most?" --Mark Twain

~~~~~~~~~~~~~~~Looking for a high-performance, easy to use, and lightweight math library? http://www.cmldev.net/ (note: I'm not associated with that project; just a user)
Thanks for the optimizing tips ArKano22. What are your thoughts on using SSAO along with normal mapping? I do my depth/normal in one pass and then use the output in the SSAO shader. However, SSAO requires plain vertex normals and lighting requires normal/bump maps. Whats the best way to get around this without having any more geometry passes? Would I have to have two normal render targets?
Quote:Original post by Shael
Thanks for the optimizing tips ArKano22. What are your thoughts on using SSAO along with normal mapping? I do my depth/normal in one pass and then use the output in the SSAO shader. However, SSAO requires plain vertex normals and lighting requires normal/bump maps. Whats the best way to get around this without having any more geometry passes? Would I have to have two normal render targets?


There is a way around it if you are willing to sacrifice a bit of quality in your ssao: reconstruct the normal based on position.
Replacing your normal-buffer reading function with this should so the trick:

float3 getNormal(in float3 p ,in float2 uv){  float3 p1 = tex2D(g_buffer_pos, uv+float2(1.0/g_screen_size.x*0.25,0)).xyz;  float3 p2 = tex2D(g_buffer_pos, uv+float2(0,1.0/g_screen_size.y*0.25)).xyz;    float3 dx = p1-p;  float3 dy = p2-p;    return normalize(cross( dx , dy  ));}


This will give you flat-normals, not interpolated normals (bad for organic shapes) and a liiitle bit of haloing. For this to work, your position buffer must be linearly filtered.
(I could have used ddx() and ddy() to do the reconstruction but they create big halos.)

However, unless you are really reticent to having two normal buffers around, i would recommend having them both: per pixel normals for lighting and interpolated per face normals for ssao.
Looks like there's definitely a problem with RenderMonkey clamping GLSL outputs. Things work fine if I compress the range to fit inside [0,1] in the fill_pos/fill_posb passes and then decompress it in do_ssao. Still using the 32-bit floating point render targets.
"But who prays for Satan? Who, in eighteen centuries, has had the common humanity to pray for the one sinner that needed it most?" --Mark Twain

~~~~~~~~~~~~~~~Looking for a high-performance, easy to use, and lightweight math library? http://www.cmldev.net/ (note: I'm not associated with that project; just a user)
Quote:Original post by ArKano22
int iterations = lerp(5.0,1.0,p.z/g_far_clip);

vec[] in your code is of size 4. Wouldn't a case such as an ortho projection with near plane of 0 or negative be able to cause a shader runtime error as vec[4] is accessed when nearby geometry crosses depth 0?

"But who prays for Satan? Who, in eighteen centuries, has had the common humanity to pray for the one sinner that needed it most?" --Mark Twain

~~~~~~~~~~~~~~~Looking for a high-performance, easy to use, and lightweight math library? http://www.cmldev.net/ (note: I'm not associated with that project; just a user)

This topic is closed to new replies.

Advertisement