Number of existing lights in shader

Started by Thomas., March 05, 2012, 01:26:36 PM

Previous topic - Next topic

Thomas.

How can I find how much lights exists in fragment shader?

EgonOlsen

It will be injected by the engine. Just look at the documentation of the GLSLShader-class.

Thomas.

OK, thanks. And what is the best for programming of mobile shaders?

Thomas.

#3
Where is problem? I know, scene have 2 lights, when I use this, everything working


...

void main()
{
    ...
    for (int i = 0; i < 2; i++){
        ...
    }
}


but this not

uniform int lightCount;
...
void main()
{
    ...
    for (int i = 0; i < lightCount; i++){
    ...
    }
}


edit: I know where is problem, this code is compiled and probably all loops are transformed to code without loops (lightCount when code is compiling is zero)... So conditions have to be used in this case...

EgonOlsen

That would have been one of my hints about shaders on mobile devices, if you hadn't it found out already... ;) It's actually fine to use that for-loop and it does work on some chips/drivers but not on others. On Adreno chips, it can crash the phone badly when using this. That's why jPCT-AE's default shaders look that ugly with all these ifs in them.

Other hints:

Do as much as possible in the vertex shader. If you are doing calculations in the fragment shader that are not per fragment, move them into the vertex shader and use a varying to access the result.

Move complex uniforms into the vertex shader even if you need them in the fragment shader only if you update them every frame. For example: It's faster to put a vec4 uniform into the vertex shader and copy it into a varying to use it in the fragment shader than to put it directly into the fragment shader.

Be prepared for bugs in the shader compiler. PowerVR, nVidia and Mali are pretty much ok, but Adreno really sucks. But even on PowerVR, i had strange results with some shaders. For example, i had to introduce pointless variables with no need into the vertex shader to prevent the compiler from compiling a shader that paints everything in black (again, you can find this gem somewhere in the default shaders).

Don't rely on high precision in the fragment shader. The implementation is free to use medium precision instead and Mali chipset do so.

...

Thomas.

OK, thanks for your reply and tips :) ... Sometimes, I did change, which I think that is OK, compiling is OK, but when app is running, it shut down withou error log...
I added support for up to 8 lights, repair additional and ambient color, but transparency and specular still does not working... Anyway Galaxy S, 3 lights 25fps, sensation 1 light 60fps, Galaxy S2 with 3 lights 60fps

Thomas.

Is possible set specific lighting for each light? For example, one light will be per-pixel, one per-vetex, one spot? Probably yes, but I really do not know how...

Thomas.

Mobile shaders is wrong! Just one condition in fragment shader (lightCount > 0) takes down fps by 8 frames! And a lot of bugs... now I know what Egon was talking about... So the best solution will be use stupidity like 9 vertex and 9 fragment shaders for case without light, with one light,... ?
... now 49fps on galaxy s with one light :)

EgonOlsen

Yes, a set of separate shaders will be best, but you have to make some compromises...you can't write a specific shader for every case. Some have to be generic at the cost of lower performance or you'll end up with gazillions of shaders. Again, you might to look at the default shaders in the jar. jPCT-AE allows you to replace them, so you can already cover the most common cases by doing this.

Anyway, having conditions in the fragment shader is a performance killer...move them into the vertex shader whenever possible.

Thomas.

And what about specific light as point, spot,... how I find which light is for which lighting?

EgonOlsen

#10
Quote from: Thomas. on March 07, 2012, 08:57:45 PM
And what about specific light as point, spot,... how I find which light is for which lighting?
Either do your own light implementation with your own uniforms instead of jPCT-AE's, use some magic numbers encoded in either the lights position or color or try to guarantee a specific order. Depending on how you are using lights in the scene, you can use the Light.setDistanceOverride(...) in the latest beta versions for this.

Thomas.

Ok, so first is impossible, position of lights is sounds better, but is there any clear solution? spot light is for something like this (screen is from doom3)


EgonOlsen

If you override the distance with 100, 200, 300..., you should get the lights injected into the shader in that order. If that is a clear solution or a hack depends on the view of things...

Thomas.

Ok I'll try to play with it, else I have flare and it looks also good :)

Thomas.

Egon, could you add method for get number of lights in java code, please? Something like World.getLightCount()...