CMPS-3480 Computer Graphics
Lab-8
Overview:
Change to your 3480/8/ folder. Copy the lab files now... cp /home/fac/gordon/p/3480/code/lab8/* . Compile and run the program: make ./lab8 Pressing R renders a disk. If you see this image, your program is working. We will do some coding together to make an incredible scene. Get ready to code!
Homework is... Choose #1 or #2 1. Create an image using a new object type that you define, such as a ring. 2. Create a gif animation that seamlessly loops forever. Here are some images created with our lab8.cpp after class. For the planet Saturn you will need to define a ring object. This is a gif animation. You may setup a rendering loop outside of the main function for ray-tracing. lab8.cpp is not a real-time program. Setup some global variables to be used inside the init() function. Modify the variables inside your animation loop. Render and take a screenshot each frame of your animation loop.
We will code together starting at 7:20am. Some of our work will require that we copy & paste the code below. void sphereNormal(Vec hitPoint, Vec center, Vec norm) { //Calculate normal at hit point of sphere norm[0] = hitPoint[0] - center[0]; norm[1] = hitPoint[1] - center[1]; norm[2] = hitPoint[2] - center[2]; vecNormalize(norm); } int raySphereIntersect(Object *o, Ray *ray, Hit *hit) { //Log("raySphereIntersect()...\n"); //Determine if and where a ray intersects a sphere. // // sphere equation: // (p - c) * (p - c) = r * r // // where: // p = point on sphere surface // c = center of sphere // // ray equation: // o + t*d // // where: // o = ray origin // d = ray direction // t = distance along ray, or scalar // // substitute ray equation into sphere equation // // (o + t*d - c) * (o + t*d - c) - r * r = 0 // // we want it in this form: // a*t*t + b*t + c = 0 // // (o + d*t - c) // (o + d*t - c) // ------------- // o*o + o*d*t - o*c + o*d*t + d*t*d*t - d*t*c - o*c + c*d*t + c*c // d*t*d*t + o*o + o*d*t - o*c + o*d*t - d*t*c - o*c + c*d*t + c*c // d*t*d*t + 2(o*d*t) - 2(c*d*t) + o*o - o*c - o*c + c*c // d*t*d*t + 2(o-c)*d*t + o*o - o*c - o*c + c*c // d*t*d*t + 2(o-c)*d*t + (o-c)*(o-c) // // t*t*d*d + t*2*(o-c)*d + (o-c)*(o-c) - r*r // // a = dx*dx + dy*dy + dz*dz // b = 2(ox-cx)*dx + 2(oy-cy)*dy + 2(oz-cz)*dz // c = (ox-cx)*(ox-cx) + (oy-cy)*(oy-cy) + (oz-cz)*(oz-cz) - r*r // // now put it in quadratic form: // t = (-b +/- sqrt(b*b - 4ac)) / 2a // // //1. a, b, and c are given to you just above. //2. Create variables named a,b,c, and assign the values you see above. //3. Look how a,b,c are used in the quadratic equation. //4. Make your code solve for t. //5. Remember, a quadratic can have 0, 1, or 2 solutions. // //Your code goes here... // //I'll start you out with a and b //You try to do c // Flt a = ray->d[0]*ray->d[0] + ray->d[1]*ray->d[1] + ray->d[2]*ray->d[2]; Flt b = 2.0*(ray->o[0]-o->center[0])*ray->d[0] + 2.0*(ray->o[1]-o->center[1])*ray->d[1] + 2.0*(ray->o[2]-o->center[2])*ray->d[2]; Flt c = (ray->o[0]-o->center[0])*(ray->o[0]-o->center[0]) + (ray->o[1]-o->center[1])*(ray->o[1]-o->center[1]) + (ray->o[2]-o->center[2])*(ray->o[2]-o->center[2]) - o->radius*o->radius; Flt t0,t1; //discriminant Flt disc = b * b - 4.0 * a * c; if (disc < 0.0) return 0; disc = sqrt(disc); t0 = (-b - disc) / (2.0*a); t1 = (-b + disc) / (2.0*a); // if (t0 > 0.0) { hit->p[0] = ray->o[0] + ray->d[0] * t0; hit->p[1] = ray->o[1] + ray->d[1] * t0; hit->p[2] = ray->o[2] + ray->d[2] * t0; sphereNormal(hit->p, o->center, hit->norm); hit->t = t0; return 1; } if (t1 > 0.0) { hit->p[0] = ray->o[0] + ray->d[0] * t1; hit->p[1] = ray->o[1] + ray->d[1] * t1; hit->p[2] = ray->o[2] + ray->d[2] * t1; sphereNormal(hit->p, o->center, hit->norm); hit->t = t1; return 1; } return 0; } //This code segment will be added to trace() // if (o->specular) { //1. Reflect the ray off the specular surface. //Build a reflected ray Vec rcol = {0,0,0}; Ray tray; // reflect(ray->d, closehit.norm, tray.d); vecCopy(closehit.p, tray.o); nudge_ray_forward(&tray); vecZero(rcol); //Recursive call trace(&tray, rcol, weight*0.5, level+1); // rgb[0] += rcol[0] * o->spec[0] * weight; rgb[1] += rcol[1] * o->spec[1] * weight; rgb[2] += rcol[2] * o->spec[2] * weight; // //2. Look for a specular highlight... //http://en.wikipedia.org/wiki/Specular_highlight //Blinn Phong lighting model Vec lightDir, halfway; lightDir[0] = g.lightPos[0] - closehit.p[0]; lightDir[1] = g.lightPos[1] - closehit.p[1]; lightDir[2] = g.lightPos[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, 512.0); rgb[0] += 1.0 * dot; rgb[1] += 1.0 * dot; rgb[2] += 1.0 * dot; } }
Your instructor will find your work out on Odin!