Integrating DPSF

rated by 0 users
This post has 10 Replies | 4 Followers

Top 200 Contributor
Posts 10
SunBurn_Pro_Licensee
helmers Posted: 01-02-2010 11:31 AM

Hi,

I want to integrate DPSF into my Game Engine which uses Sunburn for the graphics. Integration was so far pretty easy but now I'm stuck with one problem.

I draw the particle systems via the ParticleSystemManager. The manager itself is called after EndFrameRendering() (using deffered rendering).

It draws the system but sadly always on top. It disregards the depth buffer! I have checked that the render state is set correctly in the particle effect (depth buffer is enabled).

Trying to call the ParticleSystemManager before EndFrameRendering() doesn't draw anything!

So what is up. It seems that others have alredy integegrated DPSF already. Could someone provide a short list in which sequence the calls have to be done (Sunburn deffered + DPSF) ?

Thanks a lot in advance.

Top 25 Contributor
Posts 136
SunBurn_Community_Licensee
SunBurn_Contributor

The reason it is drawing on top of everything is because SunBurn is set up to add post-processing effects (e.g. HDR) and the depth buffer is filled with the value of the full-screen render. I think you'll need to integrate more deeply by using the depth buffer exposed by SunBurn if you want to have it work with the deferred renderer.

Top 50 Contributor
Posts 95
SunBurn_Community_Licensee
SunBurn_Pro_Licensee

Hi,

This is the code I used to get DPSF integrate into my project (within the draw method):

// Render the scene.

sceneState.BeginFrameRendering(view, projection, gameTime, environment);

editor.BeginFrameRendering(sceneState);

renderManager.BeginFrameRendering(sceneState, bufferManager);

 

renderManager.Render();

 

// Set the World, View, and Projection Matrices for the Particle Systems before Drawing them

mcParticleSystemManager.SetWorldViewProjectionMatricesForAllParticleSystems(world, view, projection);

// Draw the Particle Systems

mcParticleSystemManager.DrawAllParticleSystems();

 

renderManager.EndFrameRendering();

editor.EndFrameRendering();

sceneState.EndFrameRendering();

 

 As you can see the positioning seems okidoki to me ;-)

Kind regards,

Wim

Top 25 Contributor
Posts 197
SunBurn_Community_Licensee
SunBurn_Contributor
SunBurn_Pro_Licensee

Move all your particle draw calls until after sunburn has done it's stuff....

My main draw code in my inherited game class looks like this...

        protected override void Draw(GameTime gameTime)
        {
            ActiveScreen.DrawDeferred(gameTime);
            base.Draw(gameTime);
            ActiveScreen.DrawForward(gameTime);
        }

The Screen class splits the draw phase into a deferred and forward pass - anything i draw with Sunburn's deferred engine in the first pass and everything after using a normal forward pass which i use to draw things like particles any alpha blended objects and HUD overlays etc. I think in the example above that you will lose alpha blending effects since the particle draws occur withing sunburns deferred phase and affect the depth buffer for lighting.

The first call submits all my objects to sunburn for rendering.

        public override void DrawDeferred(GameTime gameTime)
        {


            //Game.GraphicsDevice.Clear(Color.Black);

            foreach (SceneNode node in Game.SceneManager.GetVisibileNodes(Game.ActiveCamera))
            {
                 // SUBMIT ALL YOUR DEFERRED MODELS HERE
            }

        }


base.Draw calls all the base sunburn rendering.

            sceneState.BeginFrameRendering(ActiveCamera.View, ActiveCamera.Projection, gameTime, _environment);
            editor.BeginFrameRendering(sceneState);
            // postProcessManager.BeginFrameRendering(sceneState);
            renderManager.BeginFrameRendering(sceneState, bufferManager);

            renderManager.Render();

            renderManager.EndFrameRendering();
            // postProcessManager.EndFrameRendering();
            editor.EndFrameRendering();
            sceneState.EndFrameRendering();

The third draws any forward pass stuff such as particles after Sunburn has done it's thing.

        public override void DrawForward(GameTime gameTime) {

            foreach (ParticleSystem particleSystem in _particleSystems.Values)
            {
                particleSystem.SetCamera(_game.ActiveCamera.View, _game.ActiveCamera.Projection);
                particleSystem.Draw(gameTime);
            }
        }

In the example above i'm not using Sunburns postprocess, but it works as advertised. I'm guessing the depth buffer restore occurs in sceneState.EndFrameRendering() Since my forward pass works fine. I should have DPSF in my engine in the next few days so if you're still having problems i'll post my code.

