Seperate lighting for sun burn UI sprites

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

Top 75 Contributor
Posts 41
SunBurn_Pro_Licensee
bryanedds Posted: 08-23-2010 11:04 PM

Hi!

I'm experimenting with different UI approaches in the context of a 3D SunBurn game. The UI I'm currently contriving is going to use SunBurn's sprite system. Obviously, I need the UI sprites to have a separate lighting rig than the 3D scene behind it. However, I don't see an obvious way to do this. Can anyone let me know how this is generally done?

thanks!

Top 10 Contributor
Posts 4,546
Employee
SunBurn_Studio_Licensee

Hi bryan,

Probably the easiest way is to create a separate scene interface for the 2D and 3D scenes, then render the 2D scene to a texture, which is applied overtop of the 3D rendered scene.

If both the 2D and 3D scenes use the same rendering type (deferred or forward), then you can also add the shadow manager from one to the other, allowing them to shared graphics resources.

Let me know if this helps!

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

Top 75 Contributor
Posts 41
SunBurn_Pro_Licensee

That sounds feasible, I suppose, but SunBurn's API doesn't allow me to infer how that would implemented.

Here's my current drawing method -


        protected override void Draw(GameTime gameTime)
        {
            // Check to see if the splash screen is finished.
            if (SplashScreenGameComponent.DisplayComplete)
            {
                // Begin rendering the scene.
                sceneState.BeginFrameRendering(camera.View, camera.Projection, gameTime, environment, true);
                sceneInterface.BeginFrameRendering(sceneState, deferredBuffers);

                // Add custom rendering that should occur before the scene is rendered.
                if (physicsBoxDrawer.Visible) physicsBoxDrawer.Draw(camera.View, camera.Projection);

                // Perform rendering.
                sceneInterface.RenderManager.Render();

                // End rendering.
                sceneInterface.EndFrameRendering();
                sceneState.EndFrameRendering();
            }
            base.Draw(gameTime);
        }

Where would I modify it to do what I need?

Top 10 Contributor
Posts 4,546
Employee
SunBurn_Studio_Licensee

Hi bryan,

Depending on how you want to implement this it could look something like:


        protected override void Draw(GameTime gameTime)
        {
            // Check to see if the splash screen is finished.
            if (SplashScreenGameComponent.DisplayComplete)
            {
                GraphicsDevice.SetRenderTarget(renderTargetOf2DScene);

                // Begin rendering 2D scene.
                sceneState.BeginFrameRendering(<need the 2D params here>);
                sceneInterface2D.BeginFrameRendering(sceneState, deferredBuffers);

                sceneInterface2D.RenderManager.Render();

                sceneInterface2D.EndFrameRendering();
                sceneState.EndFrameRendering();

                GraphicsDevice.SetRenderTarget(null);

                // Begin rendering 3D scene.
                sceneState.BeginFrameRendering(camera.View, camera.Projection, gameTime, environment, true);
                sceneInterface3D.BeginFrameRendering(sceneState, deferredBuffers);

                sceneInterface3D.RenderManager.Render();

                sceneInterface3D.EndFrameRendering();
                sceneState.EndFrameRendering();

                // Overlay the 2D image here using some type of blending.
            }
            base.Draw(gameTime);
        }


SunBurn contains helper objects for using render target (RenderTargetHelper) and rendering textures to the screen (FullFrameQuad), or this can be done with a standard xna render target and SpriteBatch.

Let me know if this helps!

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

Top 75 Contributor
Posts 41
SunBurn_Pro_Licensee

EDIT - nevermind!

Top 75 Contributor
Posts 41
SunBurn_Pro_Licensee

Hi again John :D

I'm trying to use FullFrameQuad with BasicEffect, but I am confused about its constructor. It requires a width and height parameter. But if the FullFrameQuad is defined to be the 'full frame', then what meaning do those parameters have? Should I just use [1,1] and assume that means 'full full frame'?

Top 75 Contributor
Posts 41
SunBurn_Pro_Licensee

