 |
 |
|
 | |
Terrain Tutorial
Simulating Lighting Computations
Lighting a surface can be a costly operation. In this section it will be shown how to compute the colors of a vertex as if it was being lit by a light source. For the sake of simplicity only the diffuse component will be taken into account. Two types of light sources will be considered: Directional and Point lights.
According to the red book the diffuse component of the vertex color is defined as
(max { L . n, 0} ) * diffuseLight * diffuseMaterial
where
L is a unit length vector that points
from the vertex to the light position
n is a unit lenght normal for the vertex
and
L . n means the inner product between two vectors
The definition of inner product is as follows:
Consider two vectors a = [ax,ay,az] and b = [bx,by,bz].
the inner product is a number computed as following:
ip = ax * bx + ay * by + az * bz
As mentioned before two types of lights are dealt in here: Directional and Point lights. For a directional light the vector L is constant because the light rays are considered to be parallel, i.e. the vector from a vertex to the light position is not dependent of the vertex position. In fact, in OpenGL when defining a Directional Light we're not defining its position but the direction L. Because OpenGL does not require this vector to be unit length it is necessary first to normalize it.
To compute the diffuse component the following information is required:
L = [Lx,Ly,Lz] - the vector from the vertex to the light source
n = [nx,ny,nz] - the vertex normal
dL = [dLR, dLG, dLB] - the diffuse component of the light (RGB)
dv = [dvR, dvG, dvB] - the diffuse component of the vertex (RGB)
The complete process for lighting a vertex with a directional light is resumed to:
1. Normalise L
l = sqrt(Lx * Lx + Ly * Ly + Lz * Lz);
Lx = Lx / l;
Ly = Ly / l;
Lz = Lz / l;
2. Compute the inner product between L and n.
ip = Lx * nx + Ly * ny + Lz * nz
3. Check to see if its larger than zero
if (ip < 0)
ip = 0;
4. Compute the vertex lit color vc = [vcR, vcG, vcB]
vcR = ip * dLR * dvR
vcG = ip * dLG * dvG
vcB = ip * dLB * dvB
In the directional light case, step 1, the normalisation of L, should be done only once because L is the same for every vertex.
For point lights, the process is similar, the only difference being in step 1. In this case the computation of L is required. Assuming that
the vertex position is v = [vx,vy,vz],
the light position is l = [lx,ly,lz]
then step 1 becomes:
1.1. Compute the vector from the vertex to the light source
vl = [vlx, vly, vlz]
where
vlx = lx - px
vly = ly - py
vlz = lz - pz
1.2. Normalise vl to obtain L
length = sqrt(vlx*vlx + vly*vly + vlz*vlz)
Lx = lx / length
Ly = ly / length
Lz = lz / length
Steps 2 to 4 are identical for both light types. The next section shows the implementation details and the relevant functions.
|