And as a handy hint if you're deploying to XBOX don't use foreach calls like i've done above...this is quick and nasty code to demo the idea...

 

Top 25 Contributor
Posts 197
SunBurn_Community_Licensee
SunBurn_Contributor
SunBurn_Pro_Licensee

Just scanning the code above i guess you may have problems if you're using sunburns post process pipeline - i currently don't, but in my code Sunburns post process certainly won't affect my particles but i don't see any post process calls in your code so that shouldn't be the issue.

Top 200 Contributor
Posts 10
SunBurn_Pro_Licensee

Ok, I thinks some answers are due:

At first thanks for the discussion and attempts to solve my problem.

@Wim Vancoillie

I asume you use forward rendering. That code should be OK for this mode. But in deffered mode nothing gets drawn (or is overwritten).

@bamyazi

Basically that is exactly what I am doing currently. So the particles get drawn but they get drawn on top of the deffered renderd objects.

@Raphael

I have the same impression as you. I asume that the depth buffer is reste after the End.. calls. So it makes sense that then the particles are drawn on top and not according to their depth. This would also fit to some hints in other threads mentioning the depth buffer.

 

So my latest attempt in solving this was to play around with the depth buffer.

I tried to fetch the depth buffer before the End.. calls:

depthBuffer = m_RenderManager.GraphicsDeviceManager.GraphicsDevice.DepthStencilBuffer;

And set it again after the Ends but before the particle drawing. The particless are still drawn on top.

Perhaps I only get a "pointer" to the buffer and simply reset the pointers which still point to the erased depth buffer. But I have found no method to copy the depth buffer!

Another aproach was to use a hint from bobthebuilder: To access the depth buffer via the DeferredBufferManager. It is possible to fetch it as a RenderTarget2D. But I found no means to set it later on!

Perhaps bobthebuilder is so kind to provide us with some insight into Sunburn here. Any hint for further investigation is welcome!

I also intensivied my research in the web for particles and deferred rendering. And there are some ideas that can be followed if you have full control over the rendering (which we do not have in Sunburn by intention; which is OK). Most of these techniques asume that the particles should be part of the deferred rendering. That is something I do not need (at least up to now). It is OK if I get my particles drawn pure and unlit as my main focus is on drawing fire, smoke, rain, ... All I need is to get them drawn with correct depth handling.

 

Top 50 Contributor
Posts 95
SunBurn_Community_Licensee
SunBurn_Pro_Licensee

Hi Helmers,

my code was based upon the Simple Integration (Deferred Rendering) template provided with SunBurn 1.2.6. i started a complete new project to test the DPSF integration.

I admit it is only a test I've done without any fancy stuff yet.

 

Top 10 Contributor
Posts 4,546
Employee
SunBurn_Studio_Licensee

Hi guys,

It's best to rendering particles between the calls to Render() and EndFrameRendering().  The particles will blend nicely with the existing scene and the depth buffer is still intact.

On the Xbox PostProcessorManager.EndFrameRendering() will clear the depth buffer (due to Xbox render target behavior), so ideally all scene rendering should be done before this call.  UI and other non-scene elements can be rendered at anytime.

If the particles are not showing up it could be related to a render state set by code elsewhere in the game.  Try creating a quick test project with SunBurn and DPSF and slowly add custom code in until the problem pops up.

Let me know if this helps!

Follow me on Twitter – development and personal tweets
Awesome XNA Videos – Lighting, Rendering, and game videos

Top 50 Contributor
Posts 98
SunBurn_Community_Licensee

Gents,

John is right.  In my game I render both my DPSF particle effects and my weapon swipe trails between Render() and EndFramRendering().  Everything ends up perfectly in the depth buffer.

Top 200 Contributor
Posts 10
SunBurn_Pro_Licensee

OK, I got it!!!

Mea culpa!  Mea maxima culpa!!!

I was very solid in thinking that I have switched my project to Sunburn 1.2.6 but instead I still worked with 1.2.3.

Switching the DLLs and adapting my engine which was easy enough I retried my torch flame test and surprise! Everything works as expected and I got my torch flame hidden by the figure in the foreground.

Sorry for all the trouble I raised and thanks for the help from all of you. A really great community here!

As small thanks here a picture of my torch flame test! Finally hidden behind the figure :-)

Top 25 Contributor
Posts 136
SunBurn_Community_Licensee
SunBurn_Contributor

Cool! That's a nice screenshot. Congrats on getting it working!

Page 1 of 1 (11 items) | RSS