Jump to content
  • Advertisement
  • entries
    422
  • comments
    1540
  • views
    490888

Pseudo Code

Sign in to follow this  
jollyjeffers

129 views

Right,

I've actually managed to kick myself into doing something today (been feeling ill lately, so productivity went downhill).

Some of my better journal entries recently have been regarding the rendering pipeline I need to implement for my project. I put together some pretty Visio digrams and so on to represent them...

I've now tried to write it all out in a more rigid pseudo code form. It needs a little bit more work, but it's pretty much finished. The idea was to go from a high-level flow diagram to a list of the actual commands that I'll need to issue.

The original translation from Visio-Pseudo revealed a lot of refactoring potential (redundant state changing for example), so I rearranged a lot of the instructions. The listing presented here should be about as optimal as I can get without resorting to special cases:

Initialization
--------------

Input: Screen Width
Input: Screen Height

Constant: Shadow Width
Constant: Shadow Height

Texture: Buffer0 = Screen Width * Screen Height * A32R32G32B32F
Texture: Buffer1 = Screen Width * Screen Height * A32R32G32B32F
Texture: Buffer2 = Screen Width * Screen Height * A32R32G32B32F
Texture: Temp = Screen Width * Screen Height * R32F
Texture: Shadow = Screen Width * Screen Height * R32F
Texture: Directional Shadow Map = Shadow Width * Shadow Height * R32F
Texture: Cube-Map Shadow Map = Shadow Width * Shadow Height * R32F * 6
Texture: DepthStencil Shadow = Shadow Width * Shadow Height * D16


Per-Frame Processing
--------------------
// Make a copy of existing rendering
Surface : Current Depth Stencil Target
GetDepthStencil()
Surface : Current Render Target
GetRenderTarget()
// Begin this frames rendering
{
// Clear the intermediary buffers
ClearTexture( Buffer1, Black );
ClearTexture( Buffer2, Black );

For( Each Light, L )
{
If( Enabled( L ) )
{
// Clear the resource that will be used in this pass
ClearTexture( Buffer1, Black );
ClearTexture( Shadow, White );

// Perform Shadow rendering if applicable
If( CastsShadows( L ) )
{
Configure Shadow Mapping Shader : Outputs Depth Only
If( IsPointLight( L ) )
{
// Construct cube shadow map
SetDepthStencil( DepthStencil Shadow );
For( Each Face, F )
{
SetRenderTarget( F );
ClearDepthBuffer();
ClearRenderTarget();
ConfigureCamera( Lights View, Looking at Face F );
RenderScene( NO_MATERIAL_SETUP );
}

// Render Scene With Shadow Contributions
ConfigureCamera( Viewer Position );
SetRenderTarget( Shadow );
SetDepthStencilSurface( Original DST );
ClearDepthBuffer();
Configure Shadow Rendering Shader : Does cube-map lookup
RenderScene( NO_MATERIAL_SETUP );
}
Else( IsDirectionalLight( L ) )
{
// Construct Single Shadow Map
SetRenderTarget( Directional Shadow Map );
SetDepthStencilTarget( DepthStencil Shadow );
ClearDepthBuffer();
ClearRenderTarget();
ConfigureCamera( From Light Point Of View );
RenderScene( NO_MATERIAL_SETUP );

// Render Scene With Shadow Contributions
ConfigureCamera( Viewer Position );
SetRenderTarget( Shadow );
SetDepthStencilSurface( Original DST );
ClearDepthBuffer();
Configure Shadow Rendering Shader: Projects texture onto scene
RenderScene( NO_MATERIAL_SETUP );
}

If( Soft Shadows )
{
SetRenderTarget( Temp );
Configure Horizontal Blur Filter
PostProcess( Shadow onto Temp );

SetRenderTarget( Shadow );
Configure Vertical Blur Filter
PostProcess( Temp onto Shadow );
}
}

// Render the frame
SetRenderTarget( Buffer0 );
RenderScene( FULL_MATERIAL_SETUP );

// Perform the additive combiner
SetRenderTarget( Buffer( 2 - L % 2 ) );
SetInputTexture( Buffer0 );
SetInputTexture( Buffer( 1 + L % 2 ) );
SetInputTexture( Shadow );
DoBlendOperation( Add Buffer0*Shadow to Buffer(1+L%2) and store in Buffer(2-L%2) );
}
}

}
// Restore state as of function start
Restore Original DST: SetDepthStencil()
Restore Original RT : SetRenderTarget()


Any thoughts?

An immediate problem presented itself which is good. How to clear an arbitrary render target. As you can see in a few places above, it's necessary to wipe one (or more) of the temporary buffers when they aren't actually the current render target (thus a IDirect3DDevice9::Clear() isn't useful).

I should be able to use IDirect3DTexture9::GetSurfaceLevel() and feed it into IDirect3DDevice9::ColorFill(). But I've not used that method "in anger" before - so I don't know what its performance characteristics are. A hardware Clear() operation is so stupidly fast these days that it's almost free - so it might be worth trying to set the buffer as a render target, clear it, then un-set it... hmm...

Jack
Sign in to follow this  


5 Comments


Recommended Comments

Sorry about the feeling ill stuff. I know exactly how you feel, I had something nasty come down the pipe last week and knock me out for about 4 days. Ended up working only half-days at work, and taking herculean doses of Nyquil just to get to sleep at night. I've still got the persistent hacking cough that just won't go away.

Share this comment


Link to comment
ColorFill should be clear-like fast, at least on nvidia hw. Last year or so we had an app that was using this, and it was not fast in the driver, so this was addressed.

Share this comment


Link to comment
Quote:
Sorry about the feeling ill stuff. I know exactly how you feel, I had something nasty come down the pipe last week and knock me out for about 4 days.

Thanks! I guess its "that time of the year"... I've always had a pretty good imune system, so fingers crossed I'll be up and running in a day or so [smile]

Quote:
ColorFill should be clear-like fast, at least on nvidia hw. Last year or so we had an app that was using this, and it was not fast in the driver, so this was addressed.

Thanks for that bit of information [grin] I'm deploying to a Gf 6600, but developing on an Radeon 9800... I'll go with the ColorFill approach and if it causes problems it shouldn't be hard to find an alternative.

Cheers,
Jack

Share this comment


Link to comment
Why are you clearing the depth buffer when rendering the shadow contributions for each light pass? Wouldn't it be better to only do it once, before the light loop, and render your ambient pass/zfill, then reuse the depth with Z less/equal?

You might also want to be careful with the buffer swap if any lights are disabled (only advance your active buffer counter when rendering enabled light). I'm also assuming you use a cheaper DoBlendOperation shader (no shadow texture lookup) if no shadows are cast :)

Oh, and you need a ConfigureCamera( Viewer Position ); if the first enabled light doesn't cast shadows.


Share this comment


Link to comment
Thanks for the comments VOR.

Quote:
Why are you clearing the depth buffer when rendering the shadow contributions for each light pass? Wouldn't it be better to only do it once, before the light loop, and render your ambient pass/zfill, then reuse the depth with Z less/equal?
I had been contemplating putting a "Z Fill" pass in - they've been quite useful before. Probably an oversight on my part [smile]

Quote:
You might also want to be careful with the buffer swap if any lights are disabled (only advance your active buffer counter when rendering enabled light).
Yup, I've got that one in the code - just forgot it in the pseudo listing [smile]
Quote:
I'm also assuming you use a cheaper DoBlendOperation shader (no shadow texture lookup) if no shadows are cast :)
I've got a few micro-optimizations like this planned. At least initially I'll probably just get it working and then start implementing some "special case" optimizations.

Cheers,
Jack

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!