I will kneel before you <3SamiTheGreat wrote:Getting it work with FSAA would be nice feature so I will look if I can do something about it
[WIP] HB ambient occlusion for Ogre
-
- OGRE Expert User
- Posts: 1148
- Joined: Sat Jul 06, 2013 10:59 pm
- Location: Chile
- x 168
Re: [WIP] HB ambient occlusion for Ogre
- dark_sylinc
- OGRE Team Member
- Posts: 5292
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1278
- Contact:
Re: [WIP] HB ambient occlusion for Ogre
This is the GLSL & HLSL shaders I used to downsample depth:
Changing it to handle MSAA textures should be a no-brainer (it's the same work, but you use a Texture2DMS and sample the 4 MSAA subsamples instead of sampling the 4 neighbouring samples).
The only annoying part is providing multiple shaders / or recompiling the same one that can handle the MSAA sample count being used (or no MSAA).
With Compute Jobs it's easy because shaders go through the Hlms and you can ask the Hlms whether this is an MSAA texture, and how many samples are required (honestly IMO that is awesome, but my opinion is obviously biased ). If MSAA count changes, the shader gets recompiled
However low level materials didn't get that feature yet, so you have to get that info and recompile yourself.
Code: Select all
#version 330
uniform sampler2D depthTexture;
vec4 gl_FragCoord;
out float gl_FragDepth;
void main()
{
float fDepth0 = texelFetch( depthTexture, ivec2(gl_FragCoord.xy * 2.0), 0 ).x;
float fDepth1 = texelFetch( depthTexture, ivec2(gl_FragCoord.xy * 2.0) + ivec2( 0, 1 ), 0 ).x;
float fDepth2 = texelFetch( depthTexture, ivec2(gl_FragCoord.xy * 2.0) + ivec2( 1, 0 ), 0 ).x;
float fDepth3 = texelFetch( depthTexture, ivec2(gl_FragCoord.xy * 2.0) + ivec2( 1, 1 ), 0 ).x;
//gl_FragDepth = texelFetch( depthTexture, ivec2(gl_FragCoord.xy * 2.0), 0 ).x;
gl_FragDepth = min( min( fDepth0, fDepth1 ), min( fDepth2, fDepth3 ) );
}
Code: Select all
struct PS_INPUT
{
float2 uv0 : TEXCOORD0;
};
Texture2D<float> depthTexture : register(t0);
float main
(
PS_INPUT inPs,
float4 gl_FragCoord : SV_Position
) : SV_Depth
{
float fDepth0 = depthTexture.Load( int3( int2(gl_FragCoord.xy * 2.0), 0 ) ).x;
float fDepth1 = depthTexture.Load( int3( int2(gl_FragCoord.xy * 2.0) + int2( 0, 1 ), 0 ) ).x;
float fDepth2 = depthTexture.Load( int3( int2(gl_FragCoord.xy * 2.0) + int2( 1, 0 ), 0 ) ).x;
float fDepth3 = depthTexture.Load( int3( int2(gl_FragCoord.xy * 2.0) + int2( 1, 1 ), 0 ) ).x;
//return depthTexture.Load( int3( int2(gl_FragCoord.xy * 2.0), 0 ) ).x;
return min( min( fDepth0, fDepth1 ), min( fDepth2, fDepth3 ) );
}
The only annoying part is providing multiple shaders / or recompiling the same one that can handle the MSAA sample count being used (or no MSAA).
With Compute Jobs it's easy because shaders go through the Hlms and you can ask the Hlms whether this is an MSAA texture, and how many samples are required (honestly IMO that is awesome, but my opinion is obviously biased ). If MSAA count changes, the shader gets recompiled
However low level materials didn't get that feature yet, so you have to get that info and recompile yourself.
- SamiTheGreat
- Bronze Sponsor
- Posts: 102
- Joined: Sat Aug 30, 2008 11:57 am
- Location: Finland
- x 8
Re: [WIP] HB ambient occlusion for Ogre
Hello everyone! I made research about real HBAO and I decided to continue with this hemisphere SSAO because otherwise I would need to rewrite whole system from scrath. Good news are that I was managed to fix those artifacts while running on DirectX Many hours I tried to figure out what the heck is wrong with the shader and then I noticed that HLSL mul function makes difference if parameters are in different order... I changed this line: float3 oSample = mul(TBN, sNoise) to this: float3 oSample = mul(sNoise, TBN) and voila, no artifacts anymore Another bug was that I normalized sample vector in the shader and that caused samples to be taken always at the same distance. Now occlusion is much more smoother.
Result looks like this: (note, it is rendered as half resolution so image is not that sharp as earlier)
Next, I will take a look of FSAA issue and write better blur shader that uses depth. In NVIDIA slides was said that blur should be done in full resolution to prevent screen edge area artifacts.
EDIT: I implemented a better blur using vertical and horizontal gaussian pass and comparing depths. The result is much much more better now.
Result looks like this: (note, it is rendered as half resolution so image is not that sharp as earlier)
Next, I will take a look of FSAA issue and write better blur shader that uses depth. In NVIDIA slides was said that blur should be done in full resolution to prevent screen edge area artifacts.
EDIT: I implemented a better blur using vertical and horizontal gaussian pass and comparing depths. The result is much much more better now.
Last edited by SamiTheGreat on Mon Jun 11, 2018 10:06 am, edited 3 times in total.
-
- OGRE Expert User
- Posts: 1148
- Joined: Sat Jul 06, 2013 10:59 pm
- Location: Chile
- x 168
Re: [WIP] HB ambient occlusion for Ogre
holy poop that's amazing!!
you should disable Vsync to see the actual fps and how every filter affect performance
you should disable Vsync to see the actual fps and how every filter affect performance
- dark_sylinc
- OGRE Team Member
- Posts: 5292
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1278
- Contact:
Re: [WIP] HB ambient occlusion for Ogre
Holy SSAO that looks great!
-
- Gremlin
- Posts: 184
- Joined: Sat Apr 16, 2016 9:25 pm
- x 19
Re: [WIP] HB ambient occlusion for Ogre
Looking much better!
I am curious what difference there is between your approach and "proper" HBAO, when it comes to quality, performance, or any other interesting metric.
Edit: And if it's not a hassle, it would be sweet if you would push the changes to your bitbucket repo, so that we can try it out as well.
I am curious what difference there is between your approach and "proper" HBAO, when it comes to quality, performance, or any other interesting metric.
Edit: And if it's not a hassle, it would be sweet if you would push the changes to your bitbucket repo, so that we can try it out as well.
- SamiTheGreat
- Bronze Sponsor
- Posts: 102
- Joined: Sat Aug 30, 2008 11:57 am
- Location: Finland
- x 8
Re: [WIP] HB ambient occlusion for Ogre
"Proper" HBAO is made by rotating sample kernel and finding horizon (the highest tangent angle) and comparing fragment's normal tangent and horizon tangent. You will get better results in HBAO with lower samples than in SSAO. However calculating tangents and finding horizon takes extra time. In original SSAO you just cast ray samples around spherical sample kernel and check if sample occludes the fragment. In this case, I use hemispherical sample kernel pointing to fragment's normal direction so samples are never taken "inside of object" to prevent self occlusion.zxz wrote:Looking much better!
I am curious what difference there is between your approach and "proper" HBAO, when it comes to quality, performance, or any other interesting metric.
Edit: And if it's not a hassle, it would be sweet if you would push the changes to your bitbucket repo, so that we can try it out as well.
I made performance test using RenderDoc to see timings.
Code: Select all
NVIDIA GTX 580
DEBUG, FULL HD (1920x1080) windowed, half resolution SSAO, full resolution blur, 64 SSAO samples
Frametime 6.52 ms
Scene render 0.78938 ms
SSAO 4.095 ms
BlurH 0.7225 ms
BlurV 0.7224 ms
Apply 0.157 ms
AO SUM: 5.6969 ms (0.0056969 s)
FPS: 153,3 frames per second
I will not push this version yet because I have to write the new blur shader for OpenGL also. In addition, shader code need to be clened up because there is alot of mess because of my experiments
- SamiTheGreat
- Bronze Sponsor
- Posts: 102
- Joined: Sat Aug 30, 2008 11:57 am
- Location: Finland
- x 8
Re: [WIP] HB ambient occlusion for Ogre
Hi! The newest version is now available and I've pushed it to my fork. FSAA support is not included since it would have made code too messy. Enabling it should be easy. Just add quad pass before SSAO using shaders that dark_sylinc provided earlier to downsample depth before using it in SSAO (or better, make a new compositing node to render scene and give output to downsample node and then pass result to ssao node). I also made little modifications to blur shader to increase its performance and cleaned up all shader code.
I hope that you guys like it!
EDIT: I can make another version using FSAA and share it via zip file here if you need it. FSAA support is a feature that we need so I will code it anyway.
I hope that you guys like it!
EDIT: I can make another version using FSAA and share it via zip file here if you need it. FSAA support is a feature that we need so I will code it anyway.
-
- OGRE Expert User
- Posts: 1148
- Joined: Sat Jul 06, 2013 10:59 pm
- Location: Chile
- x 168
Re: [WIP] HB ambient occlusion for Ogre
=D! I am going to try this later
btw, theres a typo in the tutorial explanation (Tutorial_SSAO.cpp) "horizontal based amibent occlusion" and I think you mean Horizon, no Horizontal (??? or are the same???)
btw, theres a typo in the tutorial explanation (Tutorial_SSAO.cpp) "horizontal based amibent occlusion" and I think you mean Horizon, no Horizontal (??? or are the same???)
- SamiTheGreat
- Bronze Sponsor
- Posts: 102
- Joined: Sat Aug 30, 2008 11:57 am
- Location: Finland
- x 8
Re: [WIP] HB ambient occlusion for Ogre
Yeah, it should be horizon if it was "real" horizon based ao I forgot to rewrite explanation.. I will fix that. BTW I renamed this AO to HSAO (hemisphere ambient occlusion) since it describes it better.xrgo wrote:=D! I am going to try this later
btw, theres a typo in the tutorial explanation (Tutorial_SSAO.cpp) "horizontal based amibent occlusion" and I think you mean Horizon, no Horizontal (??? or are the same???)
- SamiTheGreat
- Bronze Sponsor
- Posts: 102
- Joined: Sat Aug 30, 2008 11:57 am
- Location: Finland
- x 8
Re: [WIP] HB ambient occlusion for Ogre
Hi! I wanted to ask what is the state of merge progress? It appears that this hasn't been merged yet to Ogre 2.1 so far. I am currenly integrating my SSAO for our game engine and I remembered that dark_sylinc had some performance fix earlier to fix some depth buffer issues (that FPS drop when zooming close to the objects). If you don't have time to check this out, I can try to fix the issue for the newest version if you could send me some more information about the issue.
- dark_sylinc
- OGRE Team Member
- Posts: 5292
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1278
- Contact:
Re: [WIP] HB ambient occlusion for Ogre
So it's ready to be merged by your standards? I was waiting for you to tell me to take a new look.
Right now I'm extremely busy (contract work + Metal), so I think it may be quite a while until I can take a look at your SSAO again (think ~7 weekends). If suddenly I become more available I may be able to take a look earlier. I really want to push this into main repo, subjectively speaking looks really good.
Cheers
Matias
Right now I'm extremely busy (contract work + Metal), so I think it may be quite a while until I can take a look at your SSAO again (think ~7 weekends). If suddenly I become more available I may be able to take a look earlier. I really want to push this into main repo, subjectively speaking looks really good.
Cheers
Matias
- GlowingPotato
- Goblin
- Posts: 211
- Joined: Wed May 08, 2013 2:58 pm
- x 10
Re: [WIP] HB ambient occlusion for Ogre
I can say that we are using your AO code and its working flawless.
It does have bugs when using with FSAA, but since we are using FXAA 3.1, this is not an issue for us.
It does have bugs when using with FSAA, but since we are using FXAA 3.1, this is not an issue for us.
- dark_sylinc
- OGRE Team Member
- Posts: 5292
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1278
- Contact:
Re: [WIP] HB ambient occlusion for Ogre
I'm just here to tell you I'm integrating your code. Done some performance improvements.
Turns out your demo uncovered a bug!
I was puzzled by this:
It made no sense to multiply by 2.0; it shouldn't have been there (D3D doesn't need it). Turns out "depth_copy" pass was affecting the GL Viewport state, without restoring it; thus causing a bug which you could counter by multiplying by 2.0.
But still GL & D3D diverged a little.
Now that the bug is fixed the 2.0 isn't needed anymore, and OpenGL version looks the same as D3D.
Turns out your demo uncovered a bug!
I was puzzled by this:
Code: Select all
float fDepth = texture( depthTexture, uv*2.0).x; //multiply uv coords by 2 because we are working with half res
But still GL & D3D diverged a little.
Now that the bug is fixed the 2.0 isn't needed anymore, and OpenGL version looks the same as D3D.
- SamiTheGreat
- Bronze Sponsor
- Posts: 102
- Joined: Sat Aug 30, 2008 11:57 am
- Location: Finland
- x 8
Re: [WIP] HB ambient occlusion for Ogre
Thanks for the bug fixes and optimization! Giving sample vector as uniform inputs is indeed better solution since sampling the texture is not needed anymore. I got also one optimization idea for blur shaders. Depth could be linearized with projectionParams to temp texture so we don't need to do it two times (now it calculates it in both vertical and horizontal blur). I am not sure if it worth since it is tradeoff between performance and memory.dark_sylinc wrote:I'm just here to tell you I'm integrating your code. Done some performance improvements.
Turns out your demo uncovered a bug!
I was puzzled by this:It made no sense to multiply by 2.0; it shouldn't have been there (D3D doesn't need it). Turns out "depth_copy" pass was affecting the GL Viewport state, without restoring it; thus causing a bug which you could counter by multiplying by 2.0.Code: Select all
float fDepth = texture( depthTexture, uv*2.0).x; //multiply uv coords by 2 because we are working with half res
But still GL & D3D diverged a little.
Now that the bug is fixed the 2.0 isn't needed anymore, and OpenGL version looks the same as D3D.
-
- OGRE Expert User
- Posts: 1148
- Joined: Sat Jul 06, 2013 10:59 pm
- Location: Chile
- x 168
Re: [WIP] HB ambient occlusion for Ogre
Hello! I tried to use this SSAO in my project but I get this glitches:
I am using it as is, just copied all the files and using the same workspace as the sample, and included the lines that creates the kernel samples and noise texture.
maybe someone recognize the error?
Thanks!
I am using it as is, just copied all the files and using the same workspace as the sample, and included the lines that creates the kernel samples and noise texture.
maybe someone recognize the error?
Thanks!
- dark_sylinc
- OGRE Team Member
- Posts: 5292
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1278
- Contact:
Re: [WIP] HB ambient occlusion for Ogre
Could be that your depth buffer contains garbage (maybe depth sharing ended up using the depth buffer for something unrelated in the middle, destroying its contents).
Could be that something (i.e. uniform parameters) expects the depth buffer to be in a different resolution.
Could be sampler units not being correctly initialized (thus everything is reading from the same tex unit).
Could be that something (i.e. uniform parameters) expects the depth buffer to be in a different resolution.
Could be sampler units not being correctly initialized (thus everything is reading from the same tex unit).
-
- OGRE Expert User
- Posts: 1148
- Joined: Sat Jul 06, 2013 10:59 pm
- Location: Chile
- x 168
Re: [WIP] HB ambient occlusion for Ogre
The problem appears in the SSAO/HS material, the input textures seems correct, depth looksgood and noise texture too (but seems strange to me that it only uses a 2x2 texture).
Then I noticed that I was lacking "psParams->setNamedConstant("projection", mainCamera->getProjectionMatrix());" that in the example is in the "update" method, I put it in the framrenderingqueue and now the output of SSAO/HS looks like this:
Then I noticed that I was lacking "psParams->setNamedConstant("projection", mainCamera->getProjectionMatrix());" that in the example is in the "update" method, I put it in the framrenderingqueue and now the output of SSAO/HS looks like this:
-
- OGRE Expert User
- Posts: 1148
- Joined: Sat Jul 06, 2013 10:59 pm
- Location: Chile
- x 168
Re: [WIP] HB ambient occlusion for Ogre
solved, the problem was this part:
since I am running inside a qt window, for some reason it was giving the wrong width and height
Thanks for this feature, its awesome!!
Code: Select all
psParams->setNamedConstant( "noiseScale", Ogre::Vector2(
( mGraphicsSystem->getRenderWindow()->getWidth() * 0.5f ) / 2.0f,
( mGraphicsSystem->getRenderWindow()->getHeight() * 0.5f ) / 2.0f ) );
Thanks for this feature, its awesome!!