Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411579 Posts in 69386 Topics- by 58445 Members - Latest Member: Mansreign

May 05, 2024, 02:56:45 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Too many lights on a starship! (XNA, shaders)
Pages: [1]
Print
Author Topic: Too many lights on a starship! (XNA, shaders)  (Read 2763 times)
Traveller
Level 1
*


View Profile
« on: February 24, 2009, 03:41:55 PM »

First off:  My target is pixel shader v.1.4, so it's pretty old stuff here.

I'm working with the inside of a starship, mapped in a Quake 3 bsp file, but not rendered with that engine (using meshes from Blender and stuff).  It has lots of windows, well, some windows at least.  It also has rooms that are lit different from each other.  What I'm not sure about is, how do I make the best use of limited lights?  What should I keep, what should I drop?

I've looked up shadowmaps, and I think they would be very nice to use...but, well, I only have so many lights allowed.  When the sun is shining right into windows from Mercury's orbit, I'd like to see it cast glaring shadows from all the control panels and people in the ship onto the back wall.  I'm pretty sure I could pull that off...but nothing else would cast shadows, and I think that sounds kind of glaring.  Would it be bad if only the sun in the windows cast shadows, and nothing else did?  (Other lights would only do normal diffuse lighting, etc.)

Also...I -want- to give each room in my ship its own light properties, but they're pretty much connected by hallways and not doors.  I THINK I could get away with saying "each room has its own ambient light, plus one point light, and things are only lit by the room they are in", but...would that be too weird at the hallways?  As an object moved out of the room, it would just suddenly be lit by the next room.  Would that be too awful-looking, especially if you're watching another player walk out of the room you're in?  I'm also worried about, say, an exit from a well-lit room into a poorly-lit room.  Sudden shadows!

Heck, I'm assuming I can even pull this off at all, which isn't guaranteed--If there's ten lights on the screen, but any given object is only lit by one light at a time, will that work on my graphics card or will it cause problems?  I know my card can't fit ten lights at once (due to low shader version), but can it switch which lights it's using when it switches to a new mesh to render?

Looking for advice on "Would that look awful?", "Is it technically possible?", and "Is there a better way to do that?"
Logged
Ishi
Pixelhead
Level 10
******


coffee&coding


View Profile WWW
« Reply #1 on: February 24, 2009, 04:01:00 PM »

If all the lights inside the ship are going to be static you could try a light map or something to precompute all the lighting on the static geometry at least, at the cost of probably a fair bit of texture memory.

Shadows just from windows might be fakeable with a few projected textures of the light that's coming through the window. You could also consider shadow volumes for the shadows, although they're pretty nasty things (I fully intend never implementing them myself) they can be done purely through the fixed function pipeline so they're a bit more suitable to older hardware. Hmm.. depending on the situation you might be able to use a shadow volume as a "light volume" and project them from the windows, and lighten stuff that falls in the volume.

If you want lots of lights you could look into deferred shading, although that's best suited to rendering lots of lights whose range is quite small in screenspace (like lights on a christmas tree or something).

Having different ambient light per room would be perfectly workable I think, especially if you have hallways between each room, as you could interpolate gradually between the two ambient colours as you walk down the hallway.

Some random thoughts on the matter there.
Logged

Ivan
Owl Country
Level 10
*


alright, let's see what we can see


View Profile
« Reply #2 on: February 24, 2009, 04:17:12 PM »

This is a pretty complex topic and one I've been struggling with in my own engine for awhile, so here a few thoughts on it.

My current setup for dynamic lights, which is by no means perfect is like this: The engine has two types of lights, area and spotlight and you can have as many as you want in a scene. In my material framework, I define which built-in properties get passed to a shader, like AREALIGHTPOSITION0, or SPOTLIGHTPOSITION0, and the engine will take the brightest nearby lights of that type and pass those properties to the shader, same with light zbuffers for shadow-enabled spotlights, etc. It works fairly well most of the time as long as you're careful about how your lights are created.

Concerning shadow mapping in general: You're only realistically going to be able to have one light casting shadows at a time since you have to re-render the scene for every shadow casting spotlight (and re-render it multiple times for every shadow-casting area light, which is why i opted out of those in my engine).

