Lab-13 is to add the following...

   • multiple lights
   • anti-aliasing

to a ray traced scene.

Post screen shots showing your scene,
   and a closeup of some anti-aliasing.

Show them on a web page at:

   public_html/3480/lab13.html

Note:
   - Use this lab page to build your: public_html/3480/lab13.html.
   - You can do a "View Page Source", or copy it.


Add multiple light sources to your ray tracing program. ------------------------------------------------------- Add the following code to your 3480/b/lab11.cpp program or another program such as trans.cpp. Whatever is your current ray tracing program. Scene from class with 3 light sources... Anit-aliasing added on Monday during class... Copy in the code, then use vi editor to indent correctly. //Add this //-------- #define MAX_LIGHTS 200 //Add this to the Global class //---------------------------- class Global { public: Vec lightPos[MAX_LIGHTS]; Vec lightCol[MAX_LIGHTS]; int nlights; //In init(), add this to your scene //--------------------------------- //This is 3 lights. //A key-light, fill-light, and a back light. g.nlights = 0; vecMake(400.0, 400.0, 500.0, g.lightPos[g.nlights]); vecMake(1.2, 1.2, 1.2, g.lightCol[g.nlights]); ++g.nlights; vecMake(-400.0, 100.0, 500.0, g.lightPos[g.nlights]); vecMake(0.3, 0.3, 0.3, g.lightCol[g.nlights]); ++g.nlights; vecMake(-1800.0, 100.0, -1500.0, g.lightPos[g.nlights]); vecMake(0.5, 0.9, 0.5, g.lightCol[g.nlights]); ++g.nlights; //Change the getShadow() function header to this //---------------------------------------------- bool getShadow(int idx, Vec pt) //New code in the getShadow() function //------------------------------------ vecSub(g.lightPos[idx], pt, lightDir); //New trace() function //-------------------- void trace(Ray *ray, Vec rgb, Flt weight, int level) { //Trace a ray through the scene. if (level > 5 || weight < 0.1) { return; } int i; Hit hit, closehit; Object *o; int h = -1; closehit.t = 9e9; for (i=0; i<g.nobjects; i++) { o = &g.object[i]; switch (o->type) { case TYPE_DISK: if (rayDiskIntersect(o, ray, &hit)) { if (hit.t < closehit.t) { closehit.t = hit.t; vecCopy(hit.p, closehit.p); vecCopy(o->color, closehit.color); vecCopy(o->norm, closehit.norm); h=i; } } break; case TYPE_RING: if (rayRingIntersect(o, ray, &hit)) { if (hit.t < closehit.t) { closehit.t = hit.t; vecCopy(hit.p, closehit.p); vecCopy(o->color, closehit.color); vecCopy(o->norm, closehit.norm); h=i; } } break; case TYPE_TRIANGLE: if (rayTriangleIntersect(o, ray, &hit)) { if (hit.t < closehit.t) { closehit.t = hit.t; vecCopy(hit.p, closehit.p); vecCopy(o->color, closehit.color); vecCopy(o->norm, closehit.norm); h=i; } } break; case TYPE_SPHERE: if (raySphereIntersect(o, ray, &hit)) { if (hit.t < closehit.t) { closehit.t = hit.t; vecCopy(hit.p, closehit.p); vecCopy(o->color, closehit.color); sphereNormal(closehit.p, o->center, closehit.norm); h=i; } } break; } } if (h < 0) { //ray did not hit an object. //Flt c = asin(ray->d[1]); Flt c = ray->d[1]; if (c < 0.0) c = 0.0; //if (c > 1.0) c = 1.0; rgb[0] += (g.sky[0][0] + (g.sky[1][0] - g.sky[0][0]) * c) * weight; rgb[1] += (g.sky[0][1] + (g.sky[1][1] - g.sky[0][1]) * c) * weight; rgb[2] += (g.sky[0][2] + (g.sky[1][2] - g.sky[0][2]) * c) * weight; return; } //Set the color of the pixel to the color of the object. o = &g.object[h]; if (o->surface == SURF_CHECKER) { int x = 10000.0 + (closehit.p[0]/2) / 37.0; int z = 10000.0 + (closehit.p[2]/2) / 37.0; x = x % 2; z = z % 2; if (x==z) { closehit.color[0] = 0.9; closehit.color[1] = 0.1; closehit.color[2] = 0.1; } else { closehit.color[0] = 0.9; closehit.color[1] = 0.9; closehit.color[2] = 0.9; } } if (o->sf_transmit > 0.0) { Ray rx; Vec nh; vecCopy(closehit.norm, nh); Flt kr, kt; fresnel(ray->d, nh, o->sf_iorOutside, o->sf_iorInside, kr); kt = 1.0 - kr; //reflect Vec rrgb = {0.0}; if (o->specular > 0.0) { kr *= o->spectrans; kt = 1.0 - kr; vecCopy(closehit.p, rx.o); reflect(ray->d, nh, rx.d); nudge_ray_forward(&rx); trace(&rx, rrgb, weight*kr, level+1); } //transmit Flt eta = o->sf_iorOutside / o->sf_iorInside; if ((vecDotProduct(ray->d, nh)) > 0.0) { //Normal is pointing the wrong way, so flip. vecNegate(nh); eta = 1.0 / eta; } refract(eta, ray->d, nh, rx.d); vecCopy(closehit.p, rx.o); Vec trgb = {0.0}; nudge_ray_forward(&rx); trace(&rx, trgb, weight*kt, level+1); rgb[0] += (rrgb[0] + trgb[0]); rgb[1] += (rrgb[1] + trgb[1]); rgb[2] += (rrgb[2] + trgb[2]); } //else if (o->specular) { if (o->specular) { //Build a reflected ray Vec rcol = {0,0,0}; Ray tray; #define DISPERSION #ifdef DISPERSION Vec tcol = {0,0,0}; int n = 0; for (int i=0; i<5; i++) { reflect(ray->d, closehit.norm, tray.d); vecCopy(closehit.p, tray.o); nudge_ray_forward(&tray); tray.d[0] += rnd() * .02 - .01; tray.d[1] += rnd() * .02 - .01; tray.d[2] += rnd() * .02 - .01; vecZero(rcol); trace(&tray, rcol, weight*0.5, level+1); tcol[0] += rcol[0]; tcol[1] += rcol[1]; tcol[2] += rcol[2]; ++n; } Flt fn = 1.0 / (Flt)n; rcol[0] = tcol[0] * fn; rcol[1] = tcol[1] * fn; rcol[2] = tcol[2] * fn; #else //DISPERSION reflect(ray->d, closehit.norm, tray.d); vecCopy(closehit.p, tray.o); nudge_ray_forward(&tray); vecZero(rcol); trace(&tray, rcol, weight*0.5, level+1); #endif //DISPERSION // rgb[0] += rcol[0] * o->spec[0] * weight; rgb[1] += rcol[1] * o->spec[1] * weight; rgb[2] += rcol[2] * o->spec[2] * weight; // //Look for specular highlight... //http://en.wikipedia.org/wiki/Specular_highlight //Blinn Phong lighting model for (int i=0; i<g.nlights; i++) { Vec lightDir, halfway; lightDir[0] = g.lightPos[i][0] - closehit.p[0]; lightDir[1] = g.lightPos[i][1] - closehit.p[1]; lightDir[2] = g.lightPos[i][2] - closehit.p[2]; halfway[0] = (lightDir[0] - ray->d[0]) * 0.5; halfway[1] = (lightDir[1] - ray->d[1]) * 0.5; halfway[2] = (lightDir[2] - ray->d[2]) * 0.5; vecNormalize(halfway); Flt dot = vecDotProduct(halfway, closehit.norm); if (dot > 0.0) { dot = pow(dot, 320.0); rgb[0] += g.lightCol[i][0] * dot; rgb[1] += g.lightCol[i][1] * dot; rgb[2] += g.lightCol[i][2] * dot; } } } // for (int i=0; i<g.nlights; i++) { bool inShad = false; inShad = getShadow(i, closehit.p); Flt dot = 0.0; if (!inShad) { //The hit point is not in shadow. //Get light contribution. //Dot product of light vector and surface normal. Vec v; vecSub(g.lightPos[i], closehit.p, v); vecNormalize(v); vecNormalize(closehit.norm); dot = vecDotProduct(v, closehit.norm); if (dot < 0.0) dot = 0.0; } //The ray hit an object. for (int j=0; j<3; j++) { rgb[j] += closehit.color[j] * dot * g.lightCol[i][j] * weight; } } rgb[0] += closehit.color[0] * g.ambient[0] * weight; rgb[1] += closehit.color[1] * g.ambient[1] * weight; rgb[2] += closehit.color[2] * g.ambient[2] * weight; return; }