SSAO Compositor

A place to show off your latest screenshots and for people to comment on them. Only start a new thread here if you have some nice images to show off!
User avatar
Noman
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 714
Joined: Mon Jan 31, 2005 7:21 pm
Location: Israel
x 2

Re: SSAO Compositor

Post by Noman »

Thanks!

Converting shaders is turning out to be a bigger hassle than I expected. Should've thought about it beforehand.
I'll probably make the move to CG instead of HLSL+GLSL anyway, so I'll probably just write the shader set from scratch, perhaps using some of the shaders from your demo as a starting point.

Is that alright with you?
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Re: SSAO Compositor

Post by nullsquared »

Noman wrote:Thanks!

Converting shaders is turning out to be a bigger hassle than I expected. Should've thought about it beforehand.
I'll probably make the move to CG instead of HLSL+GLSL anyway, so I'll probably just write the shader set from scratch, perhaps using some of the shaders from your demo as a starting point.

Is that alright with you?
Yup, and if you need any help, just PM me. I suggest simply using CG anyways, keeping the same thing in both HLSL and GLSL is annoying. My deferred renderer uses nothing but CG.
lukeneorm
Halfling
Posts: 61
Joined: Wed Apr 01, 2009 12:03 am

Re: SSAO Compositor

Post by lukeneorm »

Hi there,
first of all THANK YOU nullsquared for your answers. I'm doing a day-by-day step forward in my shader code knowledge. :D

I'm continuing to study ssao compositor code. This time I have some trubles with ssao_ps pixel shader.. :?

-> geomMap is the output of the pixel shader geom_ps: it is a texture with values (depth, normal.x, normal.y, normal.z) of the current pixel. Why in geom_ps we calculate the depth value with length(vp.xyz) and not with vp.z?

Here are some questions about the pixel shader ssao_ps:

Code: Select all

		// random normal lookup from a texture and expand to [-1..1]
		float3 randN = TEX2DLOD(randMap, IN.uv * 24).xyz * 2.0 - 1.0;
		float4 geom = TEX2DLOD(geomMap, IN.uv);
-> IN.uv contains [0,1] values, but if we multiply IN.uv values by 24, don't we run the risk that we'll overflow correct [0,1] UV range values to lookup randMap texture values? Why we mutiply by 24?
-> Then we multiply the texture lookup by 2.0 and the subtract 1.0, as we want to obtain [-1,1] range from [0,1] range, but when we look for the RGB values in UV position in randMap, don't we obtain [0, 128] values stored in randN.xyz instead of [0,1] range values?

Code: Select all

			// move new view-space position back into texture space
			#define RADIUS 0.2125
			float4 nuv = mul(ptMat, float4(viewPos.xyz + randomDir * RADIUS, 1));
			nuv.xy /= nuv.w;
-> ptMat is passed from the program, and its value is CLIP_SPACE_TO_IMAGE_SPACE * cam->getProjectionMatrixWithRSDepth(), where getProjectionMatrixWithRSDepth() will return the projectionMatrix in Ogre's native format (right-handed), and the depth values will range from [-1, 1]; CLIP_SPACE_TO_IMAGE_SPACE is a hard-coded matrix. Why we need this particular kind of matrix and we can't obtain nuv in screenSpace by passing ptMat with a simple projMatrix in the default_params of ssao_ps fragment program?

Code: Select all

			// compute occlusion based on the (scaled) Z difference
			float zd = saturate(far * (depth - TEX2DLOD(geomMap, nuv.xy).x));
-> far is the value of the far clip distance, passed from the program. If we want the difference (depth - TEX2DLOD(geomMap, nuv.xy).x) to be a coefficient between 0 and 1, why we multiply it by the far value? Shouldn't we divide by it?
-> How we deal with edge cases / sampling outside the screen? [Starcraft]: The offset vectors are in viewSpace, not screenSpace: who ensure that nuv.xy coords will not overflow geoMap? Does tex_address_mode clamp in ssao.material addresses this issue?