I have no idea how XNA is setup, but I hope this helps somewhat.
Logged

http://polycode.org/ - Free, cross-platform, open-source engine.
Traveller
Level 1
*


View Profile
« Reply #3 on: February 24, 2009, 04:39:53 PM »

Hmmm...

After more consideration, I'm not sure what I'm going to have in the way of truly dynamic lights.  There's no flashlights (not planned anyway), so the only light that can ever move will be the sun, pretty much.

Although it would be nice to be able to change the color of lights in the room from whitish to reddish when the emergency lights come on...

The fact that I will be changing from white to red--as well as having the sun, and knowing not much about the Quake 3 rendering format (I really can't use the Quake 3 lighting tools)--kind of has me a little confused.  Are there any shortcuts that I can take, with the knowledge that my lights are at least all in the same place all the time?

I think I can deal with only shadow casting from the sun.

But I do want to have my non-static meshes clearly be lit from above in a room that only has ceiling lights (most of them).  With few lights, it seems like I'm going to resort to either adding the light vectors or only taking the brightest one to light my meshes.  What should I do in a room that has, like, a bunch of ceiling lights placed across the ceiling, when I can only USE a couple lights?  If someone walks down a hallway away from that room, they should be lit from behind instead of above.  I guess it still works.

Has anyone ever seen a technique where you precompute the light angles per, oh, 1'x1'x1' cube across the map?  It seems like it would be expensive to figure out what values you should use to light your mesh if you recomputed all the time.

I'm curious about precomputing light on the walls at the cost of texture memory...  Could someone explain that better, or link it?  Do you make a copy of each wall's texture whenever the lights change, and do a slow procedure to calculate it properly and then save a copy per wall face?  That sounds reasonable...
Logged
Ivan
Owl Country
Level 10
*


alright, let's see what we can see


View Profile
« Reply #4 on: February 24, 2009, 04:54:18 PM »

I think what you're talking about is sort of how they do the ambient lighting in the Source engine. They basically have evenly placed "lightcubes" throughout the map, which have a certain light value for each side, computed from all the lights and radiance in the scene, then in their shader, they use the nearest cube to light the model with Spherical Harmonics.

You can find that stuff in their paper on Source which you can find here:

http://www.valvesoftware.com/publications.html
Logged

http://polycode.org/ - Free, cross-platform, open-source engine.
Traveller
Level 1
*


View Profile
« Reply #5 on: February 24, 2009, 05:35:03 PM »

Oh, man!  I need to find a simpler explanation of spherical harmonics, clearly.  But these papers are very useful!  Great!
Logged
Zaknafein
Level 4
****



View Profile WWW
« Reply #6 on: February 24, 2009, 08:10:00 PM »

I thought that the Source ambient cubes were sampled just as cubemaps, using the normal of the model and just looking up with something like a texCUBE() HLSL intrinsic. So then spherical harmonics are not needed.
Also I must admit that I never "got" SH, they're still voodoo magic to me. Shrug

One more thing : I don't think you can even get projective texturing (and thus dynamic shadow/light-mapping) in SM1.4. The tex2Dproj() HLSL intrinsic appears in Pixel Shaders 2.0. Anyway, asking for 2.0 shaders nowadays is pretty reasonable.
« Last Edit: February 24, 2009, 08:15:26 PM by Zaknafein » Logged

Ivan
Owl Country
Level 10
*


alright, let's see what we can see


View Profile
« Reply #7 on: February 24, 2009, 08:13:36 PM »

Yeah, I think you're right actually, but I don't think it's as simple as texCUBE. I think it's just a simplified version of SH or something.
Logged

http://polycode.org/ - Free, cross-platform, open-source engine.
David Pittman
Level 2
**


MAEK GAEM


View Profile WWW
« Reply #8 on: February 25, 2009, 12:46:33 AM »

Has anyone ever seen a technique where you precompute the light angles per, oh, 1'x1'x1' cube across the map?  It seems like it would be expensive to figure out what values you should use to light your mesh if you recomputed all the time.

I actually do this in my engine as my only source of lighting for dynamic objects. It works fine for my purposes, but would generally be better used just for a directional ambient term like they do in Source. It lacks the fidelity to provide realistic specular highlights (because you don't have an actual light vector, just the sum of light on the cardinal axes), and it's static. The nice thing about it is that I can use infinite lights at no extra cost (but they're all static and resolved down to the irradiance volumes).

I'm curious about precomputing light on the walls at the cost of texture memory...  Could someone explain that better, or link it?  Do you make a copy of each wall's texture whenever the lights change, and do a slow procedure to calculate it properly and then save a copy per wall face?  That sounds reasonable...

The classical example is Quake 1's lightmaps, where you have a low resolution grayscale  texture for each face, multiplied on top of the diffuse texture to create shadows. (Actually, you'd pack a whole bunch of these into large lightmap atlases.) There's no directional information there, though, so they don't play real nice with normal mapped surfaces. That's where Source's "radiosity normal maps" come in--they're basically just lightmaps computed relative to three basis vectors instead of to the surface normal. (In my engine, I do the same thing but for vertex lighting instead of lightmaps.)

One solution I've seen that allows dynamic light values (but not positions) is to encode the lightmap with the contributions of the most relevant lights (e.g., four lights on the RGBA channels). Then the value of the lights (color and/or intensity) can be changed and passed into the shader and multiplied by the lightmap value on the appropriate channel. I haven't implemented this myself, but it seems like a clever solution if you need to be able to turn lights on and off in an otherwise static scene.

I thought that the Source ambient cubes were sampled just as cubemaps, using the normal of the model and just looking up with something like a texCUBE() HLSL intrinsic. So then spherical harmonics are not needed.

1x1 cubemaps are a decent analogy for how irradiance volumes work, but that's not actually how they're implemented in the shader. I guess it could be done that way, but the texture sample would probably be slower than this:

Code:
float4 LightCube[6];
float4 GetCubeLight( float3 InNormal )
{
    float3 NormalSquared = InNormal * InNormal;
    int3 IsNegative = InNormal < 0.0f;
    return
        NormalSquared.x * LightCube[ IsNegative.x ] +
        NormalSquared.y * LightCube[ IsNegative.y + 2 ] +
        NormalSquared.z * LightCube[ IsNegative.z + 4 ];
}
« Last Edit: February 25, 2009, 01:54:20 PM by David Pittman » Logged

Traveller
Level 1
*


View Profile
« Reply #9 on: February 25, 2009, 12:10:36 PM »

Alright!  I think I now have a good understanding of how Source handles light volumes, which is exactly what I needed to know.  It also tells me what I need to look for in the tools and resources I have available.  I also understand radiosity normal lighting and light maps.

Unfortunately, the Quake 3 .bsp format (which I'm using) is a little different.  Its light map cubes, instead, have:
- ambient light rgb
- directional light rgb
- phi/theta to directional light
Its lightmaps are also a single rgb.  At least that's better than grayscale, but it's not radiosity normal mapping.  I could theoretically try normal mapping on my models but it might not be worthwhile.

So it looks like each model in my game is only going to have one directional light pointing at it.  Oh well.  Makes me wonder how they compute that stuff.  They probably start with the data Source does in the radiosity phase, then figure out some best-fit of the above variables.

Well, now I have everything I need to know to use static lights to their full potential, including on nonstatic meshes!  I think I'm going to forego my dynamic lights entirely--which means no big flashing red warning lights.  Well, I can make do with other interface things.

David, I really like your idea for dynamic intensity lights.  Right now it looks like I'll be relying very heavily on Quake 3's bsp format, so I don't have time to muck around in the compiler, but that is a serious thought for the future.  At first glance it seemed trivially simple, but now it seems like the single best way to do things!  Especially if you can group your semi-static lights together in groups.  Like, "all these emitters are always on", "all these emitters go on and off at the same time", etc.  Then I guess you just do each surface for each combination of lights and find out which four are the most important, which will be difficult.

I think I WILL do my "sun" stuff with an emphasis on light instead of shadow.  So the sun is the one big dynamic light, and it gets handled specially, including fun handling of overbright stuff.

Thanks, everyone!  You've answered my questions, helped me learn, and directed me at some very useful information.
« Last Edit: February 25, 2009, 12:50:38 PM by Traveller » Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic