3 /**************************************************************************
5 * Java Grande Forum Benchmark Suite - Version 2.0 *
9 * Java Grande Benchmarking Project *
13 * Edinburgh Parallel Computing Centre *
15 * email: epcc-javagrande@epcc.ed.ac.uk *
17 * Original version of this code by *
18 * Florian Doyon (Florian.Doyon@sophia.inria.fr) *
19 * and Wilfried Klauser (wklauser@acm.org) *
21 * This version copyright (c) The University of Edinburgh, 1999. *
22 * All rights reserved. *
24 **************************************************************************/
27 public class RayTracer {
31 * Lights for the rendering scene
36 * Objects (spheres) for the rendering scene
41 * The view for the rendering scene
48 // Ray tRay= new Ray();
54 // static final int alpha = 255 << 24;
55 static final int alpha ;
58 * Null vector (for speedup, instead of <code>new Vec(0,0,0)</code>
60 // static final Vec voidVec = new Vec();
61 // static final Vec voidVec;
70 * Current intersection instance (only one is needed!)
72 // Isect inter = new Isect();
76 * Height of the <code>Image</code> to be rendered
81 * Width of the <code>Image</code> to be rendered
85 // int datasizes[] = { 150, 500 };
98 // voidVec = new Vec();
100 // inter = new Isect();
102 datasizes = new int[2];
112 * Create and initialize the scene for the rendering picture.
114 * @return The scene just created
117 Scene createScene() {
121 Scene scene = new Scene();
129 for (int i = 0; i < nx; i++) {
130 for (int j = 0; j < ny; j++) {
131 for (int k = 0; k < nz; k++) {
132 double xx = 20.0 / (nx - 1) * i - 10.0;
133 double yy = 20.0 / (ny - 1) * j - 10.0;
134 double zz = 20.0 / (nz - 1) * k - 10.0;
136 p = new Sphere(new Vec(xx, yy, zz), 3);
137 // p.setColor(i/(double) (nx-1), j/(double)(ny-1),
138 // k/(double) (nz-1));
139 p.setColor(0, 0, (i + j) / (double) (nx + ny - 2));
141 p.surf.ks = 1.5 - 1.0;
142 p.surf.kt = 1.5 - 1.0;
148 /* Creates five lights for the scene */
149 scene.addLight(new Light(100, 100, -50, 1.0));
150 scene.addLight(new Light(-100, 100, -50, 1.0));
151 scene.addLight(new Light(100, -100, -50, 1.0));
152 scene.addLight(new Light(-100, -100, -50, 1.0));
153 scene.addLight(new Light(200, 200, 0, 1.0));
155 /* Creates a View (viewing point) for the rendering scene */
156 View v = new View(new Vec(x, 20, -30), new Vec(x, y, 0), new Vec(0, 1,
157 0), 1.0, 35.0 * 3.14159265 / 180.0, 1.0);
159 * v.from = new Vec(x, y, -30); v.at = new Vec(x, y, -15); v.up = new
160 * Vec(0, 1, 0); v.angle = 35.0 * 3.14159265 / 180.0; v.aspect = 1.0;
168 public void setScene(Scene scene) {
169 // Get the objects count
170 int nLights = scene.getLights();
171 int nObjects = scene.getObjects();
173 lights = new Light[nLights];
174 prim = new Primitive[nObjects];
177 for (int l = 0; l < nLights; l++) {
178 lights[l] = scene.getLight(l);
181 // Get the primitives
182 for (int o = 0; o < nObjects; o++) {
183 prim[o] = scene.getObject(o);
187 view = scene.getView();
190 public void render(Interval interval,boolean vtest) {
196 int row[] = new int[interval.width * (interval.yto - interval.yfrom)];
197 int pixCounter = 0; // iterator
199 // Rendering variables
200 // int x, y, red, green, blue;
201 // double xlen, ylen;
204 viewVec = Vec.sub(view.at, view.from);
206 Vec tmpVec = new Vec(viewVec);
207 tmpVec.scale(Vec.dot(view.up, viewVec));
208 Vec upVec = Vec.sub(view.up, tmpVec);
210 Vec leftVec = Vec.cross(view.up, viewVec);
212 double frustrumwidth = view.dist * Math.tan(view.angle);
213 upVec.scale(-frustrumwidth);
214 leftVec.scale(view.aspect * frustrumwidth);
216 // Ray r = new Ray(view.from, new Vec(0,0,0));
217 // Vec col = new Vec();
219 // Header for .ppm file
220 // System.out.println("P3");
221 // System.out.println(width + " " + height);
222 // System.out.println("255");
224 // All loops are reversed for 'speedup' (cf. thinking in java p331)
227 for (int y = interval.yfrom; y < interval.yto; y++) {
228 double ylen = (double) (2.0 * y) / (double) interval.width - 1.0;
229 // System.out.println("Doing line " + y);
230 // For each pixel of the line, launch parallel sese
232 int tempArray[]=new int[interval.width];
234 Ray tRay = new Ray();
235 Ray r = new Ray(view.from, new Vec(0,0,0));
237 for (int x = 0; x < interval.width; x++) {
240 double xlen = (double) (2.0 * x) / (double) interval.width - 1.0;
241 int pixCounter_t=y*(interval.width)+x;
243 r.D = Vec.comb(xlen, leftVec, ylen, upVec);
247 col = trace(0, 1.0, r,new Isect(),new Ray(),new Vec());
249 // computes the color of the ray
251 int red = (int) (col.x * 255.0);
254 int green = (int) (col.y * 255.0);
257 int blue = (int) (col.z * 255.0);
261 line_checksum += red;
262 line_checksum += green;
263 line_checksum += blue;
266 // RGB values for .ppm file
267 // System.out.println(red + " " + green + " " + blue);
269 // row[pixCounter_t] = alpha | (red << 16) | (green << 8) | (blue);
270 tempArray[x]= alpha | (red << 16) | (green << 8) | (blue);
272 } // end of sese line
276 int pixCounter_t=y*(interval.width);
277 System.arraycopy(tempArray, 0, row, pixCounter_t, interval.width);
279 for (int x = 0; x < interval.width; x++) {
280 int pixCounter_t=y*(interval.width)+x;
281 row[pixCounter_t] = tempArray[x];
284 checksum+=line_checksum;
285 if(y== (interval.yto-1)){
286 System.out.println("CHECKSUM="+checksum);
293 System.out.println("END OF WORK");
299 boolean intersect(Ray r, double maxt,Isect inter) {
305 for (i = 0; i < prim.length; i++) {
306 // uses global temporary Prim (tp) as temp.object for speedup
307 tp = prim[i].intersect(r);
308 if (tp != null && tp.t < inter.t) {
310 inter.prim = tp.prim;
311 inter.surf = tp.surf;
312 inter.enter = tp.enter;
316 return nhits > 0 ? true : false;
320 * Checks if there is a shadow
324 * @return Returns 1 if there is a shadow, 0 if there isn't
326 int Shadow(Ray r, double tmax,Isect inter) {
327 if (intersect(r, tmax,inter))
333 * Return the Vector's reflection direction
335 * @return The specular direction
337 Vec SpecularDirection(Vec I, Vec N) {
339 r = Vec.comb(1.0 / Math.abs(Vec.dot(I, N)), I, 2.0, N);
345 * Return the Vector's transmission direction
347 Vec TransDir(Surface m1, Surface m2, Vec I, Vec N) {
348 double n1, n2, eta, c1, cs2;
350 n1 = m1 == null ? 1.0 : m1.ior;
351 n2 = m2 == null ? 1.0 : m2.ior;
354 cs2 = 1.0 - eta * eta * (1.0 - c1 * c1);
357 r = Vec.comb(eta, I, eta * c1 - Math.sqrt(cs2), N);
363 * Returns the shaded color
365 * @return The color in Vec form (rgb)
367 Vec shade(int level, double weight, Vec P, Vec N, Vec I, Isect hit,Ray tRay,Vec L) {
368 double n1, n2, eta, c1, cs2;
372 double t, diff, spec;
380 if (surf.shine > 1e-6) {
381 R = SpecularDirection(I, N);
384 // Computes the effectof each light
385 for (l = 0; l < lights.length; l++) {
386 // L.sub2(lights[l].pos, P);
388 L.x=lights[l].pos.x-P.x;
389 L.y=lights[l].pos.y-P.y;
390 L.z=lights[l].pos.z-P.z;
392 if (Vec.dot(N, L) >= 0.0) {
398 // Checks if there is a shadow
399 if (Shadow(tRay, t,hit) > 0) {
400 diff = Vec.dot(N, L) * surf.kd * lights[l].brightness;
402 col.adds(diff, surf.color);
403 if (surf.shine > 1e-6) {
404 spec = Vec.dot(R, L);
406 spec = Math.pow(spec, surf.shine);
417 if (surf.ks * weight > 1e-3) {
418 tRay.D = SpecularDirection(I, N);
419 tcol = trace(level + 1, surf.ks * weight, tRay,hit,tRay,L);
420 col.adds(surf.ks, tcol);
422 if (surf.kt * weight > 1e-3) {
424 tRay.D = TransDir(null, surf, I, N);
426 tRay.D = TransDir(surf, null, I, N);
427 tcol = trace(level + 1, surf.kt * weight, tRay,hit,tRay,L);
428 col.adds(surf.kt, tcol);
441 Vec trace(int level, double weight, Ray r,Isect inter,Ray tRay,Vec L) {
446 // Checks the recursion level
450 hit = intersect(r, 1e6,inter);
452 P = r.point(inter.t);
453 N = inter.prim.normal(P);
454 if (Vec.dot(r.D, N) >= 0.0) {
457 return shade(level, weight, P, N, r.D, inter,tRay,L);
460 // no intersection --> col = 0,0,0
461 return new Vec(0,0,0);