2 /**************************************************************************
3 * * Java Grande Forum Benchmark Suite - Version 2.0 * * produced by * * Java
4 * Grande Benchmarking Project * * at * * Edinburgh Parallel Computing Centre *
5 * * email: epcc-javagrande@epcc.ed.ac.uk * * Original version of this code by *
6 * Florian Doyon (Florian.Doyon@sophia.inria.fr) * and Wilfried Klauser
7 * (wklauser@acm.org) * * This version copyright (c) The University of
8 * Edinburgh, 1999. * All rights reserved. * *
9 **************************************************************************/
11 public class RayTracer {
17 * Lights for the rendering scene
22 * Objects (spheres) for the rendering scene
27 * The view for the rendering scene
34 // Ray tRay= new Ray();
40 // static final int alpha = 255 << 24;
41 static final int alpha;
44 * Null vector (for speedup, instead of <code>new Vec(0,0,0)</code>
46 // static final Vec voidVec = new Vec();
47 // static final Vec voidVec;
56 * Current intersection instance (only one is needed!)
58 // Isect inter = new Isect();
62 * Height of the <code>Image</code> to be rendered
67 * Width of the <code>Image</code> to be rendered
71 // int datasizes[] = { 150, 500 };
83 // voidVec = new Vec();
85 // inter = new Isect();
87 datasizes = new int[2];
97 * Create and initialize the scene for the rendering picture.
99 * @return The scene just created
102 public Scene createScene() {
106 Scene scene = new Scene();
114 for (int i = 0; i < nx; i++) {
115 for (int j = 0; j < ny; j++) {
116 for (int k = 0; k < nz; k++) {
117 float xx = (float) (20.0f / (nx - 1) * i - 10.0);
118 float yy = (float) (20.0f / (ny - 1) * j - 10.0);
119 float zz = (float) (20.0f / (nz - 1) * k - 10.0);
121 p = new Sphere(new Vec(xx, yy, zz), 3);
122 // p.setColor(i/(float) (nx-1), j/(float)(ny-1),
123 // k/(float) (nz-1));
124 p.setColor(0, 0, (i + j) / (float) (nx + ny - 2));
125 p.surf.shine = (float) 15.0;
126 p.surf.ks = (float) (1.5 - 1.0);
127 p.surf.kt = (float) (1.5 - 1.0);
133 /* Creates five lights for the scene */
134 scene.addLight(new Light((float) 100, (float) 100, (float) -50, (float) 1.0));
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) 200, (float) 200, (float) 0, (float) 1.0));
140 /* Creates a View (viewing point) for the rendering scene */
141 View v = new View(new Vec(x, 20, -30), new Vec(x, y, 0), new Vec(0, 1,
142 0),(float) 1.0, (float)(35.0 * 3.14159265 / 180.0), (float)1.0);
144 * v.from = new Vec(x, y, -30); v.at = new Vec(x, y, -15); v.up = new
145 * Vec(0, 1, 0); v.angle = 35.0 * 3.14159265 / 180.0; v.aspect = 1.0;
153 public void setScene(Scene scene) {
154 // Get the objects count
155 int nLights = scene.getLights();
156 int nObjects = scene.getObjects();
158 lights = new Light[nLights];
159 prim = new Primitive[nObjects];
162 for (int l = 0; l < nLights; l++) {
163 lights[l] = scene.getLight(l);
166 // Get the primitives
167 for (int o = 0; o < nObjects; o++) {
168 prim[o] = scene.getObject(o);
172 view = scene.getView();
175 public void render(Interval interval) {
178 int pixCounter = 0; // iterator
181 viewVec = Vec.sub(view.at, view.from);
183 Vec tmpVec = new Vec(viewVec);
184 tmpVec.scale(Vec.dot(view.up, viewVec));
185 Vec upVec = Vec.sub(view.up, tmpVec);
187 Vec leftVec = Vec.cross(view.up, viewVec);
189 float frustrumwidth = (float) (view.dist * Math.tan(view.angle));
190 upVec.scale(-frustrumwidth);
191 leftVec.scale((float) (view.aspect * frustrumwidth));
194 for (int y = interval.yfrom; y < interval.yto; y++) {
196 float ylen = (float) (2.0 * y) / (float) interval.width -(float) 1.0;
198 // For each pixel of the line
199 int row[]=new int[interval.width];
201 Ray tRay = new Ray();
202 Ray r = new Ray(view.from, new Vec(0,0,0));
204 for (int x = 0; x < interval.width; x++) {
207 float xlen = (float) (2.0 * x) / (float) interval.width - (float) 1.0;
209 r.D = Vec.comb(xlen, leftVec, ylen, upVec);
213 col = trace( 0, (float) 1.0, r,new Isect(),new Ray(),new Vec());
215 // computes the color of the ray
217 int red = (int) (col.x * 255.0);
220 int green = (int) (col.y * 255.0);
223 int blue = (int) (col.z * 255.0);
232 row[x]= alpha | (red << 16) | (green << 8) | (blue);
241 boolean intersect(Ray r, float maxt, Isect inter) {
246 inter.t = (float) 1e9;
247 for (i = 0; i < prim.length; i++) {
248 // uses global temporary Prim (tp) as temp.object for speedup
249 tp = prim[i].intersect(r);
250 if (tp != null && tp.t < inter.t) {
252 inter.prim = tp.prim;
253 inter.surf = tp.surf;
254 inter.enter = tp.enter;
258 return nhits > 0 ? true : false;
262 * Checks if there is a shadow
266 * @return Returns 1 if there is a shadow, 0 if there isn't
268 int Shadow(Ray r, float tmax, Isect inter) {
269 if (intersect(r, tmax, inter))
275 * Return the Vector's reflection direction
277 * @return The specular direction
279 Vec SpecularDirection(Vec I, Vec N) {
281 r = Vec.comb((float) (1.0 / Math.abs(Vec.dot(I, N))), I, (float) 2.0, N);
287 * Return the Vector's transmission direction
289 Vec TransDir(Surface m1, Surface m2, Vec I, Vec N) {
290 float n1, n2, eta, c1, cs2;
292 n1 = m1 == null ? (float) 1.0 : m1.ior;
293 n2 = m2 == null ? (float) 1.0 : m2.ior;
296 cs2 =(float) ( 1.0 - eta * eta * (1.0 - c1 * c1));
299 r = Vec.comb((float) eta, I,(float) ( eta * c1 - Math.sqrt(cs2)), N);
305 * Returns the shaded color
307 * @return The color in Vec form (rgb)
309 Vec shade(int level, float weight, Vec P, Vec N, Vec I, Isect hit,
311 float n1, n2, eta, c1, cs2;
323 if (surf.shine > 1e-6) {
324 R = SpecularDirection(I, N);
327 // Computes the effectof each light
328 for (l = 0; l < lights.length; l++) {
329 // L.sub2(lights[l].pos, P);
331 L.x = lights[l].pos.x - P.x;
332 L.y = lights[l].pos.y - P.y;
333 L.z = lights[l].pos.z - P.z;
335 if (Vec.dot(N, L) >= 0.0) {
341 // Checks if there is a shadow
342 if (Shadow(tRay, t, hit) > 0) {
343 diff = Vec.dot(N, L) * surf.kd * lights[l].brightness;
345 col.adds(diff, surf.color);
346 if (surf.shine > 1e-6) {
347 spec = Vec.dot(R, L);
349 spec = (float) (Math.pow(spec, surf.shine));
360 if (surf.ks * weight > 1e-3) {
361 tRay.D = SpecularDirection(I, N);
362 tcol = trace(level + 1, surf.ks * weight, tRay, hit, tRay, L);
363 col.adds(surf.ks, tcol);
365 if (surf.kt * weight > 1e-3) {
367 tRay.D = TransDir(null, surf, I, N);
369 tRay.D = TransDir(surf, null, I, N);
370 tcol = trace(level + 1, surf.kt * weight, tRay, hit, tRay, L);
371 col.adds(surf.kt, tcol);
384 Vec trace(int level, float weight, Ray r, Isect inter, Ray tRay, Vec L) {
389 // Checks the recursion level
393 hit = intersect(r, (float) 1e6, inter);
395 P = r.point(inter.t);
396 N = inter.prim.normal(P);
397 if (Vec.dot(r.D, N) >= 0.0) {
400 return shade(level, weight, P, N, r.D, inter, tRay, L);
403 // no intersection --> col = 0,0,0
404 return new Vec(0, 0, 0);