RTSS: multiple lights handling sample

Discussion area about developing or extending OGRE, adding plugins for it or building applications on it. No newbie questions please, use the Help forum for that.
User avatar
Mattan Furst
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 260
Joined: Tue Jan 01, 2008 11:28 am
Location: Israel
x 32

RTSS: multiple lights handling sample

Post by Mattan Furst »

I just added a sample called "shader system - multi lights". The sample shows one possible (relatively) simple way of how to handle a large amount of lights.
This sample comes after a long struggle with the default implementation of the RTSS lighting.

Part of the original guidelines under which the RTSS was created was to emulate the fixed pipeline mechanism as close as possible. Due to this fact and how it was interpreted using multiple lights in RTSS with the default implementation is problematic. Every light requires it's own lines of code in the shader. Every time an object receives a different amount of lights the shader for it is invalidated and recompiled. Amount of lights is also limited by the amount of const registers a shader profile can supports.

The sample I added shows a different approach to rendering lights in RTSS. A few points on this sample
  • Only one directional light is supported.
  • Point lights and spot lights are handled through the same code.
  • Light attenuation is only controlled by range. all other parameters are ignored. This is to partly to produce more efficient shader programs and partly to make the system more easier to set up .
  • Point light specular effect is not calculated, partly to produce more efficient shader programs, and partly because I'm lazy. I'll try to add it at a later date. Shouldn't be to difficult if anyone wants to take a crack at it.
  • Sample requires shader model 3 or higher to run.
  • Large amount of lights can be supported. Limited currently by the size of the texture used to send the light information to the shader (currently set to a 9x9 grid. each grid cell can contain 32 lights).
  • The world is divided into a grid of 9x9 cells (can be easily increased). Each cell receives it's own list of lights appropriate only for it. This can be increased depending on your situation.
  • Grid size and position is recalculated every frame.
  • The information of the lights in the grid is transfered onto a texture. Which is sent to the shader.
  • The list of lights is iterated over in the shader through a dynamic loop. This means there is no need to recompile the shader when the number of lights affecting an object change.
Note:
This code was partly inspired by Kojack's "Tons of street lights" (http://www.ogre3d.org/forums/viewtopic.php?t=48412) idea.
You do not have the required permissions to view the files attached to this post.
it's turtles all the way down
User avatar
duststorm
Minaton
Posts: 921
Joined: Sat Jul 31, 2010 6:29 pm
Location: Belgium
x 80

Re: RTSS: multiple lights handling sample

Post by duststorm »

I bet this will be really useful for some (including myself).
Maybe the "mulitple lights" title can be a bit confusing, because I believe this approach (using texture lookup) is only beneficial when using A LOT of lights (Well, probably any amount of lights that would require multiple shader passes -- don't know how much that would be for eg. shader model 3. But it's hard to give an estimate here anyway, as it depends on how the lights shader is implemented)

And streetlights would indeed be a very good usecase for it. ;)
Developer @ MakeHuman.org
User avatar
Mattan Furst
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 260
Joined: Tue Jan 01, 2008 11:28 am
Location: Israel
x 32

Re: RTSS: multiple lights handling sample

Post by Mattan Furst »

The implementation isn't a street light implementation. The grid is only 9x9 and updates in size every frame.
There reason I chose to implement it in a small gird was to attempt to strike a balance between a scenario requiring several dozen is lights and a scenario very few lights. With very few lights this system grid wont have much of an overhead and with several dozen lights it should have a better performance than simply giving everything to the shader as a long list (as long as they are spaced enough between one another).

Kojak "Tons of street lights" idea will still be far better if you want to use thousands of evenly spread lights.

P.S.
[s]There area a couple of bugs in the code. for instance, lights of type point are not to shown. I'll fix it tomorrow.[/s]
edit: bugs fixed
it's turtles all the way down
User avatar
duststorm
Minaton
Posts: 921
Joined: Sat Jul 31, 2010 6:29 pm
Location: Belgium
x 80

Re: RTSS: multiple lights handling sample

Post by duststorm »

Ok, so
The grid is updated every frame so you can have moving lights in the scene. Contrary to kojack's approach where all the lights were in static positions.
Developer @ MakeHuman.org
User avatar
Mattan Furst
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 260
Joined: Tue Jan 01, 2008 11:28 am
Location: Israel
x 32

Re: RTSS: multiple lights handling sample

Post by Mattan Furst »

@duststorm

Basically yes.
you can have moving lights in kojak's method. I think he has a couple. But
1. you have to distribute them evenly. you can only support 1 light per cell.
2. you have to have a method where most lights are already pre-distributed or that you know where most lights will go. simply because distributing thousands of lights takes CPU time.

The "Show grid" check box in the sample activates a special shader where you can see the how the grid is calculated.
it's turtles all the way down
User avatar
masterfalcon
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 4270
Joined: Sun Feb 25, 2007 4:56 am
Location: Bloomington, MN
x 126

Re: RTSS: multiple lights handling sample

Post by masterfalcon »

A couple comments.

1. __int16 is VS only. Won't compile with gcc
2. mSRSSegLightFactory may be null when the sample is initialized, causing crashes in _shutdown.
3. Does it require vs_3_0 or ps_3_0? Comment and actual check conflict.

