Single Pass Lighting question


can someone me explain why there is a for-loop inside the single pass lighting fragment shader? I’ve noticed that the fragment shader is called for every light in the scene.

As far as I understand, the fragment shader is called 3 times if I have 3 lights in the scene. But the for-loops inside the shader will also called 3 times. This means that the shader for-loop is called 9 times for 3 lights right?

I thought single pass lighting means only one fragment shader call and a for-loop that loops through all lights in the scene.

What is the difference to multi pass lighting?

best regards,


Did you set it up correctly?


If you did that it should render up to the number of lights specified in a single pass. Though if you specify 6 lights and use 7 it will be executed twice.

I have disabled the light culling feature but it’s the same result


I realized that the default batch size is 1. That would explain the multiple execution of the fragment shader.

Nope, the for loop is executed once per light.
The thing is, there are 3 vector4 per light in the array of light data so if you look closer the iteration idex is icremented 3 times per loop.
So yes for 3 lights the light data array has a size of 9, but the lopp will be executed 3 times.

The single lighting will do one geometry pass for each NB_LIGHT batch of light. Nb light is determined by

Then the light filtering found the lights that are influencing the objects in the frustum and send the light data to the shader.

Note that for example if you set the number of light per batch to 6, and if there are for example 8 lights for the current frame, there will be 2 geometry passes.
The first one will render 6 lights and the second one will render 2 lights.
Note though, that for the second pass with 2 lights, the loop will wtill be executed 6 times.
This may be counter intuitive, but with shaders, it’s better to have a fixed number of iteration rather than having a dynamic number.

Ok now I understand it, thank you :smile:
Btw. I have another question:

After the pixel color was calculated in the fragment shader, I apply fog to it. But if the fragement shader is called twice, the fog intensity increases for the related geometry.

I use “mix” to control the color:

   #ifdef FOG
     gl_FragColor.rgb = mix(m_FogColor.rgb, gl_FragColor.rgb, FogFactor);

Is there antoher way the apply the fog only once to that pixel?

That’s a good question…
There is no way to know in what pass you are on…

@Momoko_Fan what do you think? IMO the best course of action here would be to make the Fog params global params and have a way to set set per pass.
Or we could add a define containing the pass index…but that would mean a shader compilation between the passes…

If possible for you game, I might suggest to apply fog via a screenspace filter that reads the depth value and the modifies the framebuffer accordingly.

Sorry to interrupt and maybe ask something a little out of topic, but how to access this options from the renderManager ? Like setLightFilter , setPreferredLightMode and setSinglePassLightBatchSize ? I could not find info about that anywhere …
Its 3.1 maybe ?

yep it’s 3.1

I tried the screenspace fog filter from jme but I had problems in combination with other filters. Is it possible to implement all these fog versions with screenspace filters? =>

I prefer fragment shader based fog over the screenspace filter one but I think I have to do so if there no other way :-/

As far as I know it should be possible, but I have not done it myself, so there might be issues going that way. As for the fragment one, if you set the batchsize extremly large, it should only be called once or?

yeah but at some point you are doing useless iterations over non existing lights int he shader.
We really need something more clever

maybe a check if there is no more light to iterate to prevent useless iterations?

no, as I said before, non constant iteration number are worst in shaders.