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