CMPS-3480 Computer Graphics
Lab-8

Overview:

Start:

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.



Ray tracing...
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.





Wednesday, Friday code...

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;
}


What to turn in...
Your instructor will find your work out on Odin!