Handling lighting with Direct3D10
Posted 19 February 2012 - 12:26 PM
I'd figure something out myself, but I think it's better to know the standard protocol.
Imagine you have a level with a thousand lights, but when you pass those lights to a shader, of course you can't deal with every light. I think to iterate over all the lights in the scene for every shader, and sort them according to distance(squared) with the object that is about to get shaded, then pick the first 10 or so, and pass them to the shader? But even that seems like a huge operation, because you need to do that for per frame, per object...
Any help is appreciated.
Posted 19 February 2012 - 04:31 PM
Another approach is deferred shading. If you haven't heard about this, google it; there are many, many articles on the subject. Briefly, the idea is to render material properties (color, normal, specular intensity and power, etc.) into an offscreen buffer (called a "G-buffer" for some reason), then do lighting in image space by writing a pixel shader that fetches the material properties from the G-buffer and evaluates the lighting equation. This decouples material shaders from lighting shaders, greatly reduces the number of draw calls, and doesn't require you to track which lights hit which objects; but it also requires more memory bandwidth, and places restrictions on the shading model due to all its parameters having to fit into the G-buffer.
In either of these approaches, good frustum/occlusion culling is essential for good performance; it pays to spend some effort making sure you don't draw things that aren't visible. And none of this is really about D3D10; these are generic rendering approaches that are applicable to any API. Finally, since you mentioned the workload per frame of figuring out what to draw, note that it's often possible to exploit temporal coherence here, since what to draw this frame is usually pretty similar to what you drew last frame. Try to build a data structure that allows you to hang on to some of the information from last frame rather than starting from scratch; of course it also must be able to adapt to changing circumstances, but you can still save a lot of performance this way.
Posted 19 February 2012 - 06:43 PM
Rendering things like that is indeed generic, but I just wanted to point out that I'm using D3D10.
Could you give a simple example of the datastructure you mentioned, or just names/links/references?
Something that could help me get started
EDIT: I mean a data structure that wouldn't store the frames but the differences in the frames, what you mentioned last
Posted 20 February 2012 - 03:11 AM
The set of shaders being rendered might not churn at all depending on your app, but If it does churn, you can add new shaders by insertion-sort when necessary (insertion-sort is actually quite fast for nearly-sorted lists - although beware of corner cases that lead to inserting many elements at once), and delete ones that have had no objects added for a few frames.
This approach of bucket sorting with inter-frame-persistent buckets that are relatively rarely created and deleted - can be used for various cases where objects need to be sorted but the set of objects and their sort order will usually not change too quickly.
Also, try not to alloc/dealloc a lot of objects on the heap when doing all these operations, as that will also eat into your performance. Intrusive linked lists (i.e. those that store the next/prev pointers as members in the object itself, rather than having an external heap-alloced node struct, like std::list and friends) are helpful for this.
Posted 20 February 2012 - 01:45 PM
EDIT: And also, why would you reconstruct the per-shader list every frame?
Posted 20 February 2012 - 03:24 PM
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users