[SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Threads related to Google Summer of Code
Locked
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
Contact:

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by Noman »

Finished the GBuffer material/shader generation for now. Only basic combinations are supported for now (textured/untextured, normal mapped / regular normal calculation, skinned / unskinned), but they do cover quite a bit of 'everyday objects'. I'll add support for more stuff if its needed, and the code is built for modifications to be possible.

This allowed me to remove a big chunk of shaders, program definitions and materials from the DeferredShadingMedia directory, while still being 100% compatible with the previous demo. This will allow me to change the scene (when I find the art that I need) more easily, as I won't have to manually adjust each material to fit.

The code is also in a pretty organised state, so if anyone is interested they can look at the SVN branch for early bird access. (The relevant files are in Samples\DeferredShading, GBufferSchemeHandler / GBufferMaterialGenerator).
Next up is refactoring the lighting shaders to cg as well. I won't generate these on the fly, as the number of combinations is pretty limited. I'll probably have a shader for each type of light (point, spotlight and directional) with an option (preprocessor define?) for shadow support.
I'll also have to build the cone for the spotlight geometry and stuff like that, but thats part of the fun innit.

After that I'll have to make a final choice between linear and projective depth, and start adding implementing shadow support for deferred shading...
User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19269
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 66
Contact:

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by sinbad »

Sounds good. I've been looking at the commits as they come through and they look good, although I'm only seeing fragments so I need to take a proper look soon...

I strongly advise using linear depth and not projective depth for your shadows. I'm using all linear depth for my depth shadow projects now and its considerably easier to cope with and far, far more reliable. You can use the attenuation range on spotlights as a scalar, for directional lights I've found a fairly arbitrary fixed range like 1:100000 works surprisingly well for almost all scenes, so long as you combine it with a shadow far distance.
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
Contact:

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by Noman »

I am seriously considering changing to linear depth, but since I'm refactoring the demo more than rebuilding it (which is a decision I made, to be able to make sure that I don't break anything each step) I want to finish converting it all to CG before I start making functional changes.
When I'm done, I'll be down from ~50 material/program/shader files to about 10. This will make it a whole lot easier to make such changes.

I encountered some DX<->GL differences. Currently stuck with one that is affected by the fact that they handle depth values in a different range. Long story short, the GL version of the shader needs to divide a certain value by two, while the DX version doesn't. So, I need the shader to somehow know what RS it will run on, either at compile time or at runtime. I've heard of using ACT_RENDER_TARGET_FLIPPING for this manner, but the GL win32 window does NOT require texture flipping, so it can't be used. Still looking for a solution for this one...
Besides that, GL is showing some inaccuracies, probably because i chose the HLSL shaders to convert to CG, since they are almost identical. However, I am less afraid of creating inaccuracy issues at this stage because I will have to make sure that I am accurate on both rendersystems when I change to linear depth.

