How do you organise your rendering steps?

Started by
2 comments, last by Digitalfragment 11 years, 11 months ago
How do you organise your rendering steps when drawing a scene?This is my way:

I loop trough a list of the shaders/materials/effects and for each one I loop trough all the meshes that use it and for each mesh I loop trough all all the entities that use it and render it for each entity(each entity has its own x,y,z,rotation,scaling,current animation frame,etc.).The first mesh I render is always the terrain,then the main character(and all his armor and weapon attachments),then I loop the rest of the content.However,I'm not sure if this is the best method to do it.Do you think my approach is efficient enough to start working on a game using it?
Advertisement
My rendering code is detached from my game objects, in that a culling phase is responsible for telling the rendering loop what its drawing, as opposed to the rendering loop iterating over all of the entities.

When loading model resources, their shader bindings indicate whether they are instanced or not.

Each combination of mesh and shader pass is sorted and placed into a linear array for ideal cache usage. This includes terrain, as in the end its just another mesh/shader combo, with the exception that the terrain data is rather dynamic, instead of loaded as a model. (I've glossed over an exception to this which is to handle transparent objects and z-prepass stuff, which warrant explicit sorting at runtime.)

A dynamic buffer is created that gets populated with transforms from the culling phase, and each mesh-shader combo gets an offset and count into this buffer for its instances. The same thing is done for shader parameters / cbuffers in my case.

Then on each hardware thread I burn through this list using the async DeviceContext concept to push everything to the device.

Reason I've taken this approach is that when you reach a certain scale of complexity with your objects and scene, you tend to find your loops touch memory all over the place, and jump to lots of different functions which all heavily thrash the cache. Having data in neat linear lists helps with this greatly, and also makes parallelization easy when you get up to mulithreading your code.

From a GPU point of view, you might be better off drawing your armour attachments, then your character, then the terrain. Ideally, your video card would want to make use of Hi-Z, which works best with front-to-back sorting of opaque geometry.

From a GPU point of view, you might be better off drawing your armour attachments, then your character, then the terrain. Ideally, your video card would want to make use of Hi-Z, which works best with front-to-back sorting of opaque geometry.


Wait,so if I render the armor first and the character's body second,it would cull the part that's covered by the armor?I thought that DirectX can't automatically cull occlusion between different meshes.
It doesn't cull the meshes, the pixel shader has a better chance of being rejected before it starts.
You will still pay the entire cost of the render state changes and vertex shader though.

This topic is closed to new replies.

Advertisement