1 // The ray tracer code in this file is written by Adam Burmister. It
2 // is available in its original form from:
4 // http://labs.flog.nz.co/raytracer/
6 // It has been modified slightly by Google to work as a standalone
7 // benchmark, but the all the computational code remains
8 // untouched. This file also contains a copy of parts of the Prototype
9 // JavaScript framework which is used by the ray tracer.
11 var RayTrace
= new BenchmarkSuite('RayTrace', 739989, [
12 new Benchmark('RayTrace', renderScene
)
16 // Variable used to hold a number that can be used to verify that
17 // the scene was ray traced correctly.
21 // ------------------------------------------------------------------------
22 // ------------------------------------------------------------------------
24 // The following is a copy of parts of the Prototype JavaScript library:
26 // Prototype JavaScript framework, version 1.5.0
27 // (c) 2005-2007 Sam Stephenson
29 // Prototype is freely distributable under the terms of an MIT-style license.
30 // For details, see the Prototype web site: http://prototype.conio.net/
36 this.initialize
.apply(this, arguments
);
42 Object
.extend = function(destination
, source
) {
43 for (var property
in source
) {
44 destination
[property
] = source
[property
];
50 // ------------------------------------------------------------------------
51 // ------------------------------------------------------------------------
53 // The rest of this file is the actual ray tracer written by Adam
54 // Burmister. It's a concatenation of the following files:
61 // flog/material/basematerial.js
62 // flog/material/solid.js
63 // flog/material/chessboard.js
64 // flog/shape/baseshape.js
65 // flog/shape/sphere.js
66 // flog/shape/plane.js
67 // flog/intersectioninfo.js
73 /* Fake a Flog.* namespace */
74 if(typeof(Flog
) == 'undefined') var Flog
= {};
75 if(typeof(Flog
.RayTracer
) == 'undefined') Flog
.RayTracer
= {};
77 Flog
.RayTracer
.Color
= Class
.create();
79 Flog
.RayTracer
.Color
.prototype = {
84 initialize : function(r
, g
, b
) {
94 add : function(c1
, c2
){
95 var result
= new Flog
.RayTracer
.Color(0,0,0);
97 result
.red
= c1
.red
+ c2
.red
;
98 result
.green
= c1
.green
+ c2
.green
;
99 result
.blue
= c1
.blue
+ c2
.blue
;
104 addScalar: function(c1
, s
){
105 var result
= new Flog
.RayTracer
.Color(0,0,0);
107 result
.red
= c1
.red
+ s
;
108 result
.green
= c1
.green
+ s
;
109 result
.blue
= c1
.blue
+ s
;
116 subtract: function(c1
, c2
){
117 var result
= new Flog
.RayTracer
.Color(0,0,0);
119 result
.red
= c1
.red
- c2
.red
;
120 result
.green
= c1
.green
- c2
.green
;
121 result
.blue
= c1
.blue
- c2
.blue
;
126 multiply : function(c1
, c2
) {
127 var result
= new Flog
.RayTracer
.Color(0,0,0);
129 result
.red
= c1
.red
* c2
.red
;
130 result
.green
= c1
.green
* c2
.green
;
131 result
.blue
= c1
.blue
* c2
.blue
;
136 multiplyScalar : function(c1
, f
) {
137 var result
= new Flog
.RayTracer
.Color(0,0,0);
139 result
.red
= c1
.red
* f
;
140 result
.green
= c1
.green
* f
;
141 result
.blue
= c1
.blue
* f
;
146 divideFactor : function(c1
, f
) {
147 var result
= new Flog
.RayTracer
.Color(0,0,0);
149 result
.red
= c1
.red
/ f
;
150 result
.green
= c1
.green
/ f
;
151 result
.blue
= c1
.blue
/ f
;
157 this.red
= (this.red
> 0.0) ? ( (this.red
> 1.0) ? 1.0 : this.red
) : 0.0;
158 this.green
= (this.green
> 0.0) ? ( (this.green
> 1.0) ? 1.0 : this.green
) : 0.0;
159 this.blue
= (this.blue
> 0.0) ? ( (this.blue
> 1.0) ? 1.0 : this.blue
) : 0.0;
162 distance : function(color
) {
163 var d
= Math
.abs(this.red
- color
.red
) + Math
.abs(this.green
- color
.green
) + Math
.abs(this.blue
- color
.blue
);
167 blend: function(c1
, c2
, w
){
168 var result
= new Flog
.RayTracer
.Color(0,0,0);
169 result
= Flog
.RayTracer
.Color
.prototype.add(
170 Flog
.RayTracer
.Color
.prototype.multiplyScalar(c1
, 1 - w
),
171 Flog
.RayTracer
.Color
.prototype.multiplyScalar(c2
, w
)
176 brightness : function() {
177 var r
= Math
.floor(this.red
*255);
178 var g
= Math
.floor(this.green
*255);
179 var b
= Math
.floor(this.blue
*255);
180 return (r
* 77 + g
* 150 + b
* 29) >> 8;
183 toString : function () {
184 var r
= Math
.floor(this.red
*255);
185 var g
= Math
.floor(this.green
*255);
186 var b
= Math
.floor(this.blue
*255);
188 return "rgb("+ r
+","+ g
+","+ b
+")";
191 /* Fake a Flog.* namespace */
192 if(typeof(Flog
) == 'undefined') var Flog
= {};
193 if(typeof(Flog
.RayTracer
) == 'undefined') Flog
.RayTracer
= {};
195 Flog
.RayTracer
.Light
= Class
.create();
197 Flog
.RayTracer
.Light
.prototype = {
202 initialize : function(pos
, color
, intensity
) {
205 this.intensity
= (intensity
? intensity
: 10.0);
208 toString : function () {
209 return 'Light [' + this.position
.x
+ ',' + this.position
.y
+ ',' + this.position
.z
+ ']';
212 /* Fake a Flog.* namespace */
213 if(typeof(Flog
) == 'undefined') var Flog
= {};
214 if(typeof(Flog
.RayTracer
) == 'undefined') Flog
.RayTracer
= {};
216 Flog
.RayTracer
.Vector
= Class
.create();
218 Flog
.RayTracer
.Vector
.prototype = {
223 initialize : function(x
, y
, z
) {
224 this.x
= (x
? x
: 0);
225 this.y
= (y
? y
: 0);
226 this.z
= (z
? z
: 0);
229 copy: function(vector
){
235 normalize : function() {
236 var m
= this.magnitude();
237 return new Flog
.RayTracer
.Vector(this.x
/ m
, this.y
/ m
, this.z
/ m
);
240 magnitude : function() {
241 return Math
.sqrt((this.x
* this.x
) + (this.y
* this.y
) + (this.z
* this.z
));
244 cross : function(w
) {
245 return new Flog
.RayTracer
.Vector(
246 -this.z
* w
.y
+ this.y
* w
.z
,
247 this.z
* w
.x
- this.x
* w
.z
,
248 -this.y
* w
.x
+ this.x
* w
.y
);
252 return this.x
* w
.x
+ this.y
* w
.y
+ this.z
* w
.z
;
255 add : function(v
, w
) {
256 return new Flog
.RayTracer
.Vector(w
.x
+ v
.x
, w
.y
+ v
.y
, w
.z
+ v
.z
);
259 subtract : function(v
, w
) {
260 if(!w
|| !v
) throw 'Vectors must be defined [' + v
+ ',' + w
+ ']';
261 return new Flog
.RayTracer
.Vector(v
.x
- w
.x
, v
.y
- w
.y
, v
.z
- w
.z
);
264 multiplyVector : function(v
, w
) {
265 return new Flog
.RayTracer
.Vector(v
.x
* w
.x
, v
.y
* w
.y
, v
.z
* w
.z
);
268 multiplyScalar : function(v
, w
) {
269 return new Flog
.RayTracer
.Vector(v
.x
* w
, v
.y
* w
, v
.z
* w
);
272 toString : function () {
273 return 'Vector [' + this.x
+ ',' + this.y
+ ',' + this.z
+ ']';
276 /* Fake a Flog.* namespace */
277 if(typeof(Flog
) == 'undefined') var Flog
= {};
278 if(typeof(Flog
.RayTracer
) == 'undefined') Flog
.RayTracer
= {};
280 Flog
.RayTracer
.Ray
= Class
.create();
282 Flog
.RayTracer
.Ray
.prototype = {
285 initialize : function(pos
, dir
) {
287 this.direction
= dir
;
290 toString : function () {
291 return 'Ray [' + this.position
+ ',' + this.direction
+ ']';
294 /* Fake a Flog.* namespace */
295 if(typeof(Flog
) == 'undefined') var Flog
= {};
296 if(typeof(Flog
.RayTracer
) == 'undefined') Flog
.RayTracer
= {};
298 Flog
.RayTracer
.Scene
= Class
.create();
300 Flog
.RayTracer
.Scene
.prototype = {
306 initialize : function() {
307 this.camera
= new Flog
.RayTracer
.Camera(
308 new Flog
.RayTracer
.Vector(0,0,-5),
309 new Flog
.RayTracer
.Vector(0,0,1),
310 new Flog
.RayTracer
.Vector(0,1,0)
312 this.shapes
= new Array();
313 this.lights
= new Array();
314 this.background
= new Flog
.RayTracer
.Background(new Flog
.RayTracer
.Color(0,0,0.5), 0.2);
317 /* Fake a Flog.* namespace */
318 if(typeof(Flog
) == 'undefined') var Flog
= {};
319 if(typeof(Flog
.RayTracer
) == 'undefined') Flog
.RayTracer
= {};
320 if(typeof(Flog
.RayTracer
.Material
) == 'undefined') Flog
.RayTracer
.Material
= {};
322 Flog
.RayTracer
.Material
.BaseMaterial
= Class
.create();
324 Flog
.RayTracer
.Material
.BaseMaterial
.prototype = {
326 gloss
: 2.0, // [0...infinity] 0 = matt
327 transparency
: 0.0, // 0=opaque
328 reflection
: 0.0, // [0...infinity] 0 = no reflection
332 initialize : function() {
336 getColor: function(u
, v
){
347 toString : function () {
348 return 'Material [gloss=' + this.gloss
+ ', transparency=' + this.transparency
+ ', hasTexture=' + this.hasTexture
+']';
351 /* Fake a Flog.* namespace */
352 if(typeof(Flog
) == 'undefined') var Flog
= {};
353 if(typeof(Flog
.RayTracer
) == 'undefined') Flog
.RayTracer
= {};
355 Flog
.RayTracer
.Material
.Solid
= Class
.create();
357 Flog
.RayTracer
.Material
.Solid
.prototype = Object
.extend(
358 new Flog
.RayTracer
.Material
.BaseMaterial(), {
359 initialize : function(color
, reflection
, refraction
, transparency
, gloss
) {
361 this.reflection
= reflection
;
362 this.transparency
= transparency
;
364 this.hasTexture
= false;
367 getColor: function(u
, v
){
371 toString : function () {
372 return 'SolidMaterial [gloss=' + this.gloss
+ ', transparency=' + this.transparency
+ ', hasTexture=' + this.hasTexture
+']';
376 /* Fake a Flog.* namespace */
377 if(typeof(Flog
) == 'undefined') var Flog
= {};
378 if(typeof(Flog
.RayTracer
) == 'undefined') Flog
.RayTracer
= {};
380 Flog
.RayTracer
.Material
.Chessboard
= Class
.create();
382 Flog
.RayTracer
.Material
.Chessboard
.prototype = Object
.extend(
383 new Flog
.RayTracer
.Material
.BaseMaterial(), {
388 initialize : function(colorEven
, colorOdd
, reflection
, transparency
, gloss
, density
) {
389 this.colorEven
= colorEven
;
390 this.colorOdd
= colorOdd
;
391 this.reflection
= reflection
;
392 this.transparency
= transparency
;
394 this.density
= density
;
395 this.hasTexture
= true;
398 getColor: function(u
, v
){
399 var t
= this.wrapUp(u
* this.density
) * this.wrapUp(v
* this.density
);
402 return this.colorEven
;
404 return this.colorOdd
;
407 toString : function () {
408 return 'ChessMaterial [gloss=' + this.gloss
+ ', transparency=' + this.transparency
+ ', hasTexture=' + this.hasTexture
+']';
412 /* Fake a Flog.* namespace */
413 if(typeof(Flog
) == 'undefined') var Flog
= {};
414 if(typeof(Flog
.RayTracer
) == 'undefined') Flog
.RayTracer
= {};
415 if(typeof(Flog
.RayTracer
.Shape
) == 'undefined') Flog
.RayTracer
.Shape
= {};
417 Flog
.RayTracer
.Shape
.Sphere
= Class
.create();
419 Flog
.RayTracer
.Shape
.Sphere
.prototype = {
420 initialize : function(pos
, radius
, material
) {
421 this.radius
= radius
;
423 this.material
= material
;
426 intersect: function(ray
){
427 var info
= new Flog
.RayTracer
.IntersectionInfo();
430 var dst
= Flog
.RayTracer
.Vector
.prototype.subtract(ray
.position
, this.position
);
432 var B
= dst
.dot(ray
.direction
);
433 var C
= dst
.dot(dst
) - (this.radius
* this.radius
);
436 if(D
> 0){ // intersection!
438 info
.distance
= (-B
) - Math
.sqrt(D
);
439 info
.position
= Flog
.RayTracer
.Vector
.prototype.add(
441 Flog
.RayTracer
.Vector
.prototype.multiplyScalar(
446 info
.normal
= Flog
.RayTracer
.Vector
.prototype.subtract(
451 info
.color
= this.material
.getColor(0,0);
458 toString : function () {
459 return 'Sphere [position=' + this.position
+ ', radius=' + this.radius
+ ']';
462 /* Fake a Flog.* namespace */
463 if(typeof(Flog
) == 'undefined') var Flog
= {};
464 if(typeof(Flog
.RayTracer
) == 'undefined') Flog
.RayTracer
= {};
465 if(typeof(Flog
.RayTracer
.Shape
) == 'undefined') Flog
.RayTracer
.Shape
= {};
467 Flog
.RayTracer
.Shape
.Plane
= Class
.create();
469 Flog
.RayTracer
.Shape
.Plane
.prototype = {
472 initialize : function(pos
, d
, material
) {
475 this.material
= material
;
478 intersect: function(ray
){
479 var info
= new Flog
.RayTracer
.IntersectionInfo();
481 var Vd
= this.position
.dot(ray
.direction
);
482 if(Vd
== 0) return info
; // no intersection
484 var t
= -(this.position
.dot(ray
.position
) + this.d
) / Vd
;
485 if(t
<= 0) return info
;
489 info
.position
= Flog
.RayTracer
.Vector
.prototype.add(
491 Flog
.RayTracer
.Vector
.prototype.multiplyScalar(
496 info
.normal
= this.position
;
499 if(this.material
.hasTexture
){
500 var vU
= new Flog
.RayTracer
.Vector(this.position
.y
, this.position
.z
, -this.position
.x
);
501 var vV
= vU
.cross(this.position
);
502 var u
= info
.position
.dot(vU
);
503 var v
= info
.position
.dot(vV
);
504 info
.color
= this.material
.getColor(u
,v
);
506 info
.color
= this.material
.getColor(0,0);
512 toString : function () {
513 return 'Plane [' + this.position
+ ', d=' + this.d
+ ']';
516 /* Fake a Flog.* namespace */
517 if(typeof(Flog
) == 'undefined') var Flog
= {};
518 if(typeof(Flog
.RayTracer
) == 'undefined') Flog
.RayTracer
= {};
520 Flog
.RayTracer
.IntersectionInfo
= Class
.create();
522 Flog
.RayTracer
.IntersectionInfo
.prototype = {
531 initialize : function() {
532 this.color
= new Flog
.RayTracer
.Color(0,0,0);
535 toString : function () {
536 return 'Intersection [' + this.position
+ ']';
539 /* Fake a Flog.* namespace */
540 if(typeof(Flog
) == 'undefined') var Flog
= {};
541 if(typeof(Flog
.RayTracer
) == 'undefined') Flog
.RayTracer
= {};
543 Flog
.RayTracer
.Camera
= Class
.create();
545 Flog
.RayTracer
.Camera
.prototype = {
552 initialize : function(pos
, lookAt
, up
) {
554 this.lookAt
= lookAt
;
556 this.equator
= lookAt
.normalize().cross(this.up
);
557 this.screen
= Flog
.RayTracer
.Vector
.prototype.add(this.position
, this.lookAt
);
560 getRay: function(vx
, vy
){
561 var pos
= Flog
.RayTracer
.Vector
.prototype.subtract(
563 Flog
.RayTracer
.Vector
.prototype.subtract(
564 Flog
.RayTracer
.Vector
.prototype.multiplyScalar(this.equator
, vx
),
565 Flog
.RayTracer
.Vector
.prototype.multiplyScalar(this.up
, vy
)
569 var dir
= Flog
.RayTracer
.Vector
.prototype.subtract(
574 var ray
= new Flog
.RayTracer
.Ray(pos
, dir
.normalize());
579 toString : function () {
583 /* Fake a Flog.* namespace */
584 if(typeof(Flog
) == 'undefined') var Flog
= {};
585 if(typeof(Flog
.RayTracer
) == 'undefined') Flog
.RayTracer
= {};
587 Flog
.RayTracer
.Background
= Class
.create();
589 Flog
.RayTracer
.Background
.prototype = {
593 initialize : function(color
, ambience
) {
595 this.ambience
= ambience
;
598 /* Fake a Flog.* namespace */
599 if(typeof(Flog
) == 'undefined') var Flog
= {};
600 if(typeof(Flog
.RayTracer
) == 'undefined') Flog
.RayTracer
= {};
602 Flog
.RayTracer
.Engine
= Class
.create();
604 Flog
.RayTracer
.Engine
.prototype = {
605 canvas
: null, /* 2d context we can render to */
607 initialize: function(options
){
608 this.options
= Object
.extend({
613 renderDiffuse
: false,
614 renderShadows
: false,
615 renderHighlights
: false,
616 renderReflections
: false,
620 this.options
.canvasHeight
/= this.options
.pixelHeight
;
621 this.options
.canvasWidth
/= this.options
.pixelWidth
;
623 /* TODO: dynamically include other scripts */
626 setPixel: function(x
, y
, color
){
628 pxW
= this.options
.pixelWidth
;
629 pxH
= this.options
.pixelHeight
;
632 this.canvas
.fillStyle
= color
.toString();
633 this.canvas
.fillRect (x
* pxW
, y
* pxH
, pxW
, pxH
);
636 checkNumber
+= color
.brightness();
638 // print(x * pxW, y * pxH, pxW, pxH);
642 renderScene: function(scene
, canvas
){
646 this.canvas
= canvas
.getContext("2d");
651 var canvasHeight
= this.options
.canvasHeight
;
652 var canvasWidth
= this.options
.canvasWidth
;
654 for(var y
=0; y
< canvasHeight
; y
++){
655 for(var x
=0; x
< canvasWidth
; x
++){
656 var yp
= y
* 1.0 / canvasHeight
* 2 - 1;
657 var xp
= x
* 1.0 / canvasWidth
* 2 - 1;
659 var ray
= scene
.camera
.getRay(xp
, yp
);
661 var color
= this.getPixelColor(ray
, scene
);
663 this.setPixel(x
, y
, color
);
666 if (checkNumber
!== 2321) {
667 throw new Error("Scene rendered incorrectly");
671 getPixelColor: function(ray
, scene
){
672 var info
= this.testIntersection(ray
, scene
, null);
674 var color
= this.rayTrace(info
, ray
, scene
, 0);
677 return scene
.background
.color
;
680 testIntersection: function(ray
, scene
, exclude
){
682 var best
= new Flog
.RayTracer
.IntersectionInfo();
683 best
.distance
= 2000;
685 for(var i
=0; i
<scene
.shapes
.length
; i
++){
686 var shape
= scene
.shapes
[i
];
688 if(shape
!= exclude
){
689 var info
= shape
.intersect(ray
);
690 if(info
.isHit
&& info
.distance
>= 0 && info
.distance
< best
.distance
){
696 best
.hitCount
= hits
;
700 getReflectionRay: function(P
,N
,V
){
702 var R1
= Flog
.RayTracer
.Vector
.prototype.add(
703 Flog
.RayTracer
.Vector
.prototype.multiplyScalar(N
, 2*c1
),
706 return new Flog
.RayTracer
.Ray(P
, R1
);
709 rayTrace: function(info
, ray
, scene
, depth
){
711 var color
= Flog
.RayTracer
.Color
.prototype.multiplyScalar(info
.color
, scene
.background
.ambience
);
712 var oldColor
= color
;
713 var shininess
= Math
.pow(10, info
.shape
.material
.gloss
+ 1);
715 for(var i
=0; i
<scene
.lights
.length
; i
++){
716 var light
= scene
.lights
[i
];
718 // Calc diffuse lighting
719 var v
= Flog
.RayTracer
.Vector
.prototype.subtract(
724 if(this.options
.renderDiffuse
){
725 var L
= v
.dot(info
.normal
);
727 color
= Flog
.RayTracer
.Color
.prototype.add(
729 Flog
.RayTracer
.Color
.prototype.multiply(
731 Flog
.RayTracer
.Color
.prototype.multiplyScalar(
740 // The greater the depth the more accurate the colours, but
741 // this is exponentially (!) expensive
742 if(depth
<= this.options
.rayDepth
){
743 // calculate reflection ray
744 if(this.options
.renderReflections
&& info
.shape
.material
.reflection
> 0)
746 var reflectionRay
= this.getReflectionRay(info
.position
, info
.normal
, ray
.direction
);
747 var refl
= this.testIntersection(reflectionRay
, scene
, info
.shape
);
749 if (refl
.isHit
&& refl
.distance
> 0){
750 refl
.color
= this.rayTrace(refl
, reflectionRay
, scene
, depth
+ 1);
752 refl
.color
= scene
.background
.color
;
755 color
= Flog
.RayTracer
.Color
.prototype.blend(
758 info
.shape
.material
.reflection
766 /* Render shadows and highlights */
768 var shadowInfo
= new Flog
.RayTracer
.IntersectionInfo();
770 if(this.options
.renderShadows
){
771 var shadowRay
= new Flog
.RayTracer
.Ray(info
.position
, v
);
773 shadowInfo
= this.testIntersection(shadowRay
, scene
, info
.shape
);
774 if(shadowInfo
.isHit
&& shadowInfo
.shape
!= info
.shape
/*&& shadowInfo.shape.type != 'PLANE'*/){
775 var vA
= Flog
.RayTracer
.Color
.prototype.multiplyScalar(color
, 0.5);
776 var dB
= (0.5 * Math
.pow(shadowInfo
.shape
.material
.transparency
, 0.5));
777 color
= Flog
.RayTracer
.Color
.prototype.addScalar(vA
,dB
);
781 // Phong specular highlights
782 if(this.options
.renderHighlights
&& !shadowInfo
.isHit
&& info
.shape
.material
.gloss
> 0){
783 var Lv
= Flog
.RayTracer
.Vector
.prototype.subtract(
788 var E
= Flog
.RayTracer
.Vector
.prototype.subtract(
789 scene
.camera
.position
,
793 var H
= Flog
.RayTracer
.Vector
.prototype.subtract(
798 var glossWeight
= Math
.pow(Math
.max(info
.normal
.dot(H
), 0), shininess
);
799 color
= Flog
.RayTracer
.Color
.prototype.add(
800 Flog
.RayTracer
.Color
.prototype.multiplyScalar(light
.color
, glossWeight
),
811 function renderScene(){
812 var scene
= new Flog
.RayTracer
.Scene();
814 scene
.camera
= new Flog
.RayTracer
.Camera(
815 new Flog
.RayTracer
.Vector(0, 0, -15),
816 new Flog
.RayTracer
.Vector(-0.2, 0, 5),
817 new Flog
.RayTracer
.Vector(0, 1, 0)
820 scene
.background
= new Flog
.RayTracer
.Background(
821 new Flog
.RayTracer
.Color(0.5, 0.5, 0.5),
825 var sphere
= new Flog
.RayTracer
.Shape
.Sphere(
826 new Flog
.RayTracer
.Vector(-1.5, 1.5, 2),
828 new Flog
.RayTracer
.Material
.Solid(
829 new Flog
.RayTracer
.Color(0,0.5,0.5),
837 var sphere1
= new Flog
.RayTracer
.Shape
.Sphere(
838 new Flog
.RayTracer
.Vector(1, 0.25, 1),
840 new Flog
.RayTracer
.Material
.Solid(
841 new Flog
.RayTracer
.Color(0.9,0.9,0.9),
849 var plane
= new Flog
.RayTracer
.Shape
.Plane(
850 new Flog
.RayTracer
.Vector(0.1, 0.9, -0.5).normalize(),
852 new Flog
.RayTracer
.Material
.Chessboard(
853 new Flog
.RayTracer
.Color(1,1,1),
854 new Flog
.RayTracer
.Color(0,0,0),
862 scene
.shapes
.push(plane
);
863 scene
.shapes
.push(sphere
);
864 scene
.shapes
.push(sphere1
);
866 var light
= new Flog
.RayTracer
.Light(
867 new Flog
.RayTracer
.Vector(5, 10, -1),
868 new Flog
.RayTracer
.Color(0.8, 0.8, 0.8)
871 var light1
= new Flog
.RayTracer
.Light(
872 new Flog
.RayTracer
.Vector(-3, 5, -15),
873 new Flog
.RayTracer
.Color(0.8, 0.8, 0.8),
877 scene
.lights
.push(light
);
878 scene
.lights
.push(light1
);
880 var imageWidth
= 100; // $F('imageWidth');
881 var imageHeight
= 100; // $F('imageHeight');
882 var pixelSize
= "5,5".split(','); // $F('pixelSize').split(',');
883 var renderDiffuse
= true; // $F('renderDiffuse');
884 var renderShadows
= true; // $F('renderShadows');
885 var renderHighlights
= true; // $F('renderHighlights');
886 var renderReflections
= true; // $F('renderReflections');
887 var rayDepth
= 2;//$F('rayDepth');
889 var raytracer
= new Flog
.RayTracer
.Engine(
891 canvasWidth
: imageWidth
,
892 canvasHeight
: imageHeight
,
893 pixelWidth
: pixelSize
[0],
894 pixelHeight
: pixelSize
[1],
895 "renderDiffuse": renderDiffuse
,
896 "renderHighlights": renderHighlights
,
897 "renderShadows": renderShadows
,
898 "renderReflections": renderReflections
,
903 raytracer
.renderScene(scene
, null, 0);