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); /* Project this surface point onto the "projection" plane. Here, we use orthogonal projection. */ localU = surfacePosition[0] / lights[WhichLight].uscale; localV = surfacePosition[1] / lights[WhichLight].vscale; /* Do simple projection */ 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->cols; int iv = theTexture->rows - localV * theTexture->rows; float tcolor[3]; /* Evaluate the texture here */ if((iu >= 0) && (iu < theTexture->cols) && (iv >= 0) && (iv < theTexture->rows)) { unsigned long val = theTexture->pixel[iv][iu]; vec_set(tcolor,((val>>24)&0xff)/255.0, ((val>>16)&0xff)/255.0, ((val>>8)&0xff)/255.0); } else vec_set(tcolor,0,0,0); vec_comp_mult(lights[WhichLight].color,tcolor,color); } }
void shader(float *color) { 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); CLAMP_COLOR(color); }
# # 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