![]() |
![]() |
| A view of a tilted plane with a projected texture from the light source | A view from beside the light source |
This only works for a light source located on the Z axis. In your assignment, you need to be able to move the light source anywhere.
void
lightShader(int WhichLight, float *color)
{
float localU, localV;
vec_set(color,0,0,0);
/* Do a simple projection */
/* First, project onto UV plane, parallel to XY plane, by scaling x and y */
localU = surfacePosition[0] / lights[WhichLight].uscale;
localV = surfacePosition[1] / lights[WhichLight].vscale;
/* Add perspective: divide u and v by z distance from light to surface */
localU /= (-surfacePosition[2] + lights[WhichLight].position[2]);
localV /= (-surfacePosition[2] + lights[WhichLight].position[2]);
/* Rescale to between 0 and 1 */
localU = ((localU + 1) / 2.0);
localV = ((localV + 1) / 2.0);
if((localU >= 0) && (localU <= 1) && (localV >= 0) && (localV <= 1))
{
int iu = localU * theTexture->width;
int iv = theTexture->height - localV * theTexture->height;
float tcolor[3];
/* Evaluate the texture here */
if((iu >= 0) && (iu < theTexture->width) &&
(iv >= 0) && (iv < theTexture->height))
{
Pixel pixel = ImagePixel(theTexture, iu, iv);
vec_set(tcolor, pixel.r / 255.0, pixel.g / 255.0, pixel.b / 255.0);
}
else
vec_set(tcolor,0,0,0);
vec_comp_mult(lights[WhichLight].color,tcolor,color);
}
}
void
shader(float *color)
{
float ambientColor[3] = { 0.1, 0.1, 0.1 };
float eye2Surf[3];
int i;
/* Compute vector from surface to eye. */
vec_sub(eyePosition,surfacePosition,eye2Surf);
vec_normalize(eye2Surf);
/* For each light, compute its contribution */
vec_set(color,0,0,0);
for(i=0 ; i<numLights ; i++)
{
float light2Surf[3];
float edotn;
float tmp[3];
float lcolor[3];
/* Can we see the light? */
lightShader(i, lcolor);
/* Compute vector from light to surface. */
vec_sub(lights[i].position,surfacePosition,light2Surf);
vec_normalize(light2Surf);
/* Add diffuse component. */
edotn = vec_dot(light2Surf,surfaceNormal);
if(edotn > 0)
{
vec_scale2(edotn,diffuseColor,tmp);
vec_comp_mult(tmp,lcolor,tmp);
vec_add(color,tmp,color);
}
}
vec_add(color,ambientColor,color);
vec_clamp(color, 0, 1);
}
# # This stuff has nothing to do with the shader, only scene layout # string patchObject = plane.obj int loDice = 10 int hiDice = 200 int numLights = 1 vec eyePosition = 0 0 20 vec light0Pos = 0 0 20 vec light0Dir = 0 0 -1 vec light0Up = 0 1 0 color light0Color = 1 1 1 float light0UScale = 1 float light0VScale = 1 # # Shader variables go here # string whichShader = diffuse color diffuseColor = 0.4 0.4 0.4 string textureName = stencil2.ppm