Multiple Lights on game map with forward rendering

Started by
12 comments, last by JohnnyCode 9 years, 3 months ago

Hi guys, phew it's been like forever since I stopped game development.

Well, I'd go straight to the point. This is a problem that's been bugging me more than it should. I'm making a 3d rpg game for android, right now I've finished designing the game map format (no graphical thing to see yet :p) but it suddenly hit me like a thunder. How would I allow multiple light source to light my game map?

Well I'm using glsl (of course) + forward rendering. I couldn't use the same approach I used for game objects, because each object can only be lit by a maximum of FOUR light sources (I got that implemented already from my previous game). Each object holds a reference to a maximum of four light sources that will affect them most.

Now, I've seen several games using this approach too for their objects (players, npcs, items, props) it had also been mentioned here several times or so if I remember correctly. However, most of the games that use this method somehow could dynamically LIT their terrain/game maps/level with almost no limit of light sources. How would I do this for my game? I don't wanna go back to lightmapping since I'm concerned about storage and, I'd rather have my torches light up my world brilliantly.

NB: all the game I've seen showed like ~32 number of lights. But I'm not sure if it's "hardcoded" to their engine. (I can't imagine looping thru 32 light properties in the shader just to compute 1 pixel's color)

Advertisement

However, most of the games that use this method somehow could dynamically LIT their terrain/game maps/level with almost no limit of light sources. How would I do this for my game?

Draw with 4 lights (or however many you want and can fit with the registers available in your shader) and then draw 4 more lights with additive blending (and no ambience).


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

However, most of the games that use this method somehow could dynamically LIT their terrain/game maps/level with almost no limit of light sources. How would I do this for my game?

Draw with 4 lights (or however many you want and can fit with the registers available in your shader) and then draw 4 more lights with additive blending (and no ambience).


L. Spiro

+1

Oh, dangit. Why didn't I think about it earlier? basically it's similar to those multipass forward light with additive blending right? Yeah, I could see where I'm going now. Thanks L. Spiro.

Well I'd still need some advice though. I planned to calculate those extra pass by setting alpha to 0.0f where the light has no effect. then I blend them in with alpha testing enabled (or maybe I could just discard those pixel, but I heard it's non-conformant). Is it a "good" approach? I think I could see good performance, although I'm not sure

How is your game map different from a collection of objects? Is it a terrain or some unstructured mesh? Anyway, why not split the map into smaller pieces. Then determine the four most important lights for each pice. Do you anticipate that there will be more than four lights that significantly influence small portions of the map?


I can't imagine looping thru 32 light properties in the shader just to compute 1 pixel's color

I always thought that's exactly how it's done. Wouldn't that be better performance-wise than doing multiple passes and blending them together? Even deferred rendering sends all possible light source in a single pass.

I think L. Spiro only proposed the blending method because for some reason you're limiting yourself to 4 lights per pass?

Another interesting approach used by UE3 was to composite all lights CPU-side into a set of spherical harmonics coefficients, then send these to the GPU for shading. This is an awesome tradeoff for mobile where the extra detail afforded by calculating things like falloff per-pixel are harder to see and the performance benefits are huge-- lighting time is completely independent of the number of lights influencing the object!

clb: At the end of 2012, the positions of jupiter, saturn, mercury, and deimos are aligned so as to cause a denormalized flush-to-zero bug when computing earth's gravitational force, slinging it to the sun.

How is your game map different from a collection of objects? Is it a terrain or some unstructured mesh? Anyway, why not split the map into smaller pieces. Then determine the four most important lights for each pice. Do you anticipate that there will be more than four lights that significantly influence small portions of the map?


It's a 3d tile map basically. I divided em into a quadtree structure. Then for every light they would query which node will be influenced. Thus if there's a lots of light concentrated in a node, it would get more than 4. I just cant limit it to 4 lights. It breaks realism

I can't imagine looping thru 32 light properties in the shader just to compute 1 pixel's color


I always thought that's exactly how it's done. Wouldn't that be better performance-wise than doing multiple passes and blending them together? Even deferred rendering sends all possible light source in a single pass.

I think L. Spiro only proposed the blending method because for some reason you're limiting yourself to 4 lights per pass?
Hmm I thought looping too many times in a fragment shader would slow down itself considerably. Thus the 4 lights. Plus Id save uniforms for use with another fancy effects

Another interesting approach used by UE3 was to composite all lights CPU-side into a set of spherical harmonics coefficients, then send these to the GPU for shading. This is an awesome tradeoff for mobile where the extra detail afforded by calculating things like falloff per-pixel are harder to see and the performance benefits are huge-- lighting time is completely independent of the number of lights influencing the object!

Hey Ive been thinking about it too. If only I could store light properties in a texture and read em back in the fragment shader, that'd be great. But I dunno if that's possible. Although it would require many sampling tho.

If a lot of your lights are not changing every frame you can bake or cache those lights sources. So do multiple passes if need be render them but render the lighting to a lighting buffer and just sample from it while the lights are constant. You could mix this on a per object level too. Maybe characters are always real time while the level is baked.

You should be able to also accumulate this light buffer into the final results similar to the multipass additive lighting.

So it would be a simpler version light maps that can be updated dynamically. You should be able to as well change out the order so at this point x-y-z are baked and w is dynamic then some other point xyw are baked and z is dynamic.

You will just have to experiment with what gives the best performance. A lot will depend on your platform target and what it can handle memory and rendering performance.

I'm guessing these are probably going to be simple lights and not fully shadowed point lights.

I do it the same as jmakitalo, max X number of lights per renderable instead of full object. Till now I didn't have situations where this isn't sufficient.

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

You are over-complicating things. Really though, are you sure you can't just send all lights at once? If you have other effects, just split those over additional passes.

I don't know if looping in the shader with all of the lights at once is slower than looping over them on the CPU. But if you are dealing with lower-end hardware, the only way to make it work properly would be to use lightmaps, and update them only when needed (i.e., when a light moves), perhaps even separating them into static and dynamic lightmaps.

You can't optimize for both storage AND performance. You have to decide which is more important for you. I think storage is slowly becoming less of an issue with every new model of graphics cards though, so I would go with the lightmaps if I were you.


If only I could store light properties in a texture and read em back in the fragment shader, that'd be great.

Wouldn't this be the same as a lightmap (or more like deferred shading)?

This topic is closed to new replies.

Advertisement