For the architectural side of rendering, there's two main ways: having each object render itself, and having a single renderer which renders everything.
I'm currently aiming for the second idea, for the following reasons:
The list can be sorted to only use shaders once. Else each object would have to bind the shader, because it's not sure if it's active. The objects could be sorted and grouped.
Easier to swap APIs. With a few macro lines, it can be easy to swap between a DirectX renderer and an OpenGL renderer (not a reason for my project, but still a good point)
- Easier to manage rendering code
Of course, if anyone has strong recommendations for the first method, I will listen to them.
But I was wondering how make this work.
First idea
The renderer has a list of pointers to the renderable components of each entity, which register themselves on RenderCompoent creation. However, I'm worrying that this may end up as a lot of extra pointer weight. But I can sort the list of pointers every so often.
Second idea
The entire list of entities is passed to the renderer each render call. The renderer then sorts the list (each call, or maybe once?) and gets what it wants. That's a lot of passing and/or sorting, however.
Other ideas
???PROFIT
Anyone got ideas? Thank you.
Answer
Third idea
Each entity submits an encoded integer key, possibly with an associated value to the renderer for each item to be rendered. The renderer can then sort the keys using any fast integer sorting method, and submit each item to be rendered.
By encoding the key in the order you want each component sorted, from MSB to LSB, you get the benefits of your second idea with a much faster sorting step.
There's a huge amount of flexibility here in terms of how you encode your key, from something as minimal as:
|MaterialID|Depth|MeshID|
| 4| 20| 8| (16 materials, 256 models)
To a more complex 64-bit key & pointer value:
|Fullscreen|Viewport|Layer|Blend|Depth|MaterialID| : ptr_to_data
| 2| 3| 3| 2| 23| 30|
There are several additional benefits to using integer keys; for example, if you have a static section of the scene you can cache the resulting keys and simply re-submit the prepared list (if used often, pre-sort and use a suitable sorting algorithm).
No comments:
Post a Comment