Tons of street lights

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.
Post Reply
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

Tons of street lights

Post by Kojack »

This is a continuation of my idea from http://www.ogre3d.org/forums/viewtopic.php?f=2&t=45986 back in november of last year.
The idea is to have hundreds or thousands of dynamic light sources to simulate street lights in a city environment, without the massive performance hit of rally using that many lights.

This time it's really in ogre (not rendermonkey), with a city road mesh I found in the google 3d warehouse.

Image
Image
The fps display (fraps) dropped by 30-40fps during screenshots, so the full view shot was about 940fps. That's with 256 simulated point lights doing per pixel lighting on a single mesh.

Chucking 256 real ogre point lights at the same mesh with pass per light iteration and only bare vertex lighting was 11fps. It would be even slower with per pixel lighting.
With only 8 lights it was 300fps.

The cool thing about my shader is that there should be little performance hit for increasing the light count.
Here's the same scene with 4096 lights:
Image
It was running at 925fps (again, the fps drops during a screenshot).
Don't worry about the road being black, I spawned the lights via code and they are all close to the ground, below the height of that middle road segment.

This isn't a light map, the lighting isn't baked. These lights are dynamic and could move or change brightness. They are doing a full per pixel N dot L style lighting with some distance fading.

Here's how it works:
I create a manual texture with a res of 16x16 (that gives 256 lights, make it 64x64 for 4096 lights, etc).
This texture will be mapped over the entire world, effectively dividing the world into x 16x16 grid of cells.
Each pixel of the texture represents the position and brightness of a single point light. The alpha of the pixel is brightness, the rgb of the pixel is the xyz position as an offset from the current cell's corner, and a range of one cell. So the colour 0xff800580 would be a pure white light slightly above the ground and in the middle of it's cell.
So each cell can only contain one light, but that light can be anywhere within the cell.

In my vertex shader, I assign a world position (scaled so 0-1 covers the whole world) to each vertex as a 3d texture coordinate. I also pass the normal in.
In my pixel shader, I read the interpolated world position of each pixel and pass it to a cell lookup function. This function takes the world pos, works out which cell the pixel is within and looks up the texture to get the position and brightness of the light for that cell. I calculate where the light is in world space and do the standard lighting equation on it to get a diffuse colour, which it returns. This is enough for a single light to affect each cell, but that looks crap when a light is near the edge (since the light can't affect the next cell, so you see a hard cutoff edge of light). So instead I call the lookup function 9 times per pixel, to get the total lighting from the 3x3 cells around the current pixel. This means up to 9 lights are affecting each pixel. I can boost the speed of the 4096 light demo to 1300+fps if I only do a single lookup instead of 9, but then lights can't affect neighboring cells (could be ok if you design the world right).

To dynamically change lights, each frame you can lock the texture, modify any pixels you want and unlock.

Of course the obvious limit here is the one light per cell restriction. For street lights at night, that should be fine, most street lights are spaced apart so there isn't much overlap. You could always make several textures so you can look up multiple lights per cell.

No thought has gone to shadows, I'm trying to pretend they don't exist. :)

A spotlight would probably work better than a point light, I might change it for the demo.

I want to fix the shader and code a little (moving lights, moving objects, etc), then I'll give it out.
User avatar
PolyVox
OGRE Contributor
OGRE Contributor
Posts: 1316
Joined: Tue Nov 21, 2006 11:28 am
Location: Groningen, The Netherlands
x 18
Contact:

Re: Tons of street lights

Post by PolyVox »

Wow, very cool stuff! I have a couple of questions:

1) Would it be possible to use more textures in order to hold additional light properties? For example its RGB colour?

2) Can this extend into three dimensions? Rather than 2D cells, you could have 3D ones? So that your 4096 lights would be spread over a 16x16x16 volume instead of a 64x64 grid?

