Design a render queue
Members - Reputation: 150
Posted 14 December 2012 - 03:41 AM
I want to design a game engine by myself, and now I'm start to design "render" part .
I know change the render state is very expensive. so use a render queue to split the render object in different queue is a good idea(truth?).
But i have no idea how to start this design.
How many kinds of queue i should use?
How can I determine this object is suitable for queue A or queue B?
Could you give me some suggestion?
Members - Reputation: 835
Posted 14 December 2012 - 07:02 AM
Personally, I strongly believe to keep the engine as simple as possible until it actually runs with all the features you want (which is enough work, for starters). As a single-handed developer, you certainly don't want to waste time with premature optimization, do you? ;-)
Simply add all your objects to one queue and render them in that order. Concern yourself more with culling at this stage of development. Removing an object from the queue altogether because it is not currently visible may well proof to be way more effective than state sorting. Once your code is feature-complete, state sorting is easily added afterward.
So much for preaching, now let's have a look at how state sorting works:
The basic idea is to have a simple representation of the render state of each object (an unsigned int filled with flags, for example), and then sort your queue for this value. Theory says that all objects that require the same render state end up close together in the sorted queue and get rendered consecutively as a consequence.
Note, however, that unless you render lots of (nearly) identical objects it is quite common for all your object requiring different state (that's why I called this technique "premature optimization" previously). Certainly, the orientation and position do normally change with each object, and normally texture maps and shaders do, too. Some Objects may even require different parts to be rendered with different states (think of an otherwise opaque model with only some transparent parts).
Especially transparency introduces another problem to state sorting: It may be necessary to render transparent objects in a back-to-front order to avoid artifacts. But now you end up with two different orders to sort for: screen depth and state. And gone is your simple invocation of std::sort, or how ever it is called in the language of your choice!
To solve this problem, you could split the transparent parts from the object itself and put them in a second render queue. Now first render the opaque things, and after that the transparent parts. First queue sorted by state, second by depth. That would be similar to your queues A and B.
Hope that helped...
Crossbones+ - Reputation: 22667
Posted 14 December 2012 - 09:07 AM
I think what you mean is called "state sorting": You sort your queue for render state.
No, he means “render queue”.
However your description of what needs to be done is fairly accurate, even to the point where multiple render queues are used simultaneously to handle alpha objects vs. fully opaque objects.
In my implementation there are 2 levels of render queues. There are basic render queues and then “render-queue sets”. A render-queue set is 2 render queues. One for alpha objects and one for opaque objects.
Thinking in terms of render-queue sets makes this a but easier to grasp.
There is one render-queue set for each type of render that will need to take place. There will be a basic render pass and usually also a shadow pass. Each type of technique you can imagine will end up being another render-queue set. If you have multiple lights you will have one render-queue set for each light. The basic idea is to ask yourself how many times you need to sort these objects.
Of note is that even if your main rendering routine has an ambient pass and a lighting pass (or more than one lighting pass), the ambient pass and the lighting pass(es) will be using different shaders, but will likely end up being sorted the same way, which means you don’t need a separate sort for these passes. The same render queue can and should be used for both.
The problem becomes simpler when you break it down into sets of render queues in which the first is opaque and the second is alpha. After that you just need to decide how many sets you need, and that is easy if you simply understand how many times you need to sort the objects.
To answer your question regarding what is suitable for what, in my implementation the scene manager asks each renderable object to make that decision. Each renderable object knows which of its parts need to have alpha blending and which do not. So I suggest you follow suit and let your renderable objects themselves make that decision.
Edited by L. Spiro, 13 April 2015 - 06:55 PM.
My Art: http://l-spiro.deviantart.com/gallery/4844241/Realism My Music: https://soundcloud.com/l-spiro
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums
Members - Reputation: 1065
Posted 17 December 2012 - 12:02 PM
Chapter 10, Camera Centric Engine Design.