Lighthouse3d.com

Please send me your comments
Terrain Tutorial

Index

Introduction

A TGA Library
A Simple TGA Library
TGA lib Source

Height Maps
Height Maps from Images

Lighting
Computing Normals
Simulating Lighting
Implementation Details
Screen Shots

Source Code

Artificial Terrain Generation
The Fault Algorithm
Implementation Details
Two Simple Variations
The Circles Algorithm

Mid Point Displacement
The MPD Algorithm

Particle Deposition

Smoothing
Smoothing
Matrix filters
API details

Source (Linux and Win32)

[Previous: Computing Normals] [Next: Implementation Details]

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.

    [Previous: Computing Normals] [Next: Implementation Details]