SSAO Compositor
-
Noman
- OGRE Retired Team Member

- Posts: 714
- Joined: Mon Jan 31, 2005 7:21 pm
- Location: Israel
- x 2
Re: SSAO Compositor
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?
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?
-
nullsquared
- Old One
- Posts: 3245
- Joined: Tue Apr 24, 2007 8:23 pm
- Location: NY, NY, USA
- x 11
Re: SSAO Compositor
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.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?
-
lukeneorm
- Halfling
- Posts: 61
- Joined: Wed Apr 01, 2009 12:03 am
Re: SSAO Compositor
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.
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:
-> 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?
-> 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?
-> 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?
-> 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!
first of all THANK YOU nullsquared for your answers. I'm doing a day-by-day step forward in my shader code knowledge.
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);-> 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;Code: Select all
// compute occlusion based on the (scaled) Z difference
float zd = saturate(far * (depth - TEX2DLOD(geomMap, nuv.xy).x));-> 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);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!
-
nullsquared
- Old One
- Posts: 3245
- Joined: Tue Apr 24, 2007 8:23 pm
- Location: NY, NY, USA
- x 11
Re: SSAO Compositor
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.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?
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).Here are some questions about the pixel shader ssao_ps:-> 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?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);
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)-> 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?
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).-> 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
// 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;
The values are normalized in [0..1], we then multiply by the far clip distance to get them back to [0..far_clip] range.-> 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?Code: Select all
// compute occlusion based on the (scaled) Z difference float zd = saturate(far * (depth - TEX2DLOD(geomMap, nuv.xy).x));
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.-> 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 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.-> I read that the occlusion function can be any function that adheres to these criteria: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);
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?
-
_tommo_
- Gnoll
- Posts: 677
- Joined: Tue Sep 19, 2006 6:09 pm
- x 5
Re: SSAO Compositor
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
Anyway it looks like a good idea, maybe it could be replicated in Ogre?
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
Anyway it looks like a good idea, maybe it could be replicated in Ogre?
-
Kencho
- OGRE Retired Moderator

- Posts: 4011
- Joined: Fri Sep 19, 2003 6:28 pm
- Location: Burgos, Spain
- x 2
Re: SSAO Compositor
Yes, I doubt that's legal at all 
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).
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).
-
nullsquared
- Old One
- Posts: 3245
- Joined: Tue Apr 24, 2007 8:23 pm
- Location: NY, NY, USA
- x 11
Re: SSAO Compositor
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
See here: http://www.gamedev.net/community/forums ... _id=527170
-
_tommo_
- Gnoll
- Posts: 677
- Joined: Tue Sep 19, 2006 6:09 pm
- x 5
Re: SSAO Compositor
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
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
-
Kencho
- OGRE Retired Moderator

- Posts: 4011
- Joined: Fri Sep 19, 2003 6:28 pm
- Location: Burgos, Spain
- x 2
Re: SSAO Compositor
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._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
-
_tommo_
- Gnoll
- Posts: 677
- Joined: Tue Sep 19, 2006 6:09 pm
- x 5
Re: SSAO Compositor
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
And the fact that is default in new UE3 games proves it enough to me
-
nullsquared
- Old One
- Posts: 3245
- Joined: Tue Apr 24, 2007 8:23 pm
- Location: NY, NY, USA
- x 11
Re: SSAO Compositor
Notice how he(/she?) moves the camera very slowly and smoothly.
Try the demo. It does not look good in intense motion.
-
Kencho
- OGRE Retired Moderator

- Posts: 4011
- Joined: Fri Sep 19, 2003 6:28 pm
- Location: Burgos, Spain
- x 2
Re: SSAO Compositor
@_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?
@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?
-
_tommo_
- Gnoll
- Posts: 677
- Joined: Tue Sep 19, 2006 6:09 pm
- x 5
Re: SSAO Compositor
I did try the demo and indeed it does NOT look good... even when you stand stillnullsquared wrote:Notice how he(/she?) moves the camera very slowly and smoothly.
Try the demo. It does not look good in intense motion.
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
-
nullsquared
- Old One
- Posts: 3245
- Joined: Tue Apr 24, 2007 8:23 pm
- Location: NY, NY, USA
- x 11
Re: SSAO Compositor
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.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?
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.
-
Kencho
- OGRE Retired Moderator

- Posts: 4011
- Joined: Fri Sep 19, 2003 6:28 pm
- Location: Burgos, Spain
- x 2
Re: SSAO Compositor
Ah, understood. Gotta look deeper into SSAO and other screen space lighting techniques
I know some basics but not the real guts 
-
nullsquared
- Old One
- Posts: 3245
- Joined: Tue Apr 24, 2007 8:23 pm
- Location: NY, NY, USA
- x 11
Re: SSAO Compositor
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.Kencho wrote:Ah, understood. Gotta look deeper into SSAO and other screen space lighting techniquesI know some basics but not the real guts
-
lukeneorm
- Halfling
- Posts: 61
- Joined: Wed Apr 01, 2009 12:03 am
Re: SSAO Compositor
Thank you nullsquared for your explanations!
I have still some questions here..
-> 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):

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:
-> 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.
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. 
I have still some questions here..
-> 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):

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.
-
rbma
- Gnoblar
- Posts: 4
- Joined: Mon Jul 20, 2009 10:06 am
Re: SSAO Compositor
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
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
-
nullsquared
- Old One
- Posts: 3245
- Joined: Tue Apr 24, 2007 8:23 pm
- Location: NY, NY, USA
- x 11
Re: SSAO Compositor
For the "strength" of the brightness, you can raise the final return value in the SSAO shader to a power greater than one:
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.
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);
-
rbma
- Gnoblar
- Posts: 4
- Joined: Mon Jul 20, 2009 10:06 am
Re: SSAO Compositor
that's exactly what i was looking for.
thank you very much!
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
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
Cheers
Scratchy
AMD Ryzen 7900x, Gigabyte Nvidia GeForce 3080 10GB, 32GB DDR5
-
nullsquared
- Old One
- Posts: 3245
- Joined: Tue Apr 24, 2007 8:23 pm
- Location: NY, NY, USA
- x 11
Re: SSAO Compositor
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 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
-
scratchyrice
- Gnome
- Posts: 360
- Joined: Thu Apr 27, 2006 9:14 pm
- Location: United Kingdom - England
- x 16
Re: SSAO Compositor
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
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
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:
results in:
http://img33.imageshack.us/i/projmatrix1.png/
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?
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);
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);
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?
-
Noman
- OGRE Retired Team Member

- Posts: 714
- Joined: Mon Jan 31, 2005 7:21 pm
- Location: Israel
- x 2
Re: SSAO Compositor
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 :

Blurred :

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
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)
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 :

Blurred :

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.2125Am I missing something? (While I try to play around with that value)