Code: Select all

			// this is a sample occlusion function, you can always play with
			// other ones, like 1.0 / (1.0 + zd * zd) and stuff
			occ += saturate(pow(1.0 - zd, 11) + zd);
-> I read that the occlusion function can be any function that adheres to these criteria:
1.- Negative depth deltas should give zero occlusion (the occluding surface is behind the sample point)
2.- Smaller depth deltas should give higher occlusion values
3.- The occlusion value needs to fall to zero again beyond a certain depth delta value
..so, if we have a negative depth difference, the occlusion value should value 0. In our case we got instead that (depth - TEX2DLOD(geomMap, nuv.xy).x) is negative => saturate clamp that value to 0 => saturate(pow(1.0 - zd, 11) + zd) got 1, not 0! Why?

Thank you for the help!
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Re: SSAO Compositor

Post by nullsquared »

lukeneorm wrote: -> geomMap is the output of the pixel shader geom_ps: it is a texture with values (depth, normal.x, normal.y, normal.z) of the current pixel. Why in geom_ps we calculate the depth value with length(vp.xyz) and not with vp.z?
I do that because we then normalize the value by dividing by the greatest possible length of the view-space position, which is the far clip distance of the camera. One article also does it with vp.z instead of length(vp.xyz), so you can try that if you want.
Here are some questions about the pixel shader ssao_ps:

Code: Select all

		// random normal lookup from a texture and expand to [-1..1]
		float3 randN = TEX2DLOD(randMap, IN.uv * 24).xyz * 2.0 - 1.0;
		float4 geom = TEX2DLOD(geomMap, IN.uv);
-> IN.uv contains [0,1] values, but if we multiply IN.uv values by 24, don't we run the risk that we'll overflow correct [0,1] UV range values to lookup randMap texture values? Why we mutiply by 24?
We do overflow it, and since the texture is set to wrap, not clamp, at the borders, we get the texture to repeat. We do this so that the small texture repeats many times over the screen (which is bigger).
-> Then we multiply the texture lookup by 2.0 and the subtract 1.0, as we want to obtain [-1,1] range from [0,1] range, but when we look for the RGB values in UV position in randMap, don't we obtain [0, 128] values stored in randN.xyz instead of [0,1] range values?
Nope, when you fetch a value from a texture, it will be in the range [0..1]. (unless it's a floating point texture, which may have larger or negative values)

Code: Select all

			// move new view-space position back into texture space
			#define RADIUS 0.2125
			float4 nuv = mul(ptMat, float4(viewPos.xyz + randomDir * RADIUS, 1));
			nuv.xy /= nuv.w;
-> ptMat is passed from the program, and its value is CLIP_SPACE_TO_IMAGE_SPACE * cam->getProjectionMatrixWithRSDepth(), where getProjectionMatrixWithRSDepth() will return the projectionMatrix in Ogre's native format (right-handed), and the depth values will range from [-1, 1]; CLIP_SPACE_TO_IMAGE_SPACE is a hard-coded matrix. Why we need this particular kind of matrix and we can't obtain nuv in screenSpace by passing ptMat with a simple projMatrix in the default_params of ssao_ps fragment program?
This way we avoid scaling the UV's from [-1..1] to [0..1] for texture lookup, since the conversion from [-1..1] to [0..1] is found in CLIP_SPACE_TO_IMAGE_SPACE (which is premultiplied).

Code: Select all

			// compute occlusion based on the (scaled) Z difference
			float zd = saturate(far * (depth - TEX2DLOD(geomMap, nuv.xy).x));
-> far is the value of the far clip distance, passed from the program. If we want the difference (depth - TEX2DLOD(geomMap, nuv.xy).x) to be a coefficient between 0 and 1, why we multiply it by the far value? Shouldn't we divide by it?
The values are normalized in [0..1], we then multiply by the far clip distance to get them back to [0..far_clip] range.
-> How we deal with edge cases / sampling outside the screen? [Starcraft]: The offset vectors are in viewSpace, not screenSpace: who ensure that nuv.xy coords will not overflow geoMap? Does tex_address_mode clamp in ssao.material addresses this issue?
This compositor is pretty simple, it doesn't deal with edge cases (well, it clamps the texture fetching to the borders). Technically, you can render a bigger screen than you actually "see" just for quality SSAO computations at the edges, but it gets too complicated.

Code: Select all

			// this is a sample occlusion function, you can always play with
			// other ones, like 1.0 / (1.0 + zd * zd) and stuff
			occ += saturate(pow(1.0 - zd, 11) + zd);
-> I read that the occlusion function can be any function that adheres to these criteria:
1.- Negative depth deltas should give zero occlusion (the occluding surface is behind the sample point)
2.- Smaller depth deltas should give higher occlusion values
3.- The occlusion value needs to fall to zero again beyond a certain depth delta value
..so, if we have a negative depth difference, the occlusion value should value 0. In our case we got instead that (depth - TEX2DLOD(geomMap, nuv.xy).x) is negative => saturate clamp that value to 0 => saturate(pow(1.0 - zd, 11) + zd) got 1, not 0! Why?
This just becomes a matter of "what looks good". I did not go for correctness at all here, I just played and tweaked the formula until I got something that I thought looked good.
User avatar
_tommo_
Gnoll
Posts: 677
Joined: Tue Sep 19, 2006 6:09 pm
x 5

Re: SSAO Compositor

Post by _tommo_ »

Talking of "what looks good" i found a really interesting optimization to SSAO, used by Epic in the last UE3 games :)
they use a temporal "SSAO History" so that they can accumulate samples for depth comparison also over time, reducing by many times the weight of the whole algorithm while having a quality comparable to hundreds of samples...
You can see that in the darkest level of GOW2: if you turn fast the view you can see the SSAO "popping up" in some seconds.
It isn't very noticeable because the overall blur makes it difficult to notice these details in a moving scene...

