3 /**************************************************************************
4 * * Java Grande Forum Benchmark Suite - Version 2.0 * * produced by * * Java
5 * Grande Benchmarking Project * * at * * Edinburgh Parallel Computing Centre *
6 * * email: epcc-javagrande@epcc.ed.ac.uk * * Original version of this code by *
7 * Florian Doyon (Florian.Doyon@sophia.inria.fr) * and Wilfried Klauser
8 * (wklauser@acm.org) * * This version copyright (c) The University of
9 * Edinburgh, 1999. * All rights reserved. * *
10 **************************************************************************/
12 public class RayTracer extends Thread {
18 * Lights for the rendering scene
23 * Objects (spheres) for the rendering scene
28 * The view for the rendering scene
35 // Ray tRay= new Ray();
41 // static final int alpha = 255 << 24;
42 static final int alpha;
45 * Null vector (for speedup, instead of <code>new Vec(0,0,0)</code>
47 // static final Vec voidVec = new Vec();
48 // static final Vec voidVec;
57 * Current intersection instance (only one is needed!)
59 // Isect inter = new Isect();
63 * Height of the <code>Image</code> to be rendered
68 * Width of the <code>Image</code> to be rendered
72 // int datasizes[] = { 150, 500 };
84 // voidVec = new Vec();
86 // inter = new Isect();
88 datasizes = new int[2];
98 * Create and initialize the scene for the rendering picture.
100 * @return The scene just created
103 public Scene createScene() {
107 Scene scene = new Scene();
115 for (int i = 0; i < nx; i++) {
116 for (int j = 0; j < ny; j++) {
117 for (int k = 0; k < nz; k++) {
118 float xx = (float) (20.0f / (nx - 1) * i - 10.0);
119 float yy = (float) (20.0f / (ny - 1) * j - 10.0);
120 float zz = (float) (20.0f / (nz - 1) * k - 10.0);
122 p = new Sphere(new Vec(xx, yy, zz), 3);
123 // p.setColor(i/(float) (nx-1), j/(float)(ny-1),
124 // k/(float) (nz-1));
125 p.setColor(0, 0, (i + j) / (float) (nx + ny - 2));
126 p.surf.shine = (float) 15.0;
127 p.surf.ks = (float) (1.5 - 1.0);
128 p.surf.kt = (float) (1.5 - 1.0);
134 /* Creates five lights for the scene */
135 scene.addLight(new Light((float) 100, (float) 100, (float) -50, (float) 1.0));
136 scene.addLight(new Light((float) -100, (float) 100, (float) -50, (float) 1.0));
137 scene.addLight(new Light((float) 100, (float) -100, (float) -50, (float) 1.0));
138 scene.addLight(new Light((float) -100, (float) -100, (float) -50, (float) 1.0));
139 scene.addLight(new Light((float) 200, (float) 200, (float) 0, (float) 1.0));
141 /* Creates a View (viewing point) for the rendering scene */
142 View v = new View(new Vec(x, 20, -30), new Vec(x, y, 0), new Vec(0, 1,
143 0),(float) 1.0, (float)(35.0 * 3.14159265 / 180.0), (float)1.0);
145 * v.from = new Vec(x, y, -30); v.at = new Vec(x, y, -15); v.up = new
146 * Vec(0, 1, 0); v.angle = 35.0 * 3.14159265 / 180.0; v.aspect = 1.0;
154 public void setScene(Scene scene) {
155 // Get the objects count
156 int nLights = scene.getLights();
157 int nObjects = scene.getObjects();
159 lights = new Light[nLights];
160 prim = new Primitive[nObjects];
163 for (int l = 0; l < nLights; l++) {
164 lights[l] = scene.getLight(l);
167 // Get the primitives
168 for (int o = 0; o < nObjects; o++) {
169 prim[o] = scene.getObject(o);
173 view = scene.getView();
176 public void render(Interval interval) {
179 int pixCounter = 0; // iterator
182 viewVec = Vec.sub(view.at, view.from);
184 Vec tmpVec = new Vec(viewVec);
185 tmpVec.scale(Vec.dot(view.up, viewVec));
186 Vec upVec = Vec.sub(view.up, tmpVec);
188 Vec leftVec = Vec.cross(view.up, viewVec);
190 float frustrumwidth = (float) (view.dist * Math.tan(view.angle));
191 upVec.scale(-frustrumwidth);
192 leftVec.scale((float) (view.aspect * frustrumwidth));
195 for (int y = interval.yfrom; y < interval.yto; y++) {
197 float ylen = (float) (2.0 * y) / (float) interval.width -(float) 1.0;
199 // For each pixel of the line
200 int row[]=new int[interval.width];
202 Ray tRay = new Ray();
203 Ray r = new Ray(view.from, new Vec(0,0,0));
205 for (int x = 0; x < interval.width; x++) {
208 float xlen = (float) (2.0 * x) / (float) interval.width - (float) 1.0;
210 r.D = Vec.comb(xlen, leftVec, ylen, upVec);
214 col = trace( 0, (float) 1.0, r,new Isect(),new Ray(),new Vec());
216 // computes the color of the ray
218 int red = (int) (col.x * 255.0);
221 int green = (int) (col.y * 255.0);
224 int blue = (int) (col.z * 255.0);
233 row[x]= alpha | (red << 16) | (green << 8) | (blue);
236 image[y-interval.yfrom]=row;
242 boolean intersect(Ray r, float maxt, Isect inter) {
247 inter.t = (float) 1e9;
248 for (i = 0; i < prim.length; i++) {
249 // uses global temporary Prim (tp) as temp.object for speedup
250 tp = prim[i].intersect(r);
251 if (tp != null && tp.t < inter.t) {
253 inter.prim = tp.prim;
254 inter.surf = tp.surf;
255 inter.enter = tp.enter;
259 return nhits > 0 ? true : false;
263 * Checks if there is a shadow
267 * @return Returns 1 if there is a shadow, 0 if there isn't
269 int Shadow(Ray r, float tmax, Isect inter) {
270 if (intersect(r, tmax, inter))
276 * Return the Vector's reflection direction
278 * @return The specular direction
280 Vec SpecularDirection(Vec I, Vec N) {
282 r = Vec.comb((float) (1.0 / Math.abs(Vec.dot(I, N))), I, (float) 2.0, N);
288 * Return the Vector's transmission direction
290 Vec TransDir(Surface m1, Surface m2, Vec I, Vec N) {
291 float n1, n2, eta, c1, cs2;
293 n1 = m1 == null ? (float) 1.0 : m1.ior;
294 n2 = m2 == null ? (float) 1.0 : m2.ior;
297 cs2 =(float) ( 1.0 - eta * eta * (1.0 - c1 * c1));
300 r = Vec.comb((float) eta, I,(float) ( eta * c1 - Math.sqrt(cs2)), N);
306 * Returns the shaded color
308 * @return The color in Vec form (rgb)
310 Vec shade(int level, float weight, Vec P, Vec N, Vec I, Isect hit,
312 float n1, n2, eta, c1, cs2;
324 if (surf.shine > 1e-6) {
325 R = SpecularDirection(I, N);
328 // Computes the effectof each light
329 for (l = 0; l < lights.length; l++) {
330 // L.sub2(lights[l].pos, P);
332 L.x = lights[l].pos.x - P.x;
333 L.y = lights[l].pos.y - P.y;
334 L.z = lights[l].pos.z - P.z;
336 if (Vec.dot(N, L) >= 0.0) {
342 // Checks if there is a shadow
343 if (Shadow(tRay, t, hit) > 0) {
344 diff = Vec.dot(N, L) * surf.kd * lights[l].brightness;
346 col.adds(diff, surf.color);
347 if (surf.shine > 1e-6) {
348 spec = Vec.dot(R, L);
350 spec = (float) (Math.pow(spec, surf.shine));
361 if (surf.ks * weight > 1e-3) {
362 tRay.D = SpecularDirection(I, N);
363 tcol = trace(level + 1, surf.ks * weight, tRay, hit, tRay, L);
364 col.adds(surf.ks, tcol);
366 if (surf.kt * weight > 1e-3) {
368 tRay.D = TransDir(null, surf, I, N);
370 tRay.D = TransDir(surf, null, I, N);
371 tcol = trace(level + 1, surf.kt * weight, tRay, hit, tRay, L);
372 col.adds(surf.kt, tcol);
385 Vec trace(int level, float weight, Ray r, Isect inter, Ray tRay, Vec L) {
390 // Checks the recursion level
394 hit = intersect(r, (float) 1e6, inter);
396 P = r.point(inter.t);
397 N = inter.prim.normal(P);
398 if (Vec.dot(r.D, N) >= 0.0) {
401 return shade(level, weight, P, N, r.D, inter, tRay, L);
404 // no intersection --> col = 0,0,0
405 return new Vec(0, 0, 0);