Use of color in lights

Colors are light properties. In Chapter 3, Lights, we saw that the number of light properties depend on the lighting reflection model selected for the scene. For instance, using a Lambertian reflection model we would only need to model one shader uniform: the light diffuse property/color. In contrast, if the Phong reflection model were selected, each light source would need to have three properties: the ambient, diffuse, and specular colors.

Note

The light position is usually also modeled as a uniform when the shader needs to know where the light source is. Therefore, a Phong model with a positional light would have four uniforms: ambient, diffuse, specular, and position.

For the case of directional lights, the fourth uniform is the light direction. Refer to the More on Lights: positional lights section discussed in Chapter 3, Lights!.

We have also seen that each light property is represented by a four-element array in JavaScript and that these arrays are mapped to the vec4 uniforms in the shaders as shown in the following diagram:

Use of color in lights

The two functions we use to pass lights to the shaders are:

  • getUniformLocation— locates the uniform in the program and returns an index we can use to set the value
  • uniform4fv— since the light components are RGBA, we need to pass a four-element float vector

Using multiple lights and the scalability problem

As you could imagine, the number of uniforms grow rapidly when we want to use more than one light source in our scene — for each one of them, we need to define and map as many uniforms as we need depending on the lighting model of choice. This approach makes the programming effort simple enough — we have exactly one uniform for each light property we want to have, for each light. However, let's think about this for a moment. If we have four properties per light (ambient, diffuse, specular, and location) this means that we have to define four uniforms per each light. If we want to have three lights, we will have to write, use, and map 12 uniforms!

How many uniforms can we use?

The OpenGL Shading Language ES specification delineates the number of uniforms that we are allowed to use. (Section 4.3.4 - Uniforms):

There is an implementation dependent limit on the amount of storage for uniforms that can be used for each type of shader and if this is exceeded it will cause a compile-time or link-time error.

In order to know what the limit is for your WebGL implementation, you can query WebGL using the gl.getParameter function with these constants:

gl.MAX_VERTEX_UNIFORM_VECTORS
gl.MAX_FRAGMENT_UNIFORM_VECTORS

The implementation limit is given by your browser and it depends greatly on your graphics hardware. For instance, my MacBook Pro running Firefox tells me that I can use 1024 uniforms.

Now, the fact that we have enough variable space does not necessarily mean that the problem is solved. We still have to write and map each one of the uniforms and as we will see later in exercise ch6_Wall_Initial.html, the shaders become a lot more verbose doing this.

Simplifying the problem

In order to simplify the problem (and code less), we could assume, for instance, that the ambient component is the same for all the lights. This allows reducing the number of uniforms — one uniform less for each light. However, this is not a pretty or an extensible solution for more general cases where we cannot assume that the ambient light is a constant.

Let's see how the shaders in a scene with multiple lights look like. First, let's address some pending updates to our architecture.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.227.190.93