You can actually find the code of a working HLSL implementation into recent of UE3 games, when installed... while i don't know how much this is legal :roll:

Anyway it looks like a good idea, maybe it could be replicated in Ogre? :roll:
OverMindGames Blog
IndieVault.it: Il nuovo portale italiano su Game Dev & Indie Games
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2

Re: SSAO Compositor

Post by Kencho »

Yes, I doubt that's legal at all :P

Anyways, the idea sounds interesting. I think that some kind of threshold might be used to determine whether to rebuild the whole SSAO cache or use it (for instance, recalculating it from the ground up if a camera is switched or there was a lot of movement between a frame and the next).
Image
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Re: SSAO Compositor

Post by nullsquared »

Yeah, I've see that in action. I personally think it looks horrible unless the SSAO is extremely blurry and you have tons and tons of motion blur.

See here: http://www.gamedev.net/community/forums ... _id=527170
User avatar
_tommo_
Gnoll
Posts: 677
Joined: Tue Sep 19, 2006 6:09 pm
x 5

Re: SSAO Compositor

Post by _tommo_ »

Apparently i was not the first to notice that:
Someone on Gamedev already implemented a demo
And made a clip :)
It looks very good!

Anyway it appears that they don't do a simple average of old frames, instead they offset the old ssao using the inverse of the velocity map used for motion blur...
in fact i was wondering how the AO remains local and doesn't "streak" when you move the camera.
With a simple average it would suffer of a motion blur.

EDIT: i wasn't the first to notice that thread either :)
I wouldn't discard the idea so fast, they are still using it on x360 for GOW2, proving it's fast and good-looking :)
OverMindGames Blog
IndieVault.it: Il nuovo portale italiano su Game Dev & Indie Games
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2

Re: SSAO Compositor

Post by Kencho »

_tommo_ wrote:I wouldn't discard the idea so fast, they are still using it on x360 for GOW2, proving it's fast and good-looking :)
Hmm... be careful with this kind of metrics ("People is using it commercially, so it can't be bad"). Remember the bloom effect? HDR? Cel-shading? If not used correctly they still look horrible.
Image
User avatar
_tommo_
Gnoll
Posts: 677
Joined: Tue Sep 19, 2006 6:09 pm
x 5

Re: SSAO Compositor

Post by _tommo_ »