Also, I have neither profile supported, but the sample works if I comment out the check.
User avatar
Mattan Furst
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 260
Joined: Tue Jan 01, 2008 11:28 am
Location: Israel
x 32

Re: RTSS: multiple lights handling sample

Post by Mattan Furst »

@masterfalcon
1 and 2 I belive are fixed.

About the ps_3_0 thing. The pixel shader in this sample uses a dynamic for loop. Dynamic for loops are supported from pixel shader 3 and above. If you use less than that the shader either: won't compile. roll out the loop a few time so you will only be able to see a couple of lights. Or, roll out the for loop many times making the shader very inefficient.

I'm not sure what happens on unix type operating systems. I though ps_3_0 was a profile used for both windows and unix.
I've never figured out how to program on unix operating systems.
it's turtles all the way down
kariem2k
Kobold
Posts: 25
Joined: Sun Jan 09, 2005 10:16 pm
Location: Alexandria, Egypt
x 1

Re: RTSS: multiple lights handling sample

Post by kariem2k »

I had that exception on my NVIDIA 525m on Windows 7 x64: "This sample uses dynamic loops in cg type shader language, your graphic card must support shader 3 profile or above."

After changing the check for ps_3_0 to fp30 it worked without problems.
Kariem2k.blogspot.com
User avatar
duststorm
Minaton
Posts: 921
Joined: Sat Jul 31, 2010 6:29 pm
Location: Belgium
x 80

Re: RTSS: multiple lights handling sample

Post by duststorm »

kariem2k wrote:I had that exception on my NVIDIA 525m on Windows 7 x64: "This sample uses dynamic loops in cg type shader language, your graphic card must support shader 3 profile or above."

After changing the check for ps_3_0 to fp30 it worked without problems.
Yes apparently the sample searches for DirectX shader profiles only. This will make the sample work on windows only.
Maybe it should be extended with fp30/vp30 and fp40/vp40, as currently when trying to launch the sample on an openGL-only OS you get an error message saying your graphics hardware should support shader profile 3 (which it actually does).

I'll have to try it on my machine too ;)
Developer @ MakeHuman.org
User avatar
Mattan Furst
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 260
Joined: Tue Jan 01, 2008 11:28 am
Location: Israel
x 32

Re: RTSS: multiple lights handling sample

Post by Mattan Furst »

I don't have a machine which is openGL only. I tired to enable the sample for directX11 (ps_4_0) but it crashed so I didn't want to enable it for anything I wasn't completely sure would work.

Tell me which profile to add and I'll add it.
I'll add the fp30 profile tonight

btw
is ps_3_0 windows only. I though it was an NVidia profile?
it's turtles all the way down
bstone
OGRE Expert User
OGRE Expert User
Posts: 1920
Joined: Sun Feb 19, 2012 9:24 pm
Location: Russia
x 201

Re: RTSS: multiple lights handling sample

Post by bstone »

ps_3_0 is a DirectX profile hence it's Windows only. NVidia's profiles are fp*/vp*.
User avatar
duststorm
Minaton
Posts: 921
Joined: Sat Jul 31, 2010 6:29 pm
Location: Belgium
x 80

Re: RTSS: multiple lights handling sample

Post by duststorm »

I can confirm, adding this line makes the sample work on non-DirectX enabled operating systems:

Code: Select all

diff -r 9ff73eb39344 Samples/ShaderSystemMultiLight/include/ShaderSystemMultiLight.h
--- a/Samples/ShaderSystemMultiLight/include/ShaderSystemMultiLight.h	Fri Jul 13 22:03:47 2012 +0300
+++ b/Samples/ShaderSystemMultiLight/include/ShaderSystemMultiLight.h	Wed Jul 18 09:57:32 2012 +0200
@@ -112,7 +112,9 @@
 
     void testCapabilities( const RenderSystemCapabilities* caps )
     {
-        if (!Ogre::Root::getSingletonPtr()->getRenderSystem()->getCapabilities()->isShaderProfileSupported("ps_3_0"))
+        if (!Ogre::Root::getSingletonPtr()->getRenderSystem()->getCapabilities()->isShaderProfileSupported("ps_3_0") &&
+        !Ogre::Root::getSingletonPtr()->getRenderSystem()->getCapabilities()->isShaderProfileSupported("fp30")
+        )
 		{
             OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, "This sample uses dynamic loops in cg type shader language, your graphic card must support shader 3 profile or above."
                 " You cannot run this sample. Sorry!", "Sample_ShaderSystemMultiLight::testCapabilities");
Just like with ps I assume it's only necessary to list the minimal required version? Will a machine that is capable of fp40 also have the profile fp30 in all cases?
Developer @ MakeHuman.org
CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 58

Re: RTSS: multiple lights handling sample

Post by CABAListic »

Yes, but it's an Nvidia-specific profile and will probably fail on AMD cards. Also, fp30 does not equal shader level 3, as far as I remember, because it's named after the NV3x chip and not the shader level. fp30 is closer to shader 2.x, I believe. Better to require fp40 if you really need full shader level 3 support.
User avatar
Mattan Furst
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 260
Joined: Tue Jan 01, 2008 11:28 am
Location: Israel
x 32

Re: RTSS: multiple lights handling sample

Post by Mattan Furst »

Added fp40 profile
it's turtles all the way down