3) Presumably the lights can move around in space? Can they pass between cells (I realise that two can't exist in the same cell at the same time). Is the logic for this complex?
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

Re: Tons of street lights

Post by Kojack »

1) Would it be possible to use more textures in order to hold additional light properties? For example its RGB colour?
Yep, once the cell texture uv coords are calculated, you could do a couple of texture lookups to get extra data. Either more lights, or colours, or whatever else you want (maybe rgb as colour and alpha as falloff or something). Of course that would mean 18 or more texture lookups per pixel instead of 9 that I currently do.
2) Can this extend into three dimensions? Rather than 2D cells, you could have 3D ones? So that your 4096 lights would be spread over a 16x16x16 volume instead of a 64x64 grid?
It should work fine in 3d, if the environment required it. To handle smooth overlaps between cells you'd then have to do 27 lookups instead of 9.
3) Presumably the lights can move around in space? Can they pass between cells (I realise that two can't exist in the same cell at the same time). Is the logic for this complex?
At the moment I have no higher level handling of lights. I created them like this:

Code: Select all

	TexturePtr tex = TextureManager::getSingleton().createManual("gridlight","General",TextureType::TEX_TYPE_2D, gridsize,gridsize,1,0,PixelFormat::PF_A8R8G8B8);
	unsigned int *p = (unsigned int *)tex->getBuffer()->lock(0,16*16*4,HardwareBuffer::LockOptions::HBL_NORMAL);
	for(int y=0;y<gridsize;y++)
	{
		for(int x=0;x<gridsize;x++)
		{
			p[y*gridsize+x]=0x30000c00|(rand()%256)|(rand()%256)<<16;
		}
	}
	tex->getBuffer()->unlock();
But if you have an array or something of light objects you could easily iterate through them and place them into cells every frame. If several lights end up trying to be in the same cell, you could choose the brightest or closest or something and ignore the others.


Some improvements:
- I'm using argb8888. So I have to calculate the light pos using the colour as an offset from the cell, so resolution per axis is only 8 bit, which is bad for vertical because cells cover the full vertical range of the scene. Instead I could use a 32 bit float colour format like PF_FLOAT32_RGBA. Now each pixel is the true world pos of the light. That would make the positioning more accurate, cut down on the math in the shader and make things easier. In fact, I don't know why I didn't do this in the first place. A 64x64 texture in PF_FLOAT32_RGBA is only 64KB.
- Small lights with an area of illumination much smaller than the cell size are best. In this case a light would never overlap more than half of an adjacent cell. So instead of reading the surrounding 8 cells, I could choose 4 cells based on the current position in the centre cell. So when rendering a pixel on the left half of a cell, I only add the lighting from the next cell to the left, not the one to the right.
User avatar
madmarx
OGRE Expert User
OGRE Expert User
Posts: 1671
Joined: Mon Jan 21, 2008 10:26 pm
x 50

Re: Tons of street lights

Post by madmarx »

Hi, extremely interesting. Instant radiosity is nearer everyday!

I would like to know if it is the same technick than the one called described here :
http://www.youtube.com/watch?v=ZmvW03O-Sjg

Epic work!


edit : I have read nullsquared and kojack answer (next posts). Thank you both, it helped me to understand!
Last edited by madmarx on Sun Mar 08, 2009 11:13 pm, edited 1 time in total.
Tutorials + Ogre searchable API + more for Ogre1.7 : http://sourceforge.net/projects/so3dtools/
Corresponding thread : http://www.ogre3d.org/forums/viewtopic. ... 93&start=0
User avatar
nullsquared
Old One
Posts: 3245
Joined: Tue Apr 24, 2007 8:23 pm
Location: NY, NY, USA
x 11

Re: Tons of street lights

Post by nullsquared »

madmarx wrote: I would like to know if it is the same technick than the one called described here :
http://www.youtube.com/watch?v=ZmvW03O-Sjg
No, that's very different. That method is much like deferred shading, except you only defer the lights without any material properties.
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

Re: Tons of street lights

Post by Kojack »

What my method is doing is effectively applying something like ogre's max_lights material property by subdividing the entire world geometry into smaller chunks in real time during the pixel shader. You'd get the same kind of effect by manually splitting your world in 3dsmax into lots of small chunks and using a shader which can do 9 lights in one pass (instead of 1 pass per light). But mine also divides dynamic objects as they move.
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

Re: Tons of street lights

Post by Kojack »

In case you want to try it for yourself, I've released full source code and pre compiled binaries.

I've added in a user controlled car which drives around the land. No physics, and it hovers slightly, but it's just there to show moving objects.
The car has a single yellow headlight (I didn't feel like adding 2). This is the only true ogre light in the scene. It's passed to the gridlight shader for processing. Adding more ogre lights should be easy, this was just a quick hack.

The land has 64 lights applied, each is now stored using floating point positions (float texture for the grid) and they are a form of downwards facing spotlight instead of point lights.

To prove that the lights are dynamic, every frame 20% of the lights move in a cyclic pattern (with different phase per light) and 10% randomly flicker like headache inducing faulty fluorescent lights.

Some pics:
Image
Image

The download:
http://rapidshare.com/files/207162369/streetlights.7z

The project included should work in the latest (well, kind of recent) ogre svn samples directory, as long as you copy the resources to somewhere in the resource path.
The exe was built with visual studio 2008 on vista 64.
The shader is hlsl only. Porting to cg should be easy-ish.
User avatar
PolyVox
OGRE Contributor
OGRE Contributor
Posts: 1316
Joined: Tue Nov 21, 2006 11:28 am
Location: Groningen, The Netherlands
x 18
Contact:

Re: Tons of street lights

Post by PolyVox »

Pretty cool! It runs nice and fast here though it's a high-spec machine anyway.
User avatar
xadhoom
Minaton
Posts: 973
Joined: Fri Dec 28, 2007 4:35 pm
Location: Germany
x 1

Re: Tons of street lights

Post by xadhoom »

Very impressive! I had a very smooth performance experience on my laptop!

Thanks for sharing your approach!

xad
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

Re: Tons of street lights

Post by Kojack »

The land has 64 lights applied
Ignore that, I must have been half asleep. It's 256 lights (257 including the car headlight) in the demo.
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

Re: Tons of street lights

Post by Kojack »

Since 256 lights isn't really that impressive sounding, here's a pic of me running it with 4096 lights (remember, these are per pixel spotlights all applying to the one mesh at once in a single pass). Still over 500fps.
The biggest hit is because I'm using a power function to narrow the spotlight area of effect to match these smaller cells, that's dropped the speed from 600+ to 500+ fps. Plus I'm still updating the position of 20% of the lights and brightness of 10% of the lights every frame.

Image
User avatar
ahmadi
Gnome
Posts: 312
Joined: Sat Nov 26, 2005 4:03 pm

Re: Tons of street lights

Post by ahmadi »

Excellent work Kojack. :D
Im implementing it in my city.
I will send the result in this topic.
Thank you very much.
_________________________________
Best regards

Ahmadi
User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19269
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 66
Contact:

Re: Tons of street lights

Post by sinbad »

Very clever technique!
MattStevens
Goblin
Posts: 239
Joined: Mon Apr 07, 2008 10:27 pm
x 4

Re: Tons of street lights

Post by MattStevens »

I haven't tested the demo yet, but is the car lit by the same lights as the ground ? I don't think so by reading your description.

If it doesn't, I guess just applying the shader to the moving car would work ? I'm asking, because even if it would look awesome on a static city, any movable object crossing the spot light area would look really strange to me.

Anyway, it is still a very cool technique :)

- Matt
User avatar
xavier
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 9481
Joined: Fri Feb 18, 2005 2:03 am
Location: Dublin, CA, US
x 22

Re: Tons of street lights

Post by xavier »

sinbad wrote:Very clever technique!

Agreed -- you should probably work it up into a ShaderX/GPU Gems article?
Do you need help? What have you tried?

Image

Angels can fly because they take themselves lightly.
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

Re: Tons of street lights

Post by Kojack »

I haven't tested the demo yet, but is the car lit by the same lights as the ground ? I don't think so by reading your description.
The car is affected by the lights too. As it drives by them it lights up correctly. Any entity which includes the gridlight shader as one of it's passes will be affected by the fake lights. Even animated meshes.

The biggest problem is shadows, I haven't put any thought into how I can fake them. I'm not that good with realtime shadows, (ray traced ones are much more fun).
I think the easiest way would be to only use the gridlights for distant lights, turn off the gridlights in the cells immediately surrounding your camera and replace them with standard ogre lights (maybe with a fade to hide the differences in algorithm). So up close you have a couple of lights casting regular shadows, but further away you have thousands of lights which don't have shadows. But you can still see distant objects moving through the lights and being illuminated.

Some more ideas:
- use a 3d texture for multiple data. Have one layer of the 3d texture be position, one layer is colour, etc. Then you don't need to pass 2 or more textures in.
- Instead of lights, store precalculated spherical harmonic irradiance, each colour coefficient stored as a layer of a 3d texture. The SH is baked in something like Max, one per cell. Then at runtime any object within a cell will automatically get it's ambient lighting from the SH. Using some fading, you could have a smooth transition between SH's, even when a single mesh passes through more than one cell.
- You could do this in a deferred style. All the lookup needs is the xyz position and normal of each pixel stored as a colour. From my understanding (I've never tried it myself) a deferred renderer would already store position and normals in multiple render targets then perform one full screen pass per light to apply the each light. The gridlight shader could do all of it's thousands of lights in a single pass using the already deferred data, without harming the rest of the lighting.
User avatar
ahmadi
Gnome
Posts: 312
Joined: Sat Nov 26, 2005 4:03 pm

Re: Tons of street lights

Post by ahmadi »

Hi, I have two idea, that i hope be usefull for improving your new technique.
First, Please see following screenshots:
http://ui31.gamespot.com/1694/4087gta4screenshot_2.jpg
http://image.com.com/gamespot/images/20 ... een019.jpg

Its very good if you use spotlight position + rotation for calculating your light space, this will cause that the result of 2 light sources(with different direction) be different in the ground and walls , and all light sources result don't appear in circle-like shape on the ground.

Two, I think the car light calculation over the walls is wrong, in the following screenshot the light place in the wall is wrong for the car ;)
Image

Thanks.
_________________________________
Best regards

Ahmadi
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

Re: Tons of street lights

Post by Kojack »

Actually the car headlight effect is a correct lambert diffuse illumination effect. The reason it looks wrong is because it's not a spotlight. I only added it to show a simple ogre POINT light moving in the scene. The point light is placed close to the ground several feet in front of the car.
I could have used a spotlight, but then I'd have to pass in another shader constant and I didn't feel like that at the time.

A direction could be added to the overhead spotlights, although it would make it more likely that they bleed into adjacent cells (any light trying to bleed across 2 cell boundaries will cause a visible seam).

This is the kind of effect I was aiming for:
ImageImage
Both of those shots are from Urban Empires. The dev blog (including shader code and descriptions of his lighting method) are at http://www.gamedev.net/community/forums ... cyear=2006
He uses a 2048x2048 world overhead lightmap, each street light is rendered into the texture with depth in the alpha component, then that is projected onto the scene.
User avatar
merlinblack
Goblin
Posts: 223
Joined: Thu Mar 15, 2007 10:05 am
Location: Sydney, Australia
x 7
Contact:

Re: Tons of street lights

Post by merlinblack »

This would be perfect for something like a flight simulator. The lack of shadows shouldn't matter if your view is mostly 1000ft plus. :) very distant road traffic's headlights could be done this way.
"He'd never realized that, deep down inside, what he really wanted to do was make things go splat."
Terry Pratchett, Reaper Man
Image
User avatar
ahmadi
Gnome
Posts: 312
Joined: Sat Nov 26, 2005 4:03 pm

Re: Tons of street lights

Post by ahmadi »

Hi Kojack.
I need your help about implementing spotlights with this idea.
One important problem is that, i don't have any idea about how can i pass spotlight information with RGBA.
(SpotDirection,SpotRanges,SpotColor)

New Question:
"We are calculating diffuse color from distance vector of between vertex positions and light positions, but my roads mesh is very very lowpoly, consider a plane with 4 vertices! then light circle is similar to a light rectangle! this problem is not relative to this idea, i have same problem in my other materials such as bump!
I want change linear interpolation between vertices to making better shape for my lights, because the lighting is rectangleshape-like on very low poly models.

Thanks
_________________________________
Best regards

Ahmadi
haltendehand
Halfling
Posts: 98
Joined: Wed Jun 16, 2010 11:44 pm
Location: Freiburg, Germany
Contact:

Re: Tons of street lights

Post by haltendehand »

The link to the demo is dead - does anyone still have it and could reupload it?
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

Re: Tons of street lights

Post by Kojack »

Luckily I found a copy on one of my hard drives. :)
I've uploaded it to: http://rajetic.users.sourceforge.net/streetlights.7z
haltendehand
Halfling
Posts: 98
Joined: Wed Jun 16, 2010 11:44 pm
Location: Freiburg, Germany
Contact:

Re: Tons of street lights

Post by haltendehand »

Thanks :)
loath
Platinum Sponsor
Platinum Sponsor
Posts: 290
Joined: Tue Jan 17, 2012 5:18 am
x 67

Re: Tons of street lights

Post by loath »

thanks for sharing your fantastic idea Kojack! i am integrating this into my project now for arbitrary environment lights (torches, glowing gems, street lamps, etc) in procedurally generated worlds and dungeons.

i wonder if the texture lookups could be done in the vertex shaders and have the lighting calculations be done in the pixel shader? i realize that may be too many TEXCOORD[n] parameters for shader model 3 / dx9 though.

either way, this is a very cool approach. thanks!
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

Re: Tons of street lights

Post by Kojack »

Looking up the grid in the vertex shader should work. That would be a LOT less texture lookups overall. Although depending on how many overlapped lights you want to support, there could be a lot of data to pass to the pixel shader.
Post Reply