I know, anything done badly can look horrible... but in this case the question was "can this effect achieve good and effective results when well implemented?"
And the fact that is default in new UE3 games proves it enough to me :)
OverMindGames Blog
IndieVault.it: Il nuovo portale italiano su Game Dev & Indie Games
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Re: SSAO Compositor

Post by nullsquared »

_tommo_ wrote: And made a clip :)
It looks very good!
Notice how he(/she?) moves the camera very slowly and smoothly.

Try the demo. It does not look good in intense motion.
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2

Re: SSAO Compositor

Post by Kencho »

@_tommo_: Yes, I definitely am getting interested in ASSAO. Looks better than simple SSAO :)

@nullsquared: In the worst case I don't see a significant disadvantage over SSAO. I think it would all be a matter of fine-tuning the parameters to make it look good while gaining some performance, don't you think? :)
Image
User avatar
_tommo_
Gnoll
Posts: 677
Joined: Tue Sep 19, 2006 6:09 pm
x 5

Re: SSAO Compositor

Post by _tommo_ »

nullsquared wrote:
_tommo_ wrote: And made a clip :)
It looks very good!
Notice how he(/she?) moves the camera very slowly and smoothly.

Try the demo. It does not look good in intense motion.
I did try the demo and indeed it does NOT look good... even when you stand still :roll:
The demo is obviously bad quality as it is very grained and has artifacts compared to a normal SSAO (jaggy edges, too strong/too big/too much contrast), to be honest the blur and the popping of the effect was the less noticeable problem...
the whole setting of the demo is badly made, because on that scale (aerial view of a city) visible AO is phisically impossible being a low-range effect.

anyway i'm not trying to force anyone into making it, i was only suggesting a possible improvement :)
OverMindGames Blog
IndieVault.it: Il nuovo portale italiano su Game Dev & Indie Games
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Re: SSAO Compositor

Post by nullsquared »

Kencho wrote:@nullsquared: In the worst case I don't see a significant disadvantage over SSAO. I think it would all be a matter of fine-tuning the parameters to make it look good while gaining some performance, don't you think? :)
It's not a performance improvement. It's a quality improvement. It's basically regular SSAO, except every frame the random offsets are shuffled, yielding a the effect of having an extremely large amount of samples. The problem is that this extremely large amount of samples is accumulated over several frames, and therefore, when movement is added into the mix, this SSAO looks absolutely horrible. Nor does it perform better than "normal" SSAO.

Edit:
I see what you're saying. In theory, yes, you can skip some samples. It's really 16 samples vs. 32 samples though, not much of an improvement.
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2

Re: SSAO Compositor

Post by Kencho »

Ah, understood. Gotta look deeper into SSAO and other screen space lighting techniques :) I know some basics but not the real guts :?
Image
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Re: SSAO Compositor

Post by nullsquared »

Kencho wrote:Ah, understood. Gotta look deeper into SSAO and other screen space lighting techniques :) I know some basics but not the real guts :?
The shader code from the demo is there, you can easily look at it. He does either 16 or 32 samples depending on whether the cached result is a hit or miss (and the random offsets are shuffled around). This is, of course, assuming the GPU handles dynamic branching. Otherwise it just does 32 samples anyway.
lukeneorm
Halfling
Posts: 61
Joined: Wed Apr 01, 2009 12:03 am

Re: SSAO Compositor

Post by lukeneorm »

Thank you nullsquared for your explanations! :D

I have still some questions here.. :roll:

-> How we can deal with AO in creases (low-tassellation problem)? In my scene there are low tassellation problems like this (I increased the contrast to better see the problem):
Image
In this pdf (pag.18) nVidia suggest to use an "angle bias". Is it possible to use that technique also here? I tried to lookup for the normal vector in nuv position and dot product it with the normal vector in uv position: if it is less than some bias value the current sample has occ value = 0, but it doesn't seem to work well.

