Jump to content
  • Advertisement
Sign in to follow this  

Lighting architecture issue?

This topic is 3781 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys! Recentlly i was developing my own game engine, you konw, scene graph, renderer, physics, sound...etc. But when i was working on my renderer i come up with the problem about the lighting system. Arbitrary number of light seems to be nightmare for me:( I have read dozen of posts about that, and found there are three ways to go: 1,single pass with multi-light 2,one pass per light 3,deferd shading What i want to konw is how you guys think about that? Especially the single pass with multi-light method? Any suggestion will be valuable! Thanks for advance!

Share this post

Link to post
Share on other sites
First ask yourself how many lights you really need. 1? 5? In case you won't have that much, option 1 and 2 are fine. I don't think most games are using an insane amount of lights so far. Lot's of it is faked with tricks, or the lights only affect a small portion. Doom3 for example had dozens of lights, but most of them only reached a few surfaces, which means the average polygon only had 2, 3, maybe 4 lights shining on it.

If you want alot more lights, Deferred shading becomes more and more attractive. However, deferred shading has a couple of serious issues:
1.- Transparent/Blended surfaces
2.- A limited amount of parameters. Your shaders for each material are more limited. You can't render 1 polygon with normal diffuse/specular shading, and another one with a completely different approach.

With some hacks you can bring in transparent surfaces, but it's still not very flexible. I can imagine an outdoor scene with lots of foliage and grass would be a nightmare, unless you render them on top of the deferred shaded results with another (normal) technique. Problem 2 does not seem to be that much of a pain at first, since most games are not using 10 different lighting models. And even if you whish to do so, you can even do it with deferred shading. For example, each pixel could have 1 parameter that tells which model to use
(0==default diffuse/specular, 1==brdf, 2==velvet, 3==...). But... you often need more than just 1 parameter once you start with more exotic rendering techniques. Each pixel should be able to get its data from the buffers you rendered before. That could be:
- texture 1 : RGB = diffuse A = alpha, or distance between pixel and camera
- texture 2 : RGB = normal, A = shading technique / lighting model index number
- texture 3 : RGB = specular, A = specular term
- texture 4 : ...
(distance can be used to recalculate pixel 3D position). Sounds fine, but once you start making varying shaders, you will need more parameters. Reflectivity, contrast, brightness, fresnel parameters, ambient color, emissive color, ... The amount of texture buffers you can make is limited, for example 4. You could do 2 passes, that would give you 8 textures and thus alot more parameters for your needs. But this also costs quite alot memory and bandwidth.

In other words, deferred lighting is 'sturdy', not very flexible. You can make it more flexible, but a relative high memory cost, and overhead in your shaders. For example, each pixel must first execute a "IF (shaderTechnique == ...)" statement in order to apply the right technique.

In case you have dozens of lights, you can benefit and compromise these problems with the speed you win. If you don't have that much lights, its probably is not worth it, and it will push you into a certain direction with some nasty limitations. In fact, I first decided to do deferred lighting in my hobby engine, but later on I switched back to multi-pass lighting.

About multi-pass lighting, the more lights you can do in one shader, the better. Unfortunately, its very hard to tell how many lights a certain wall will have, since lights can move around, switch on/off, or maybe the surface itself will move as well. This will force you to constantly sort everything out. As you probably know, switching materials and shaders costs time. Its much better to render in 'batches': first render all the polygons with shader A, and texture/properties A, then go on with B, and so on. If you must switch shader/texture for each surface/polygon, you will loose a lot of performance there.

Another problem is the limited shader data you can pass. For example, if you plan to use shadowmaps, you are limited to the amount of texture channels and eventually the texcoord registers you can pass from vertex- to fragmentshader. You can't do 20 lights with shadowmaps in one shader, because there are not enough registers/texture slots. In that case you must still use multiple passes, for example, 4 lights per pass. It gets even worse if you plan to use all kind of light types (spotlight, point light, cascaded lights(long range shadowmaps), simple lights without shadow, etc...). All this stuff makes the sorting harder.

Nevertheless, if I were you I would try to find out if you can (quickly) re-sort the materials/shaders after a light or object moves. Or try at least to do a few lights in a shader. You can always fall back to 1 light per pass, which isn't too bad either, as long as you don't have very much lights.


Share this post

Link to post
Share on other sites
I talked about renderer design for many lights at UCSD and the University of Stuttgart recently. You can find my slides here


That being said: the highest amount of lights can be achieved with a renderer design pattern that is called Light Pre-Pass renderer. In essence you split up the lighting equation in two parts. The properties of the light and material properties. You render the light properties into a light buffer like in a deferred renderer by additively blending them. Then you take this light buffer in a forward rendering path and use it as your light source.
Advantages compared to a deferred renderer are:
- more than 2 - 3 times the light because you fetch only two textures for each light and run a much smaller shader because you only render light properties
- consumes less bandwidth compared to a deferred renderer
- can be implemented on ps_1_4 hardware == Wii ... deferred renderers have much higher requirements

Share this post

Link to post
Share on other sites
Thank you VERY much for your reply!
The wheel of imagination started to run!I think I would use the one light per pass method. Because I don't think I need so many lights for an object at the moment.The deferd lighting woubld be a waste about that. Whatever, my final focus is a game not an engine, maybe I can use some trick to deal with it.But still have something to consider...
To spek:Thanks for the analyse to me.It clear my doubt a lot!
To wolf:I should take some time to understand your method^^I am sure that I would find useful information in it.Thanks.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • 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!