PS2 Linux Programming

 

Ambient Light and 3 Directional Coloured lights

 

Introduction

 

This tutorial demonstrates rendering using 3 directional light sources and ambient light. Each directional light source has colour and direction and the ambient light source has colour. The light source calculations are undertaken by VU1.

 

 

Background

 

Light source calculations are used to determine the contribution at the vertex of each light source within a virtual world. The vertex normal determines the orientation of the vertex, and hence the contribution that each light source makes when determining the illumination level of the vertex.

 

The following information is required in order to perform light source calculations:

 

(Nx, Ny, Nz)               The vertex normal in local space.

(Lx, Ly, Lz)                 The light source direction vector.

(Lr, Lg, Lb)                 The light source colour intensities.

(Ar, Ag, Ab)                The background ambient light intensities.

 

 

Firstly it is necessary to convert the normal vectors from local model space to world space. This is required because the light direction vectors are defined in world space, whereas the model normals are in local space. The conversion is achieved by multiplying the vertex normals by the world matrix for the model being drawn.

 

 

 

 

 

 

 

(NWx, NWy, NWz) is the vertex normals in world space. Notice that the vertex normals must only be transformed by the rotation components of the world transformations matrix since only the orientation of the normals need to be altered. Including the translation components within the matrix will provide the wrong result. In practice , it is only necessary to send the rotation parts of the world transformation matrix to the VU for processing the normals.

 

Next the dot product must be obtained between the vertex normal and the light source direction to obtain the influence of the light source on the vertex. This can be accomplished in matrix form for all three light sources as shown below. Note that it is necessary to reverse the direction of the light vectors prior to performing the dot product.

 

 

 

 

 

 

 

LI1, LI2 and LI3 are the influence that each of the light sources make on the vertex.

 

Next the light source influence colour is obtained. The light source influence colour is the contribution that each light source makes to the final colour of the vertex. Again, this can be accomplished in matrix form as shown below.

 

 

 

 

 

 

 

(LIr, LIg, LIb) is the total red, green and blue contributions from all of the three light sources. The final colour of the vertex is obtained by adding the ambient light intensity to the light source influence colour.

 

 

 

 

 

Where (R, G, B) is the final vertex colour.

 

 

 

Example Code

 

 

The layout of data in VU memory is shown below:

 

 

 

Address

Data

0

Transformation Matrix Row #0

1

Transformation Matrix Row #1

2

Transformation Matrix Row #2

3

Transformation Matrix Row #3

4

World Matrix Row #0

5

World Matrix Row #1

6

World Matrix Row #2

7

World Matrix Row #3

8

Scaling Vector (number of vertices in w)

9

Directional Light Vector #1 (normalised)

10

Directional Light Vector #2 (normalised)

11

Directional Light Vector #3 (normalised)

12

Light Colour #1

13

Light Colour #1

14

Light Colour #1

15

Ambient Light

16

GIFTag

17

Texture Coordinate (STQ) for Vertex #1

18

Normal for Vertex #1

19

Position for Vertex #1

20

Texture Coordinate (STQ) for Vertex #2

21

Normal for Vertex #2

22

Position for Vertex #2

23

Texture Coordinate (STQ) for Vertex #3

24

Normal for Vertex #3

25

Position for Vertex #3

etc

etc

 

 

                        VU1 Data Memory Layout

 

The lighting information is constructed using the following code:

 

 

// Set up 3 directional lights

Vector4 LightDir1( 1,  0,  0,  0);   

Vector4 LightDir2(-1,  0,  0,  0);

Vector4 LightDir3( 0,  0, -1,  0);

 

// Then normalise.

LightDir1.NormaliseSelf();

LightDir2.NormaliseSelf();

LightDir3.NormaliseSelf();

 

// Light dir matrix (on VU1 we can do 3 lights + Ambient for the same price as 1)

VIFStaticDMA.AddVector(Vector4(LightDir1.x,LightDir2.x,LightDir3.x,0));

VIFStaticDMA.AddVector(Vector4(LightDir1.y,LightDir2.y,LightDir3.y,0));

VIFStaticDMA.AddVector(Vector4(LightDir1.z,LightDir2.z,LightDir3.z,0));

 

// Light colour matrix (3 directional light colours)

VIFStaticDMA.AddVector(Vector4(128,  0,  0,  0));

VIFStaticDMA.AddVector(Vector4(0  ,128,  0,  0));

VIFStaticDMA.AddVector(Vector4(0  ,  0,128,  0));

// Ambient light colour

VIFStaticDMA.AddVector(Vector4( 10, 10, 10,  0));

 

 

Notice that the light direction vectors are normalised prior to being added to the static packet memory. Also note that the light direction vectors are in column major order. In this particular arrangement, there are three light sources, a red source is pointing in the x direction, a green source is pointing in the negative x direction and a blue source is pointing in the negative z directions. This arrangement is illustrated in pictorial form below.

 

 

 

 

 

The Vector Unit code which performs the lighting calculations is shown below.

 

 

;LIGHTING CALCULATIONS

lq.xyz        Norm, StartNorm(iVertPtr)    ; Load the normal

 

mul.xyz   acc,  fLightTrans[0],  Norm[x]    ; Transform by rotation part of the world matrix

madd.xyz  acc,  fLightTrans[1],  Norm[y]

madd.xyz  Norm, fLightTrans[2],  Norm[z]

 

mula.xyz  acc, fLightDirs[0], Norm[x]       ; "Transform" normal by light direction matrix

madd.xyz  acc, fLightDirs[1], Norm[y]       ; This has the effect of outputting a vector with

madd.xyz  fIntensities, fLightDirs[2], Norm[z]  ; three intensities, one for each light.

mini.xyz  fIntensities, fIntensities, vf00[w]   ; Clamp the intensity to 0..1

max.xyz   fIntensities, fIntensities, vf00[x]

 

mula.xyz  acc, fLightCols[0], fIntensities[x]   ; Transform intensities by light colour matrix

madda.xyz acc, fLightCols[1], fIntensities[y]   ; This gives total directional light colour

madda.xyz acc, fLightCols[2], fIntensities[z]

madd.xyz  fIntensities, fAmbient, vf00[w]

 

 

addi.w    fIntensities, vf00, i                 ; Store the alpha value

ftoi0     fIntensities, fIntensities            ; Convert to int

 

sq        fIntensities, StartNorm(iVertPtr)     ; And write to the output buffer

;END LIGHTING CALCULATIONS

 

 

It can be seen that the vector unit code follows exactly the algorithms presented above.

 

 

Sample Application

 

The sample application shows a rotating textured cube illuminated by the three directional lights and ambient light. As the cube rotates, the effect of the red light shining from the left, the green light from the right and the blue light from the direction of the viewer can be seen. It is possible to rotate the cube around the origin using the left and right directions buttons, and the camera can be moved around as in the previous applications using the analogue skicks.

 

 

Conclusions

 

This tutorial has provided background on the use of directional coloured lighting and has illustrated the techniques in the sample application.

 

 

 

Dr Henry S Fortuna

University of Abertay Dundee

h.s.fortuna@abertay.ac.uk