-> As you said in the explanation of the code, 'the "smart" blur is done using a simple dot product between the original normal and the new pixels' normal. If it's over 0.9, then the pixel is accepted - otherwise, it is rejected'. Don't we need to check also the depth discontinuity? I mean, if pixel at geom and nGeom have the same normal direction but they belong to two different objects, with different depth values.. isn't this also a case to reject for the "smart" blur?

When we do the smart blur we take our samples (placed at a distance in inverse proportion with the width of the screen) with two cycles: in the first one we move from uv coords to the up-right direction, while in the second one we move in the left-down direction:

Code: Select all

    for (int i = 1; i <= NUM_BLUR_SAMPLES; ++i)
    {
        float2 nuv = uv + o * i;
        float4 nGeom = TEX2DLOD(geomMap, nuv);
        float coef = (NUM_BLUR_SAMPLES + 1 - i) * (dot(geom.yzw, nGeom.yzw) > 0.9);
        sum += TEX2DLOD(map, nuv) * coef;
        denom += coef;
    }
    for (int i = 1; i <= 4; ++i)
    {
        float2 nuv = uv + o * -i;
        float4 nGeom = TEX2DLOD(geomMap, nuv);
        float coef = (NUM_BLUR_SAMPLES + 1 - i) * (dot(geom.yzw, nGeom.yzw) > 0.9);
        sum += TEX2DLOD(map, nuv) * coef;
        denom += coef;
    }
    return sum / denom;

-> Why in he first cycle we do NUM_BLUR_SAMPLES steps, and in the second one just 4 steps?
-> If NUM_BLUR_SAMPLES=8 and for all the samples (dot(geom.yzw, nGeom.yzw) > 0.9), we have that 'denom' value is (8+7+6+5+4+3+2+1=36) + (8+7+6+5=26) = 62. We have summed 8+4 = 12 samples in 'sum' instead. Why we return sum/denom?

..and that's all. :roll: I think these are the last questions about ssao compositor, after that I'll be able to write another post like this to explain the code, thanks to your GREAT help. :wink:
rbma
Gnoblar
Posts: 4
Joined: Mon Jul 20, 2009 10:06 am

Re: SSAO Compositor

Post by rbma »

hi everybody!

nullsquared, i am currently trying to integrate your ssao-compositor into my application. i could get it up and running without much problems thanks to the provided demo. but as you can see on the following images the ssao-effect itself seems to be a little too "weak".

off
http://img124.imageshack.us/i/ssaooff.png/

on
http://img441.imageshack.us/i/ssaoon.png/

off
http://img31.imageshack.us/i/ssaooffstairs.png/

on
http://img37.imageshack.us/i/ssaoonstairs.png/

i've found your other thread regarding ssao. there you show a couple of screenshots with different emphasis on the ssao. so i was wondering which parameter needs to be changed in order to achieve a "stronger" ssao-effect. i already tried playing with the RADIUS and also added the COEF in the geom_ps shader which was suggested by Nargil but unfortunately without satisfying results. these parameters seem to only affect the size of the ssao but not the brightness of the occluded area (i guess :)).

i'm not that much into shader-programming so i would be really thankful if you could give me a hint... :)

keep up the great work!

thanks
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Re: SSAO Compositor

Post by nullsquared »

For the "strength" of the brightness, you can raise the final return value in the SSAO shader to a power greater than one:

Code: Select all

// make occlusion "stronger"
occ = pow(occ, 2); // or 1.5 or something, or perhaps higher than 2 if you want
return float4(occ, occ, occ, 1);
Just note that SSAO is rather local (as you can see in your screenshot, it only shades small creases) - it's meant more for object-object occlusion, whereas "world" occlusion (your buildings) would look better with some more global occlusion, such as precomputed/baked AO.
rbma
Gnoblar
Posts: 4
Joined: Mon Jul 20, 2009 10:06 am

Re: SSAO Compositor

Post by rbma »

that's exactly what i was looking for.

thank you very much!
scratchyrice
Gnome
Posts: 360
Joined: Thu Apr 27, 2006 9:14 pm
Location: United Kingdom - England
x 16

Re: SSAO Compositor

Post by scratchyrice »