I also encountered this bug when using CG 2.2 to compile my shaders, so I added a fix to the CGProgramManager plugin to fix it (the forum thread solution changed the DX9 rendersystem, which isn't the right place for that IMO). We'll decide what to do with this patch/hack when merge time comes (if NVIDIA hasn't fixed it by then).

Speaking of linear depth - if I use linear depth for the GBuffer building, is it possible to calculate normal (projective) depth to output to the standard buffer? The reason I want to do this, is to be able to render objects after the deferred shading stage (classic example would be semi-transparent objects), and they need to interact with the depth of the original scene, which was calculated differently.

In other stories, I'm still searching for art for the next version of the demo. Considering using the static scene in The omnidirectional shadow mapping demo from GPU Gems . Just need to make sure that there are no license issues, and I think it will be ok. (Also the converting part, but .x -> lightwave -> ogre should be possible).
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by nullsquared »

Noman wrote: I encountered some DX<->GL differences. Currently stuck with one that is affected by the fact that they handle depth values in a different range. Long story short, the GL version of the shader needs to divide a certain value by two, while the DX version doesn't. So, I need the shader to somehow know what RS it will run on, either at compile time or at runtime. I've heard of using ACT_RENDER_TARGET_FLIPPING for this manner, but the GL win32 window does NOT require texture flipping, so it can't be used. Still looking for a solution for this one...
Besides that, GL is showing some inaccuracies, probably because i chose the HLSL shaders to convert to CG, since they are almost identical. However, I am less afraid of creating inaccuracy issues at this stage because I will have to make sure that I am accurate on both rendersystems when I change to linear depth.
Just do something like this:

Code: Select all

// generic
float fixDepth(float d)
{
    return d;
}

// specific fix for the gl profile(s)
arbfp1 float fixDepth(float d)
{
    return d * 0.5;
}
CG automatically chooses the correct function based on the profile you used to compile it with.
I also encountered this bug when using CG 2.2 to compile my shaders, so I added a fix to the CGProgramManager plugin to fix it (the forum thread solution changed the DX9 rendersystem, which isn't the right place for that IMO). We'll decide what to do with this patch/hack when merge time comes (if NVIDIA hasn't fixed it by then).
Me too. My question is why you need to output to DEPTH?
Speaking of linear depth - if I use linear depth for the GBuffer building, is it possible to calculate normal (projective) depth to output to the standard buffer? The reason I want to do this, is to be able to render objects after the deferred shading stage (classic example would be semi-transparent objects), and they need to interact with the depth of the original scene, which was calculated differently.
I don't get it. Ogre should be sharing the depth buffer between the GBuffer and whatever you're rendering to in the end (as long as they are the same size). Linear depth in the gbuffer has nothing to do with standard depth in the hardware Zbuffer.
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
Contact:

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by Noman »

Whoa! Didn't know about that syntax option for CG. The code you just posted compiles just like that? Sweet!

About the 'why' : I'm still refactoring the old demo, which synchronized Gbuffer<->Scene depth by writing depth during the same pass that writes the ambient color to the main buffer, before the lighting starts. I understand what you're saying about sharing the depth buffer between the GBuffer and the output render target. I didn't research into what ogre does for sharing depth buffers between different targets. Don't know if its done currently, or how hard it would be to add support for such a feature (although, I have to admit it makes sense). Will probably dive into that a bit tomorrow. Thanks for the heads up!
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by nullsquared »

Noman wrote:Whoa! Didn't know about that syntax option for CG. The code you just posted compiles just like that? Sweet!
Yup. I had the same reaction when I learned about it :mrgreen:
Don't know if its done currently, or how hard it would be to add support for such a feature
It's already done (and has been done for a while now) you shouldn't need to do anything other than use a GBuffer with the same size as the main render target, and make sure you don't clear the Zbuffer in between rendering the Gbuffer and rendering the other stuff.

And if you really need to "restore" the depth buffer, here is what I do:

Code: Select all

float finalDepth(float4 p)
{
    // normally it's in [-1..1]
    return p.z / p.w;
}

arbfp1 float finalDepth(float4 p)
{
    // GL needs it in [0..1]
    return (p.z / p.w) * 0.5 + 0.5;
}

float4 restore_depth_buffer_ps(/* screen-space shader parameters */,
    uniform float4x4 pMat,
    out float oDepth : DEPTH): COLOR0
{
    float3 viewPos = /* calculate your view-space position with whatever depth metric you used */;

    float4 p = mul(pMat, float4(viewPos, 1));

    oDepth = finalDepth(p);

    return float4(1, 0, 1, 1); // just to satisfy the shader compiler - but make sure you turn colour writes off
}
Just FYI, you're gonna encounter trouble if you have depth_write on but depth_check off. Make sure both are on (initially I only had depth_write on and nothing got written to the Zbuffer).
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
Contact:

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by Noman »

Awesome stuff, thanks!
I'll use this to finish up the move to CG tomorrow, maybe I'll even get to linear depth. Much easier now :)
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
Contact:

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by Noman »

Finished the switch to CG. No more hlsl/glsl! Now have much less scripts to worry about when I want to change something, so experimenting is a lot easier.

Tried doing what you said about not re-filling the depth buffer, but it doesn't seem to work. I PerfHUDed my way and all the render passes are correct (IE nobody who shouldnt be writing depth does it) and I debugged to check when the depth buffer gets cleared, and it happens just once in the beginning of every frame.
And yet, the mini-lights are never hidden, even when they are behind the model.

I might make the move to linear depth and reconstruct the projective depth buffer from there, but it does feel a bit silly...
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by nullsquared »

Noman wrote:Tried doing what you said about not re-filling the depth buffer, but it doesn't seem to work. I PerfHUDed my way and all the render passes are correct (IE nobody who shouldnt be writing depth does it) and I debugged to check when the depth buffer gets cleared, and it happens just once in the beginning of every frame.
And yet, the mini-lights are never hidden, even when they are behind the model.
That's weird. Perhaps it has something to do with the GBuffer format? My Gbuffer consists of 4 RGBA8 targets, and my light buffer is also an RGBA8 target, so maybe the formats matter. I'm sure sinbad can provide more info here.
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
Contact:

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by Noman »

More progress...

With the help of nullsquared, I've almost completed the switch to linear depth.
The generated shaders now output linear depth to the GBuffer, and the lighting shaders almost completely use the new data correctly.
I've manage to reconstruct the depth buffer from the linear depth buffer (ZBuffer sharing isn't working, hopefully I'll work it out), so its now truly possible to render objects normally after the deffered stage, with respect to the scene's depth.

Its not all perfect yet - there's a lighting calculation problem that I haven't worked out yet.
Here you can see two examples of how it all looks together :
Image
Image
Something doesn't add up correctly.

To track this problem down, I show only the light accumulation from a single light..
One of the problems is the fact that the plane returns too much light :
Image

The other problem is that it seems that when the light is higher up, it affects the model less. Compare the following two pics :
Image
Image
They just seem to behave... Differently.

If anyone has any guesses what might cause these visual problems, I'd love to hear suggestions.

Tomorrow I'll hopefully track these problems down and the project will be 100% linear depth, allowing me to truly move to new capabilities.
The improvement list is :
A) Change to art that shows off a deferred renderer's advantages better. Transparent objects can now be supported as well!
B) Add spotlight support
C) Add optional compositors - nullsquared's SSAO and maybe anti-aliasing using edge detection based blurring
D) Add shadow support

