How to do it...

To create a shader program that renders using the Blinn-Phong reflection model with multiple light sources, use the following steps:

In the vertex shader, we'll use a similar structure as in the previous recipes, except we will use an array of structures for the lights. In addition, we just store two intensities for each light. The first is the ambient intensity and the second is used for both diffuse and specular. The phongModel function is updated to use light information from one of the values in the array:

layout (location = 0) in vec3 VertexPosition; 
layout (location = 1) in vec3 VertexNormal; 
 
out vec3 Color; 
 
uniform struct LightInfo {
vec4 Position; // Light position in eye coords.
vec3 La; // Ambient light intesity
vec3 L; // Diffuse and specular light intensity
} lights[5];
// Material and matrix uniforms omitted...
vec3 phongModel( int light, vec3 position, vec3 n ) {
vec3 ambient = lights[light].La * Material.Ka;
vec3 s = normalize( lights[light].Position.xyz - position );
float sDotN = max( dot(s,n), 0.0 );
vec3 diffuse = Material.Kd * sDotN;
vec3 spec = vec3(0.0);
if( sDotN > 0.0 ) {
vec3 v = normalize(-position.xyz);
vec3 r = reflect( -s, n );
spec = Material.Ks *
pow( max( dot(r,v), 0.0 ), Material.Shininess );
}

return ambient + lights[light].L * (diffuse + spec);
}
void main() {
vec3 camNorm = normalize( NormalMatrix * VertexNormal);
vec3 camPosition =
ModelViewMatrix * vec4(VertexPosition,1.0)).xyz;

// Evaluate the lighting equation, for each light
Color = vec3(0.0);
for( int i = 0; i < 5; i++ )
Color += phongModel( i, camPosition, camNorm );

gl_Position = MVP * vec4(VertexPosition,1.0);
}

The fragment shader simply applies the color to the fragment, as in previous recipes.

In the OpenGL application, set the values for the lights array in the vertex shader. For each light, use something similar to the following code. This example uses the C++ shader program class described in Chapter 2, Working with GLSL Programs (prog is a GLSLProgram object):

prog.setUniform("lights[0].L", glm::vec3(0.0f,0.8f,0.8f) ); 
prog.setUniform("lights[0].La", glm::vec3(0.0f,0.2f,0.2f) );
prog.setUniform("lights[0].Position", position );

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

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