Nevermind the FullFrameQuad. I finally got a test sprite on the screen with the following code -

        protected override void Draw(GameTime gameTime)
        {
            // Check to see if the splash screen is finished.
            if (SplashScreenGameComponent.DisplayComplete)
            {
                // Accumulate UI sprites.
                uiSprites.Begin();
                uiSprites.Add(testSprite, new Vector2(512), Vector2.Zero, 0, Vector2.Zero, Vector2.One, Vector2.Zero, 0.96f);
                uiSprites.End();

                // UI rendering.
                uiRenderTarget.Activate();
                uiSceneState.BeginFrameRendering(Vector2.Zero, 1280, 1280.0f / 720, gameTime, uiEnvironment, false);
                uiSceneInterface.BeginFrameRendering(uiSceneState, deferredBuffers);
                GraphicsDevice.Clear(ClearOptions.Target, Color.TransparentBlack, 1.0f, 0); // TODO: figure out if I should be using TransparentWhite instead
                uiSceneInterface.RenderManager.Render();
                uiSceneInterface.EndFrameRendering();
                uiSceneState.EndFrameRendering();
                uiRenderTarget.Resolve();

                // Scene rendering.
                sceneState.BeginFrameRendering(camera.View, camera.Projection, gameTime, sceneEnvironment, true);
                sceneInterface.BeginFrameRendering(sceneState, deferredBuffers);
                if (physicsBoxDrawer.Visible) physicsBoxDrawer.Draw(camera.View, camera.Projection);
                sceneInterface.RenderManager.Render();
                sceneInterface.EndFrameRendering();
                sceneState.EndFrameRendering();

                // Copy UI rendering over screen.
                RenderState renderState = GraphicsDevice.RenderState;
                uiSpriteBatch.Begin(SpriteBlendMode.AlphaBlend);
                uiSpriteBatch.Draw(uiRenderTarget.VolatileTexture, Vector2.Zero, null, Color.White);
                uiSpriteBatch.End();
            }
            base.Draw(gameTime);
        }

You'll notice I had to inject a very inefficient 'GraphicsDevice.Clear(ClearOptions.Target, Color.TransparentBlack, 1.0f, 0)' call right after the 'uiSceneInterface.BeginFrameRendering(uiSceneState, deferredBuffers)' call. This is really bad because SceneInterface.BeginFrameRendering somehow invokes a sceen clear of its own. With the injected Clear call, I'm killing fill rate because the BeginFrameRendering call clears the screen in the wrong way, result in an extra, useless screen clear.

How would I configure the BeginFrameRendering process to clear the target with TransparentBlack to avoid my Clear call thereby salvaging the fill rate?

BTW, thanks immensely for all your help so far! You rock :D

Top 10 Contributor
Posts 4,546
Employee
SunBurn_Studio_Licensee

Hi bryan,

You can disable the render manager's clear call using the ClearBackBufferEnabled property (this may require casting the render manager object to BaseRenderManager).

The FullFrameQuad arguments are the width and height of the destination render target.  This allows the quad to align the texture's lexels with the center of the target's pixels (for crisp rendering).

Let me know if this helps!

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

Top 75 Contributor
Posts 41
SunBurn_Pro_Licensee

You've been a great help John!

I have just one last nagging question - what does SceneState.BeginFrameRendering's 'renderingtoscreen' parameter mean? While rendering the UI to its geometry buffer, I set it to true. However, I tried setting it to false and it still works fine AFAIK. I suspect there's a non-trivial performance difference by setting this flag one way or the other, and I'd like to know what that is.

So, I need to know both the semantics and performance implications of that parameter please.

cheers!

Top 10 Contributor
Posts 699
SunBurn_Community_Licensee
SunBurn_Contributor

bryanedds:

what does SceneState.BeginFrameRendering's 'renderingtoscreen' parameter mean? 

Hi,

It's to notify Sunburn if you're using a rendertarget or just rendering right into the backbuffer.

Contributor on the SunBurn sgMotion Animation Library open source project.

Top 10 Contributor
Posts 4,546
Employee
SunBurn_Studio_Licensee

Hi guys,

I want to add a little extra info: the "renderingtoscreen" argument tells SunBurn (and your custom code) when to draw helper objects like in-editor gizmos and object / light icons.  Generally the best time to draw these helpers is during the main / final frame, it's often distracting to see the gizmos and icons in reflections and other off-screen render targets.

Let me know if this helps!

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

Page 1 of 1 (11 items) | RSS