But before that, I have to finish tracking down these bugs... *Sigh*
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by nullsquared »

1) can I see the shader you used for the final lighting?

2) how are you blending the lights? I don't understand how you can do additive lighting if the skybox is rendered first.
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
Contact:

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by Noman »

(I think that) additive blending works even tho the skybox has been rendered, because the distance between the light position and the view position of that pixel is so big that the lighting calculation does not affect the final picture at all.

The shaders that are used are :

LightMaterial_vs.cg and LightMaterial_ps.cg. (These links should always point to the latest SVN version)

They are currently a mix-and-match between the old version (projective depth and all) and the new version, although the calculations seem fine (and the directional light is working fine).
This causes me to suspect the vertex shader. I did some things differently than my discussion with you, because thats how it was in the previous demo (and it used to work).

Tomorrow I'll probably start debugging side by side against the working revision that used cg and projective depth and work the differences out...
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
Contact:

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by Noman »

Well, with the help of nullsquared, we pinpointed the problem to some calculations being made in the vertex side instead of the fragment side.
Moved some code around, and the result :

Image
Image
Image

Once again, huge thanks to nullsquared!


I might try and move some things back to vertex side later for optimization's sake, but that can wait. Next step is to clean up everything I've done till now, and then I'll start adding capabilities.
I think I'll start with the scene change...

Game on!
User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19269
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 66
Contact:

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by sinbad »

Well done! And thanks nullsquared, you're a trooper :)
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by nullsquared »

Image


:mrgreen:
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
Contact:

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by Noman »

More progress :

- SSAO now works correctly with the demo. Some constants need to be tweaked for the scene/metrics, but I'm waiting with that for the new demo scene (which will hopefully come soon)
- Spotlights now supported! Here is a debug view of the cone mesh and the spotlight attenuation calculation :
(White will get lit more, the spotlight is above the ogre head, pointing down)
Image
- Code is clear. Soon the 'this demo uses a heavily hacked version of the compositor system' will be removed from the opening statements :)
The main improvement is that lights now get completely treated as lights - if the shader that renders the geometry for a certain lights has an auto-param that is related to the light, ogre's AutoParamDataSource will give it the correct one.

I noticed that the spotlight was not showing on the terrain (don't have a pic, but it happens). I traced the problem down to the fact that the normals of the curved planes are not correct. Their Y axis is negative! I went to see the code, and found this in OgreMeshManager.cpp :

Code: Select all

if (params.normals)
                {
                    // This part is kinda 'wrong' for curved planes... but curved planes are
                    //   very valuable outside sky planes, which don't typically need normals
                    //   so I'm not going to mess with it for now. 

                    // Default normal is along unit Z
                    //vec = Vector3::UNIT_Z;
                    // Rotate
                    vec = rot.transformAffine(vec);
					vec.normalise();

                    *pFloat++ = vec.x;
                    *pFloat++ = vec.y;
                    *pFloat++ = vec.z;
                }
I guess the normals are wrong indeed :)
But anyway, thats not up to me. I might look into fixing it if I have time, but I'd rather concentrate on things related directly to my project.