Looking awesome! However, Before i use it in my project, How comes this demo runs so much slower than the older soft shadow demo? ATM, i have caelum + hydrax implemented, And they are both required for the game i am producing. So i would like soft shadows, And the old demo gives acceptable framerates (over 800fps!), But this new one even when i disable ssao, It runs at a max of about 100fps. Ive tried replacing all the ogre heads + turous's with just box's but this only gives an extra 20fps so its not a polycout problem.

Cheers
Scratchy

AMD Ryzen 7900x, Gigabyte Nvidia GeForce 3080 10GB, 32GB DDR5

User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Re: SSAO Compositor

Post by nullsquared »

scratchyrice wrote:Looking awesome! However, Before i use it in my project, How comes this demo runs so much slower than the older soft shadow demo? ATM, i have caelum + hydrax implemented, And they are both required for the game i am producing. So i would like soft shadows, And the old demo gives acceptable framerates (over 800fps!), But this new one even when i disable ssao, It runs at a max of about 100fps. Ive tried replacing all the ogre heads + turous's with just box's but this only gives an extra 20fps so its not a polycout problem.

Cheers
Scratchy
Wait, so the original demo I made works a lot faster than the shadows in this demo? That's quite weird... I'll look into it.
scratchyrice
Gnome
Posts: 360
Joined: Thu Apr 27, 2006 9:14 pm
Location: United Kingdom - England
x 16

Re: SSAO Compositor

Post by scratchyrice »

Hmm i had a look into it myself, And actualy the original demo has a lot less complex scene than in the new one, So it is no doubt that. Could you confirm this for me?

Also, How easy would it be to intergrate normal and parralax mapping with soft shadow casting?
Cheers
Scratchy

AMD Ryzen 7900x, Gigabyte Nvidia GeForce 3080 10GB, 32GB DDR5

rbma
Gnoblar
Posts: 4
Joined: Mon Jul 20, 2009 10:06 am

Re: SSAO Compositor

Post by rbma »

hi nullsquared,

i'm having a little more trouble using your ssao compositor. in my application i'm having different renderwindows with different frustum offsets.

using the compositor with the original projection matrix and a frustum offset of Vector2(1.1, 0) results in:
http://img38.imageshack.us/i/originalprojmatrix.png/

i'm currently trying to change the projection matrix to solve this problem.
for example:

Code: Select all

        
static const Ogre::Matrix4 CLIP_SPACE_TO_IMAGE_SPACE(
            0.15,    0,    0,  0.75,
            0,   -0.5,    0,  0.5,
            0,      0,    1,    0,
            0,      0,    0,    1);
results in:
http://img33.imageshack.us/i/projmatrix1.png/

Code: Select all

        
static const Ogre::Matrix4 CLIP_SPACE_TO_IMAGE_SPACE(
            0.15,    0,    0,  0.7,
            0,   -0.5,    0,  0.5,
            0,      0,    1,    0,
            0,      0,    0,    1);
results in:
http://img33.imageshack.us/i/projmatrix2.png/

so it does get better somehow. i was trying different values also, but couldn't get any better results.

what do you think? is changing the projection matrix the right approach to fix this?
User avatar
Noman
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 714
Joined: Mon Jan 31, 2005 7:21 pm
Location: Israel
x 2

Re: SSAO Compositor

Post by Noman »

I'm almost done integrating the SSAO compositor in the deferred shading demo. Now that depth is stored linearly, one of my GBuffer textures is the exact one that the compositor generates, so I can reference it instead of having to render the scene with the 'geom' scheme.

All I had to do to integrate it was to change the channels that the shader was adressing (your demo was depth,norm.x,norm.y,norm.z, mine is norm.x,norm.y,norm.z,depth).

The current SSAO buffer looks like this :
(Ignore the orange line, thats PerfHUD)
Original :
Image
Blurred :
Image

Something isn't perfect yet, and I'm guessing it has to do with the different metrics that the apps use.
From looking at the shader, it seems that

Code: Select all

#define RADIUS 0.2125
Is the only place that has a constant that might be related to the metrics of the geometry.
Am I missing something? (While I try to play around with that value)