the best ssao ive seen

Started by
237 comments, last by Paksas 12 years, 5 months ago
So, I tried running this (ArKano22's SSAO) in OpenGL since I'm using Cg for my shaders, and I'm not getting the same result. Anyone know why this might be, or things I can check?

On the left is what I get in Direct3D9, and on the right is OpenGL


EDIT:

I checked the positions they each recreate and OpenGL's doesn't look like Direct3D 9's, so I looked at the texture offset
I'm using:
float GetRandom(float2 uv){    return tex2D(randomTex, screenSize * uv / 32.0f).x;}float2 Rotate(float2 c, float ang){    const float cosAng = cos(ang);    const float sinAng = sin(ang);      return float2(cosAng*c.x-sinAng*c.y, sinAng*c.x+cosAng*c.y);}float offset	 = sampleRadius/max(40.0,p.z);float2 texOffset = Rotate(vec[4], GetRandom(IN.uv)*8.0)*offset;

It's not the most recent version, but with the limited testing I did, it seemed to be slightly slower. Regardless, here are my results with Direct3D 9 (which works) and OpenGL (which doesn't)


I'm thinking this has something to do with it, but I'm not sure if this is the root of the problem. Any thoughts?

[Edited by - AgentSnoop on March 27, 2010 7:13:39 PM]
Advertisement
Perhaps it's because in OpenGL z values will have the opposite sign (ex: p.z)?
[s] [/s]
I can see the fnords.
Quote:Original post by DudeMiester
Perhaps it's because in OpenGL z values will have the opposite sign (ex: p.z)?


I tried messing with stuff like that and the texture coordinates. Already, I'm setting opengl to use 1.0 - uv.y where Direct3d 9 uses just uv.y.

When I just output the random texture to the screen, they are more or less the same.. it seems like the opengl one is doing bilinear filtering for some reason even though it's set to do nearest. The only way I can set it to nearest seems to be when I set everything to nearest.

Anyway, It's at the point when I do Rotate where things really start being different. When I look at the direct3d 9 screen, it's mainly red dots with some black and occasionally some green dots. When I look at the opengl version, it's mainly black with some red dots (maybe a few green dots too, but you can't really tell)

If I do max(Rotate(...), 0), I get more red dots on opengl (still looks darker because of the bilinear filtering)

Any thoughts?

EDIT: So, it seems if I just skip the rotate part, I don't get a messed up screen in OpenGL. Also, I don't notice too much a difference compared to with the Rotate function with Direct3D 9.

[Edited by - AgentSnoop on March 29, 2010 5:44:30 PM]
I actually see very little difference between the two in terms of the visual patterns. It may just be an effect of the bilinear filtering.
[s] [/s]
I can see the fnords.
I didn`t wanted to create another SSAO topic, so I am posting to the recent one.
This is a default AO technique that uses only depth texture, so nothing new here, but my part in this is the sample gathering - instead of box blur, I aligned them circularly thus making the occlusion softer and more natural. I also used high-passed luminance texture to discard AO on the highlighted areas, as in real life AO is noticeable only in shadows.

results (animated gifs):




and a YouTube video:




Quote:
uniform sampler2D DepthTexture;
uniform sampler2D RenderedTexture;
uniform sampler2D LuminanceTexture;
uniform float RenderedTextureWidth;
uniform float RenderedTextureHeight;

#define PI 3.14159265

float width = RenderedTextureWidth; //texture width
float height = RenderedTextureHeight; //texture height

float near = 1.0; //Z-near
float far = 1000.0; //Z-far

int samples = 3; //samples on the each ring (3-7)
int rings = 3; //ring count (2-8)

vec2 texCoord = gl_TexCoord[0].st;

vec2 rand(in vec2 coord) //generating random noise
{
float noiseX = (fract(sin(dot(coord ,vec2(12.9898,78.233))) * 43758.5453));
float noiseY = (fract(sin(dot(coord ,vec2(12.9898,78.233)*2.0)) * 43758.5453));
return vec2(noiseX,noiseY)*0.004;
}

float readDepth(in vec2 coord)
{
return (2.0 * near) / (far + near - texture2D(DepthTexture, coord ).x * (far-near));
}

float compareDepths( in float depth1, in float depth2 )
{
float aoCap = 1.0;
float aoMultiplier = 100.0;
float depthTolerance = 0.0000;
float aorange = 60.0;// units in space the AO effect extends to (this gets divided by the camera far range
float diff = sqrt(clamp(1.0-(depth1-depth2) / (aorange/(far-near)),0.0,1.0));
float ao = min(aoCap,max(0.0,depth1-depth2-depthTolerance) * aoMultiplier) * diff;
return ao;
}

void main(void)
{
float depth = readDepth(texCoord);
float d;

float aspect = width/height;
vec2 noise = rand(texCoord);

float w = (1.0 / width)/clamp(depth,0.05,1.0)+(noise.x*(1.0-noise.x));
float h = (1.0 / height)/clamp(depth,0.05,1.0)+(noise.y*(1.0-noise.y));

float pw;
float ph;

float ao;
float s;

for (int i = -rings ; i < rings; i += 1)
{
for (int j = -samples ; j < samples; j += 1)
{
float step = PI*2.0 / float(samples*i);
pw = (cos(float(j)*step)*float(i));
ph = (sin(float(j)*step)*float(i))*aspect;
d = readDepth( vec2(texCoord.s+pw*w,texCoord.t+ph*h));
ao += compareDepths(depth,d);
s += 1.0;
}
}

ao /= s;
ao = 1.0-ao;

vec3 color = texture2D(RenderedTexture,texCoord).rgb;
vec3 luminance = texture2D(LuminanceTexture,texCoord).rgb;
vec3 white = vec3(1.0,1.0,1.0);
vec3 black = vec3(0.0,0.0,0.0);
vec3 treshold = vec3(0.2,0.2,0.2);

luminance = clamp(max(black,luminance-treshold)+max(black,luminance-treshold)+max(black,luminance-treshold),0.0,1.0);

gl_FragColor = vec4(color*mix(vec3(ao,ao,ao),white,luminance),1.0);
}


[Edited by - martinsh on April 10, 2010 5:20:21 PM]
@Martinsh

that is one of the best depth based methods i´ve seen. The images with shadows+ao are impressive! well done!
Thank You ArKano22, yeah I am pretty amazed how sample gathering make a noticeable visual difference.
Quote:Original post by martinsh
I also used high-passed luminance texture to discard AO on the highlighted areas

Surely you mean bright-passed... A high-pass is a frequency-domain operation ;)
"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
Quote:I also used high-passed luminance texture to discard AO on the highlighted areas
Surely you mean bright-passed... A high-pass is a frequency-domain operation ;)
Last I checked, light had a frequency too - regardless, the term is in common use with regards to image filters.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Heh, yeah well I work also with sound and it seemed a quite appropriate to use high-pass instead of bright-pass :), anyway the principle is the same.

This topic is closed to new replies.

Advertisement