5
$\begingroup$

In older versions of OpenGL there were things like:

  • glLight(...)

  • gl_LightSourceParameters

The modern way of doing lighting is passing light source parameters manually to the shader in vao-s? Or uniforms?

Why are these things decrepated?

And if I have 100 light sources in the scene, I obviously can't compute lighting with all of them. So somehow in a specific object's shading I have to only care about the light sources which are important for it.

I think that I should move for example only 8 light sources to the shaders, based on their "strength".

But isn't this too complicated to call every frame?

How should I handle lots of light sources (in the scene)?

/I read about deferred lighting, but is that the only way?/

$\endgroup$
9
$\begingroup$

Why are they deprecated?

Those functions are deprecated because the OpenGL API moved in favor of a programmable pipeline in contrast with the old fixed pipeline. The programmable pipeline allows the flexibility necessary to enable a wide variety of effects and solutions that before were difficult or not possible at all to implement. You can still access those functions, as they are necessary to support older systems, but besides that I don't see any reason not to use the programmable pipeline.

How to pass parameters

If we are talking about parameters of lights (such as their position or intensity), you can pass those using uniforms. Particularly, you should look at Uniform Buffer Objects.

It would look like this in a shader:

struct Light {
   int type;
   vec3 diffuse;
   vec3 position;
   bool on;
   ...
};

#define MAX_NUM_LIGHTS 8

uniform lightBlock {
    Light lights[MAX_NUM_LIGHTS];
};

Note that this already gives you a way of passing the lights that you want. Make your shaders expect an uniform buffer with 8 lights, copy those into an array in your client code and send them using the API. For more info on how to do this using the API functions, check the link above about UBOs and this.

Is it too complicated to call every frame?

Depends on your scene and the criteria for how to choose the lights that you want to pass to the shader. If you are worried about sending the data of 8 lights through uniforms each frame, then don't, that is the least of your worries. The problem lies in the selection process of the lights and the complexity of your scene/shading model, as the cost increases with the number of lights.

  • Forward Renderer: If your scene and shading models are simple, maybe 8 lights are okay. If you implement modern shading models, 8 lights might be a bit too much. The point is that you will have to test it with the scene and shading models and find a compromise between all of that. Maybe pass 4 instead of 8 lights, maybe you should simplify shading models, etc.
  • Deferred Renderer: A deferred renderer does help with multiple light rendering due to the way it is designed. However, deferred rendering may introduce other difficulties as it is, in my opinion, a more complex system. Also, transparency and other aspects may be a pain to deal with.

  • Other considerations: Keep in mind that there are possible optimizations. It may be possible to optimize specific lights. Maybe not all of them need to be dynamic: think of light maps and other image based lighting. You should consider if your scene can apply any of this.

In summary, choosing between deferred or forward is a big decision. Carefully think about your scene requirements first and devise a strategy for light selection. Take into account the complexity of your shading models. For optimization, you can combine several techniques, such as simplifying some lights that are far away from the camera and only pass the relevant ones. When you have a framework for testing, find a compromise between all of this.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.