CMPS-3480 Computer Graphics
Lab-8
Overview:
1. Log into Odin 2. 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 Begin by pressing 1 then R. We will write code together. Follow along.
Follow along in class as we render the following scenes. 1. Eliminate random pixels. Draw all pixels. 2. Define 3 objects. 3. Each object will be a different distance from the camera. 4. Color the objects. 1. Adjust the surface normal of each object. 2. Duplicate this image. 1. Render Saturn with its rings and stars. 2. Add a ring object to your ray tracer. 3. Stars are discs.
the code will give you this... //perspective //in check_keys case XK_p: g.perspective ^= 1; break; //in render if (!g.perspective) { ray.o.make(x, y, 1000000.0); ray.d.make(0.0, 0.0, -1.0); } else { ray.o.make(0, 0, 400.0); ray.d.make(x-0, y-0, -400.0); } //lighting //set color of object if (obj[k].checker == 1) { Flt x = (hit.x+10000.0) / 100.0; Flt z = (hit.z+10000.0) / 100.0; int a = (int)x % 2; int b = (int)z % 2; if (a == b) c[0]=0, c[1]=155, c[2]=255; else c[0]=0, c[1]=255, c[2]=0; } //vector to the light source Vec v; v.diff(g.light_pos, hit); v.normalize(); //are we in a shadow? int shadow = getShadow(hit, v); //surface normal, dot product Flt dot = v.dotProduct(obj[k].normal); //dot += 1.0; //dot /= 2.0; if (dot < 0.0) dot = 0.0; //mult diffuse light by the dot Vec diff(g.diffuse); diff.scale(dot); Vec strength; strength.add(g.ambient); if (!shadow) strength.add(diff); Vec col; col.x = c[0] / 255.0; col.y = c[1] / 255.0; col.z = c[2] / 255.0; col.mult(strength); x11.set_color_3i(col.x*255, col.y*255, col.z*255); //checker if (obj[k].checker == 1) { Flt x = (hit.x+10000.0) / 100.0; Flt z = (hit.z+10000.0) / 100.0; int a = (int)x % 2; int b = (int)z % 2; if (a == b) x11.set_color_3i(0,155,255); else x11.set_color_3i(0,255,0); } //vector class Vec(Flt a, Flt b, Flt c) { x = a; y = b; z = c; } Vec(const Vec &v) { x = v.x; y = v.y; z = v.z; } void add(Vec v) { x = x + v.x; y = y + v.y; z = z + v.z; } void mult(Vec v) { x *= v.x; y *= v.y; z *= v.z; } void scale(Flt a) { x *= a; y *= a; z *= a; } //new scene case XK_4: //two discs nobjects = 0; obj[nobjects].type = OBJ_TYPE_DISC; obj[nobjects].pos.make(0, 200, -300.0); obj[nobjects].normal.make(0.0, -1.0, 0.0); obj[nobjects].normal.normalize(); obj[nobjects].radius = 400.0; obj[nobjects].color[0] = 255; obj[nobjects].color[1] = 150; obj[nobjects].color[2] = 20; obj[nobjects].checker = 1; ++nobjects; obj[nobjects].type = OBJ_TYPE_DISC; obj[nobjects].pos.make(100, 200, -300.0); obj[nobjects].normal.make(-1.0, 0.0, 0.0); obj[nobjects].normal.normalize(); obj[nobjects].radius = 200.0; obj[nobjects].color[0] = 250; obj[nobjects].color[1] = 250; obj[nobjects].color[2] = 20; ++nobjects; obj[nobjects].type = OBJ_TYPE_DISC; obj[nobjects].pos.make(-100, 200, -300.0); obj[nobjects].normal.make(-1.0, 0.0, 0.0); obj[nobjects].normal.normalize(); obj[nobjects].radius = 200.0; obj[nobjects].color[0] = 250; obj[nobjects].color[1] = 250; obj[nobjects].color[2] = 20; ++nobjects; g.light_pos.make(-400, 80, 120); g.ambient.make(.2, .2, .2); g.diffuse.make(.8,.8,.8); break; //shadow function int getShadow(Vec h, Vec v) { Ray ray; ray.o.make(h.x,h.y,h.z); ray.d.make(v.x,v.y,v.z); //nudge ray forward just a little... ray.o.x += ray.d.x * 0.00001; ray.o.y += ray.d.y * 0.00001; ray.o.z += ray.d.z * 0.00001; for (int k=0; k<nobjects; k++) { if (obj[k].type == OBJ_TYPE_DISC) { Flt t; if (rayIntersectPlane( obj[k].normal, obj[k].pos, ray.o, ray.d, t)) { Vec hit; hit.x = ray.o.x + ray.d.x * t; hit.y = ray.o.y + ray.d.y * t; hit.z = ray.o.z + ray.d.z * t; Vec v; v.diff(hit, obj[k].pos); Flt dist = v.len(); if (dist <= obj[k].radius) { //yes, hit an object return 1; } } } } return 0; }
Your instructor will find your work out on Odin!