Next up on the list :
1) Handle being inside a light's area of effect. I can either switch to full screen quad when that happens, or reverse culling mode and turn depth check off when rendering the light geometry. I'll probably go for the latter, it seems to be the common solution in deferred shading systems.
2) Demo art - currently a bit troubled with the model I'm trying to export - this is the thread explaning my two problems. I hope to get an answer about the license, and then I'll probably be able to work the exporting technical difficulties out. (Maybe I'll write a small app that identifies identical materials and merges their submeshes)

When those two are done, I'll make the scene switch and have a cool demo. Then only shadows will be left.
I'm already in the optional stages of the project (besides the pre-submission cleanup), so I'm just running as far as I can with it...
(I really want to see the shadows in, so I'll continue even after GSoC if I don't make it in time, cause it will be TOO COOL)
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by nullsquared »

Noman wrote:or reverse culling mode and turn depth check off when rendering the light geometry. I'll probably go for the latter, it seems to be the common solution in deferred shading systems.
Don't turn the depth check off, just turn it to Ogre::CMPF_GREATER (similarly, when you're outside of the light, it should be CMPF_LESS).

There's also the option of doing ZPass (or ZFail if you're inside the light) stenciling. Exact same idea as stencil shadows, except you'd be doing it for lighting, not shadowing. For example, ZFail is very easy to implement (and works even if you're outside the light, even though you might want to switch to ZPass then):
- clear stencil to 0
- render back faces with Ogre::CMPF_GREATER, and set stencil to replace with ref value 2
- render front faces and Ogre::CMPF_LESS, and set stencil to decrement
- render light with stencil Ogre::CMPF_EQUALS and ref value 1
This means that only geometry that actually intersects the light will be lit.

(I couldn't do this optimizations since my portals use the stencil buffer for other things, so I just use the simple ZBuffer less/greater trick)
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
Contact:

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by Noman »

Hm... Yea, CMPF_GREATER makes more sense than depth check off :)

As for the overdraw-related optimizations - its more important for me for this solution to be easily understandable than to be super-efficient. I prefer using a simpler set of techniques, so that people who check the demo's code will be able to understand how it works and how it interacts with ogre.
It will be designed to be extendable, so if someone who has a deeper understanding of deferred shading will want to use it in his app, he will able to use it as a starting block and extend what I've done.
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by nullsquared »

Noman wrote: As for the overdraw-related optimizations - its more important for me for this solution to be easily understandable than to be super-efficient. I prefer using a simpler set of techniques, so that people who check the demo's code will be able to understand how it works and how it interacts with ogre.
It will be designed to be extendable, so if someone who has a deeper understanding of deferred shading will want to use it in his app, he will able to use it as a starting block and extend what I've done.
Alright, whatever floats your boat :mrgreen:

(in fact, for small lights, the cost of the stenciling will be greater than than small overdraw)
User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19269
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 66
Contact:

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by sinbad »

Good stuff - yeah, stencilling light extremities can definitely be an extension later on but is not essential immediately.

One thing though - the spotlight doesn't look like it's completely fallen off at the edge of the geometry, I would have expected the values around the edge of the cone to be black, not grey. Is that just a shader problem or is the cone not wide enough?
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
Contact:

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by Noman »

There were some trigonometric calculations that I wasn't sure of. Your comment and some pen&paper work convinced me I was right.
Fixed the radius calculation of the cone light, and this is the result :

Image

It becomes black just before the edge of the geometry (I was able to find pixels with RGB value of 2,2,2 out of 255 on the edge) so I think I got it right this time.


In other news, I got permission to use the sibenik cathedral model (the same one from the SSAO sample from the NVIDIA DirectX SDK), so I think I'll try to build the new scene around it. It is also available in blender format, so the exporting to Ogre shouldn't be that difficult...
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
Contact:

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by Noman »

Sneak preview of whats coming up :

Image

Much more work to be done, but progress is coming along... There are still problems with the main model (I used a .3ds version of it and then used 3ds2mesh, I think some things didn't convert perfectly), hopefully I'll be able to get a 100% accurate conversion soon.
Vectrex
Ogre Magi
Posts: 1266
Joined: Tue Aug 12, 2003 1:53 am
Location: Melbourne, Australia
x 1
Contact:

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by Vectrex »

It's like a mini-christmas every screenshot :)
I could try and convert it if you like. What's wrong with it? If it's normals you could probably fix it with MeshMagic
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
Contact:

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by Noman »

Its more than that - I've seen some missing geometry and inconsistent materials - some semi-transparent objects are transparent from one side and opaque from the other.
(I did these tests without deferred shading to make sure that it wasn't my pipeline that was causing these effects)

I explained some of my problems in this thread. It also contains download information etc.
I'd really appreciate help from someone with experience with these tools. If you want more info (screenshots of problematic geometry etc) I'm willing to do anything that I can do to help someone help me. Contact me privately if you want more information.
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
x 179
Contact:

Re: [SoC 2009 - Accepted] Improve Ogre's Compositor Framework

Post by jacmoe »

Maybe you could use the assets from http://www.robg3d.com/downloads.html ?
It's got a cathedral..
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.
Locked