//
import java.util.*;
import java.awt.*;
import Geometry.*;
public class SimpleRayTracer extends PixApplet
{
Vector shapes = new Vector();
public void init()
{
super.init();
shapes.addElement(new Sphere( .07,.06,-2,.07));
shapes.addElement(new Sphere(-.07,.06,-2,.07));
shapes.addElement(new Sphere(0,0,-2.02,.1));
}
public double dot(double[] v, double[] u)
{
return v[0]*u[0]+v[1]*u[1]+v[2]*u[2];
}
public void normalize(double[] v)
{
double norm = Math.sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
v[0] /= norm;
v[1] /= norm;
v[2] /= norm;
}
double viewpoint[] = {0,0,0}; // VIEW POINT
private double light[] = {1,1,1};
private double shiny = 30;
private double ambCoeff=0.4;
private double difCoeff=0.6;
private double spcCoeff=0.7;
private double light2[] = {-1,-1,1};
private double shiny2 = 30;
private double ambCoeff2=0.4;
private double difCoeff2=0.6;
private double spcCoeff2=0.7;
//private double ambCoeff=0.3;
//private double difCoeff=0.4;
//Computes the Phong illumination equation for a single directional light
public double[] illuminate(double p[], double light[], double[] viewpoint,
double[] normal, double[] material,
double dif, double spc, double shiny)
{
double rgb[] = new double[3];
double reflect[] = new double[3];
double view[] = new double[3];
// DO SHADING AT POINT - MODULATE WITH TEXTURE
double dotNL = dot(normal,light);
for(int i=0; i<3; i++)
{
reflect[i] = 2*normal[i]*dotNL - light[i];
view[i] = p[i] - viewpoint[i];
}
normalize(reflect);
normalize(view);
double dotRV = dot(reflect,view);
double dotRVtoN = dotRV>0 ? 0 : Math.pow(dotRV, shiny);
//Math.pow(dot(reflect,view), shiny);
for(int i=0; i<3; i++)
{
//K_amb*M_amb*L_amb + K_dif*M_dif*L_dif*(L_dir dot Norml) + K_spc*M_spc*L_spc*(
rgb[i] = clamp( dif*material[i]*dotNL +
spc*dotRVtoN, 0, 1);
}
return rgb;
}
public void setPix(int frame)
{
System.out.println("setPix Versio 2");
double focal_length = 3.5; // FOCAL LENGTH OF "LENS"
//double v[] = {0,0,0}; // VIEW POINT
double w[] = {0,0,-focal_length}; // RAY DIRECTION
//double w[] = {0,0,-focal_length}; // RAY DIRECTION
double t[] = new double[2]; // PLACE TO STORE ROOTS
double p[] = {0,0,0}; // SURFACE POINT
double n[] = {0,0,0}; // SURFACE NORMAL
double center[] = {0,0,-2.02}; // CENTER OF VIEW
double w2[] = new double[3];
for(int i=0; i<3; i++)
w2[i] = center[i] - viewpoint[i];
normalize(w2);
for(int j=0; j<3; j++)
w2[j] *= focal_length;
w = w2;
double rgb1[] = new double[3];
double rgb2[] = new double[3];
double rgb[] = new double[3];
normalize(light);
// LOOP THROUGH PIXELS OF IMAGE
for (int row = 0 ; row < H ; row++)
for (int col = 0 ; col < W ; col++)
{
// CONSTRUCT RAY DIRECTION VECTOR
w[0] = col / (double)W - 0.5;
w[1] = -row / (double)W + 0.5 * H / W;
// LOOP THROUGH ALL SHAPES
Shape nearest_s = null;
double nearest_t = 1000000;
for (int i = 0 ; i < shapes.size() ; i++)
{
Shape s = (Shape)shapes.elementAt(i);
if (s.traceRay(viewpoint,w,t)>0 && t[0]>0 && t[0]0 ? 0 : Math.pow(dotRV, shiny);
//Math.pow(dot(reflect,view), shiny);
for(int i=0; i<3; i++)
{
//K_amb*M_amb*L_amb + K_dif*M_dif*L_dif*(L_dir dot Norml) + K_spc*M_spc*L_spc*(
rgb[i] = clamp(ambCoeff*color[i] +
difCoeff*color[i]*dotNL +
spcCoeff*dotRVtoN, 0, 1);
}
*/
rgb1 = illuminate(p, light, viewpoint, n, color, difCoeff, spcCoeff, shiny);
rgb2 = illuminate(p, light2, viewpoint, n, color, difCoeff2, spcCoeff2, shiny2);
for(int i=0; i<3; i++)
rgb[i] = clamp(ambCoeff*color[i] + rgb1[i] + rgb2[i], 0, 1);
pix[xy2i(col, row)] = pack(d2i(rgb[0]),d2i(rgb[1]),d2i(rgb[2]));
}
else
{
if(!showShadow)
{
pix[xy2i(col, row)] = pack(200, 200, 255);
}
else
{
double zTarget = -3;
//Find the parameter for which this ray would hit the target
double uTarget = (zTarget - viewpoint[2]) / w[2];
//Find the point on the back plane
double backPoint[] = { viewpoint[0] + uTarget*w[0], viewpoint[1] + uTarget*w[1], zTarget};
//Find the ray to the light
double rayToLight[] = {light[0]-backPoint[0], light[1]-backPoint[1], light[2]-backPoint[2]};
//System.out.println(backPoint[0] + " " + backPoint[1] + " " + backPoint[2]);
// LOOP THROUGH ALL SHAPES
nearest_s = null;
nearest_t = 1000000;
for (int i = 0 ; i < shapes.size() ; i++)
{
Shape s = (Shape)shapes.elementAt(i);
if (s.traceRay(backPoint,rayToLight,t)>0 && t[0]>0 && t[0] max )
return max;
else
return x;
}
private final int d2i(double d)
{
return (int)(255*clamp(d,0,1));
}
}