]> git.saurik.com Git - apple/javascriptcore.git/blame - tests/executableAllocationFuzz/v8-raytrace.js
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / tests / executableAllocationFuzz / v8-raytrace.js
CommitLineData
ed1e77d3
A
1// The ray tracer code in this file is written by Adam Burmister. It
2// is available in its original form from:
3//
4// http://labs.flog.nz.co/raytracer/
5//
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.
10
11// Variable used to hold a number that can be used to verify that
12// the scene was ray traced correctly.
13var checkNumber;
14
15
16// ------------------------------------------------------------------------
17// ------------------------------------------------------------------------
18
19// The following is a copy of parts of the Prototype JavaScript library:
20
21// Prototype JavaScript framework, version 1.5.0
22// (c) 2005-2007 Sam Stephenson
23//
24// Prototype is freely distributable under the terms of an MIT-style license.
25// For details, see the Prototype web site: http://prototype.conio.net/
26
27
28var Class = {
29 create: function() {
30 return function() {
31 this.initialize.apply(this, arguments);
32 }
33 }
34};
35
36
37Object.extend = function(destination, source) {
38 for (var property in source) {
39 destination[property] = source[property];
40 }
41 return destination;
42};
43
44
45// ------------------------------------------------------------------------
46// ------------------------------------------------------------------------
47
48// The rest of this file is the actual ray tracer written by Adam
49// Burmister. It's a concatenation of the following files:
50//
51// flog/color.js
52// flog/light.js
53// flog/vector.js
54// flog/ray.js
55// flog/scene.js
56// flog/material/basematerial.js
57// flog/material/solid.js
58// flog/material/chessboard.js
59// flog/shape/baseshape.js
60// flog/shape/sphere.js
61// flog/shape/plane.js
62// flog/intersectioninfo.js
63// flog/camera.js
64// flog/background.js
65// flog/engine.js
66
67
68/* Fake a Flog.* namespace */
69if(typeof(Flog) == 'undefined') var Flog = {};
70if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
71
72Flog.RayTracer.Color = Class.create();
73
74Flog.RayTracer.Color.prototype = {
75 red : 0.0,
76 green : 0.0,
77 blue : 0.0,
78
79 initialize : function(r, g, b) {
80 if(!r) r = 0.0;
81 if(!g) g = 0.0;
82 if(!b) b = 0.0;
83
84 this.red = r;
85 this.green = g;
86 this.blue = b;
87 },
88
89 add : function(c1, c2){
90 var result = new Flog.RayTracer.Color(0,0,0);
91
92 result.red = c1.red + c2.red;
93 result.green = c1.green + c2.green;
94 result.blue = c1.blue + c2.blue;
95
96 return result;
97 },
98
99 addScalar: function(c1, s){
100 var result = new Flog.RayTracer.Color(0,0,0);
101
102 result.red = c1.red + s;
103 result.green = c1.green + s;
104 result.blue = c1.blue + s;
105
106 result.limit();
107
108 return result;
109 },
110
111 subtract: function(c1, c2){
112 var result = new Flog.RayTracer.Color(0,0,0);
113
114 result.red = c1.red - c2.red;
115 result.green = c1.green - c2.green;
116 result.blue = c1.blue - c2.blue;
117
118 return result;
119 },
120
121 multiply : function(c1, c2) {
122 var result = new Flog.RayTracer.Color(0,0,0);
123
124 result.red = c1.red * c2.red;
125 result.green = c1.green * c2.green;
126 result.blue = c1.blue * c2.blue;
127
128 return result;
129 },
130
131 multiplyScalar : function(c1, f) {
132 var result = new Flog.RayTracer.Color(0,0,0);
133
134 result.red = c1.red * f;
135 result.green = c1.green * f;
136 result.blue = c1.blue * f;
137
138 return result;
139 },
140
141 divideFactor : function(c1, f) {
142 var result = new Flog.RayTracer.Color(0,0,0);
143
144 result.red = c1.red / f;
145 result.green = c1.green / f;
146 result.blue = c1.blue / f;
147
148 return result;
149 },
150
151 limit: function(){
152 this.red = (this.red > 0.0) ? ( (this.red > 1.0) ? 1.0 : this.red ) : 0.0;
153 this.green = (this.green > 0.0) ? ( (this.green > 1.0) ? 1.0 : this.green ) : 0.0;
154 this.blue = (this.blue > 0.0) ? ( (this.blue > 1.0) ? 1.0 : this.blue ) : 0.0;
155 },
156
157 distance : function(color) {
158 var d = Math.abs(this.red - color.red) + Math.abs(this.green - color.green) + Math.abs(this.blue - color.blue);
159 return d;
160 },
161
162 blend: function(c1, c2, w){
163 var result = new Flog.RayTracer.Color(0,0,0);
164 result = Flog.RayTracer.Color.prototype.add(
165 Flog.RayTracer.Color.prototype.multiplyScalar(c1, 1 - w),
166 Flog.RayTracer.Color.prototype.multiplyScalar(c2, w)
167 );
168 return result;
169 },
170
171 brightness : function() {
172 var r = Math.floor(this.red*255);
173 var g = Math.floor(this.green*255);
174 var b = Math.floor(this.blue*255);
175 return (r * 77 + g * 150 + b * 29) >> 8;
176 },
177
178 toString : function () {
179 var r = Math.floor(this.red*255);
180 var g = Math.floor(this.green*255);
181 var b = Math.floor(this.blue*255);
182
183 return "rgb("+ r +","+ g +","+ b +")";
184 }
185}
186/* Fake a Flog.* namespace */
187if(typeof(Flog) == 'undefined') var Flog = {};
188if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
189
190Flog.RayTracer.Light = Class.create();
191
192Flog.RayTracer.Light.prototype = {
193 position: null,
194 color: null,
195 intensity: 10.0,
196
197 initialize : function(pos, color, intensity) {
198 this.position = pos;
199 this.color = color;
200 this.intensity = (intensity ? intensity : 10.0);
201 },
202
203 toString : function () {
204 return 'Light [' + this.position.x + ',' + this.position.y + ',' + this.position.z + ']';
205 }
206}
207/* Fake a Flog.* namespace */
208if(typeof(Flog) == 'undefined') var Flog = {};
209if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
210
211Flog.RayTracer.Vector = Class.create();
212
213Flog.RayTracer.Vector.prototype = {
214 x : 0.0,
215 y : 0.0,
216 z : 0.0,
217
218 initialize : function(x, y, z) {
219 this.x = (x ? x : 0);
220 this.y = (y ? y : 0);
221 this.z = (z ? z : 0);
222 },
223
224 copy: function(vector){
225 this.x = vector.x;
226 this.y = vector.y;
227 this.z = vector.z;
228 },
229
230 normalize : function() {
231 var m = this.magnitude();
232 return new Flog.RayTracer.Vector(this.x / m, this.y / m, this.z / m);
233 },
234
235 magnitude : function() {
236 return Math.sqrt((this.x * this.x) + (this.y * this.y) + (this.z * this.z));
237 },
238
239 cross : function(w) {
240 return new Flog.RayTracer.Vector(
241 -this.z * w.y + this.y * w.z,
242 this.z * w.x - this.x * w.z,
243 -this.y * w.x + this.x * w.y);
244 },
245
246 dot : function(w) {
247 return this.x * w.x + this.y * w.y + this.z * w.z;
248 },
249
250 add : function(v, w) {
251 return new Flog.RayTracer.Vector(w.x + v.x, w.y + v.y, w.z + v.z);
252 },
253
254 subtract : function(v, w) {
255 if(!w || !v) throw 'Vectors must be defined [' + v + ',' + w + ']';
256 return new Flog.RayTracer.Vector(v.x - w.x, v.y - w.y, v.z - w.z);
257 },
258
259 multiplyVector : function(v, w) {
260 return new Flog.RayTracer.Vector(v.x * w.x, v.y * w.y, v.z * w.z);
261 },
262
263 multiplyScalar : function(v, w) {
264 return new Flog.RayTracer.Vector(v.x * w, v.y * w, v.z * w);
265 },
266
267 toString : function () {
268 return 'Vector [' + this.x + ',' + this.y + ',' + this.z + ']';
269 }
270}
271/* Fake a Flog.* namespace */
272if(typeof(Flog) == 'undefined') var Flog = {};
273if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
274
275Flog.RayTracer.Ray = Class.create();
276
277Flog.RayTracer.Ray.prototype = {
278 position : null,
279 direction : null,
280 initialize : function(pos, dir) {
281 this.position = pos;
282 this.direction = dir;
283 },
284
285 toString : function () {
286 return 'Ray [' + this.position + ',' + this.direction + ']';
287 }
288}
289/* Fake a Flog.* namespace */
290if(typeof(Flog) == 'undefined') var Flog = {};
291if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
292
293Flog.RayTracer.Scene = Class.create();
294
295Flog.RayTracer.Scene.prototype = {
296 camera : null,
297 shapes : [],
298 lights : [],
299 background : null,
300
301 initialize : function() {
302 this.camera = new Flog.RayTracer.Camera(
303 new Flog.RayTracer.Vector(0,0,-5),
304 new Flog.RayTracer.Vector(0,0,1),
305 new Flog.RayTracer.Vector(0,1,0)
306 );
307 this.shapes = new Array();
308 this.lights = new Array();
309 this.background = new Flog.RayTracer.Background(new Flog.RayTracer.Color(0,0,0.5), 0.2);
310 }
311}
312/* Fake a Flog.* namespace */
313if(typeof(Flog) == 'undefined') var Flog = {};
314if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
315if(typeof(Flog.RayTracer.Material) == 'undefined') Flog.RayTracer.Material = {};
316
317Flog.RayTracer.Material.BaseMaterial = Class.create();
318
319Flog.RayTracer.Material.BaseMaterial.prototype = {
320
321 gloss: 2.0, // [0...infinity] 0 = matt
322 transparency: 0.0, // 0=opaque
323 reflection: 0.0, // [0...infinity] 0 = no reflection
324 refraction: 0.50,
325 hasTexture: false,
326
327 initialize : function() {
328
329 },
330
331 getColor: function(u, v){
332
333 },
334
335 wrapUp: function(t){
336 t = t % 2.0;
337 if(t < -1) t += 2.0;
338 if(t >= 1) t -= 2.0;
339 return t;
340 },
341
342 toString : function () {
343 return 'Material [gloss=' + this.gloss + ', transparency=' + this.transparency + ', hasTexture=' + this.hasTexture +']';
344 }
345}
346/* Fake a Flog.* namespace */
347if(typeof(Flog) == 'undefined') var Flog = {};
348if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
349
350Flog.RayTracer.Material.Solid = Class.create();
351
352Flog.RayTracer.Material.Solid.prototype = Object.extend(
353 new Flog.RayTracer.Material.BaseMaterial(), {
354 initialize : function(color, reflection, refraction, transparency, gloss) {
355 this.color = color;
356 this.reflection = reflection;
357 this.transparency = transparency;
358 this.gloss = gloss;
359 this.hasTexture = false;
360 },
361
362 getColor: function(u, v){
363 return this.color;
364 },
365
366 toString : function () {
367 return 'SolidMaterial [gloss=' + this.gloss + ', transparency=' + this.transparency + ', hasTexture=' + this.hasTexture +']';
368 }
369 }
370);
371/* Fake a Flog.* namespace */
372if(typeof(Flog) == 'undefined') var Flog = {};
373if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
374
375Flog.RayTracer.Material.Chessboard = Class.create();
376
377Flog.RayTracer.Material.Chessboard.prototype = Object.extend(
378 new Flog.RayTracer.Material.BaseMaterial(), {
379 colorEven: null,
380 colorOdd: null,
381 density: 0.5,
382
383 initialize : function(colorEven, colorOdd, reflection, transparency, gloss, density) {
384 this.colorEven = colorEven;
385 this.colorOdd = colorOdd;
386 this.reflection = reflection;
387 this.transparency = transparency;
388 this.gloss = gloss;
389 this.density = density;
390 this.hasTexture = true;
391 },
392
393 getColor: function(u, v){
394 var t = this.wrapUp(u * this.density) * this.wrapUp(v * this.density);
395
396 if(t < 0.0)
397 return this.colorEven;
398 else
399 return this.colorOdd;
400 },
401
402 toString : function () {
403 return 'ChessMaterial [gloss=' + this.gloss + ', transparency=' + this.transparency + ', hasTexture=' + this.hasTexture +']';
404 }
405 }
406);
407/* Fake a Flog.* namespace */
408if(typeof(Flog) == 'undefined') var Flog = {};
409if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
410if(typeof(Flog.RayTracer.Shape) == 'undefined') Flog.RayTracer.Shape = {};
411
412Flog.RayTracer.Shape.Sphere = Class.create();
413
414Flog.RayTracer.Shape.Sphere.prototype = {
415 initialize : function(pos, radius, material) {
416 this.radius = radius;
417 this.position = pos;
418 this.material = material;
419 },
420
421 intersect: function(ray){
422 var info = new Flog.RayTracer.IntersectionInfo();
423 info.shape = this;
424
425 var dst = Flog.RayTracer.Vector.prototype.subtract(ray.position, this.position);
426
427 var B = dst.dot(ray.direction);
428 var C = dst.dot(dst) - (this.radius * this.radius);
429 var D = (B * B) - C;
430
431 if(D > 0){ // intersection!
432 info.isHit = true;
433 info.distance = (-B) - Math.sqrt(D);
434 info.position = Flog.RayTracer.Vector.prototype.add(
435 ray.position,
436 Flog.RayTracer.Vector.prototype.multiplyScalar(
437 ray.direction,
438 info.distance
439 )
440 );
441 info.normal = Flog.RayTracer.Vector.prototype.subtract(
442 info.position,
443 this.position
444 ).normalize();
445
446 info.color = this.material.getColor(0,0);
447 } else {
448 info.isHit = false;
449 }
450 return info;
451 },
452
453 toString : function () {
454 return 'Sphere [position=' + this.position + ', radius=' + this.radius + ']';
455 }
456}
457/* Fake a Flog.* namespace */
458if(typeof(Flog) == 'undefined') var Flog = {};
459if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
460if(typeof(Flog.RayTracer.Shape) == 'undefined') Flog.RayTracer.Shape = {};
461
462Flog.RayTracer.Shape.Plane = Class.create();
463
464Flog.RayTracer.Shape.Plane.prototype = {
465 d: 0.0,
466
467 initialize : function(pos, d, material) {
468 this.position = pos;
469 this.d = d;
470 this.material = material;
471 },
472
473 intersect: function(ray){
474 var info = new Flog.RayTracer.IntersectionInfo();
475
476 var Vd = this.position.dot(ray.direction);
477 if(Vd == 0) return info; // no intersection
478
479 var t = -(this.position.dot(ray.position) + this.d) / Vd;
480 if(t <= 0) return info;
481
482 info.shape = this;
483 info.isHit = true;
484 info.position = Flog.RayTracer.Vector.prototype.add(
485 ray.position,
486 Flog.RayTracer.Vector.prototype.multiplyScalar(
487 ray.direction,
488 t
489 )
490 );
491 info.normal = this.position;
492 info.distance = t;
493
494 if(this.material.hasTexture){
495 var vU = new Flog.RayTracer.Vector(this.position.y, this.position.z, -this.position.x);
496 var vV = vU.cross(this.position);
497 var u = info.position.dot(vU);
498 var v = info.position.dot(vV);
499 info.color = this.material.getColor(u,v);
500 } else {
501 info.color = this.material.getColor(0,0);
502 }
503
504 return info;
505 },
506
507 toString : function () {
508 return 'Plane [' + this.position + ', d=' + this.d + ']';
509 }
510}
511/* Fake a Flog.* namespace */
512if(typeof(Flog) == 'undefined') var Flog = {};
513if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
514
515Flog.RayTracer.IntersectionInfo = Class.create();
516
517Flog.RayTracer.IntersectionInfo.prototype = {
518 isHit: false,
519 hitCount: 0,
520 shape: null,
521 position: null,
522 normal: null,
523 color: null,
524 distance: null,
525
526 initialize : function() {
527 this.color = new Flog.RayTracer.Color(0,0,0);
528 },
529
530 toString : function () {
531 return 'Intersection [' + this.position + ']';
532 }
533}
534/* Fake a Flog.* namespace */
535if(typeof(Flog) == 'undefined') var Flog = {};
536if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
537
538Flog.RayTracer.Camera = Class.create();
539
540Flog.RayTracer.Camera.prototype = {
541 position: null,
542 lookAt: null,
543 equator: null,
544 up: null,
545 screen: null,
546
547 initialize : function(pos, lookAt, up) {
548 this.position = pos;
549 this.lookAt = lookAt;
550 this.up = up;
551 this.equator = lookAt.normalize().cross(this.up);
552 this.screen = Flog.RayTracer.Vector.prototype.add(this.position, this.lookAt);
553 },
554
555 getRay: function(vx, vy){
556 var pos = Flog.RayTracer.Vector.prototype.subtract(
557 this.screen,
558 Flog.RayTracer.Vector.prototype.subtract(
559 Flog.RayTracer.Vector.prototype.multiplyScalar(this.equator, vx),
560 Flog.RayTracer.Vector.prototype.multiplyScalar(this.up, vy)
561 )
562 );
563 pos.y = pos.y * -1;
564 var dir = Flog.RayTracer.Vector.prototype.subtract(
565 pos,
566 this.position
567 );
568
569 var ray = new Flog.RayTracer.Ray(pos, dir.normalize());
570
571 return ray;
572 },
573
574 toString : function () {
575 return 'Ray []';
576 }
577}
578/* Fake a Flog.* namespace */
579if(typeof(Flog) == 'undefined') var Flog = {};
580if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
581
582Flog.RayTracer.Background = Class.create();
583
584Flog.RayTracer.Background.prototype = {
585 color : null,
586 ambience : 0.0,
587
588 initialize : function(color, ambience) {
589 this.color = color;
590 this.ambience = ambience;
591 }
592}
593/* Fake a Flog.* namespace */
594if(typeof(Flog) == 'undefined') var Flog = {};
595if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
596
597Flog.RayTracer.Engine = Class.create();
598
599Flog.RayTracer.Engine.prototype = {
600 canvas: null, /* 2d context we can render to */
601
602 initialize: function(options){
603 this.options = Object.extend({
604 canvasHeight: 100,
605 canvasWidth: 100,
606 pixelWidth: 2,
607 pixelHeight: 2,
608 renderDiffuse: false,
609 renderShadows: false,
610 renderHighlights: false,
611 renderReflections: false,
612 rayDepth: 2
613 }, options || {});
614
615 this.options.canvasHeight /= this.options.pixelHeight;
616 this.options.canvasWidth /= this.options.pixelWidth;
617
618 /* TODO: dynamically include other scripts */
619 },
620
621 setPixel: function(x, y, color){
622 var pxW, pxH;
623 pxW = this.options.pixelWidth;
624 pxH = this.options.pixelHeight;
625
626 if (this.canvas) {
627 this.canvas.fillStyle = color.toString();
628 this.canvas.fillRect (x * pxW, y * pxH, pxW, pxH);
629 } else {
630 if (x === y) {
631 checkNumber += color.brightness();
632 }
633 // print(x * pxW, y * pxH, pxW, pxH);
634 }
635 },
636
637 renderScene: function(scene, canvas){
638 checkNumber = 0;
639 /* Get canvas */
640 if (canvas) {
641 this.canvas = canvas.getContext("2d");
642 } else {
643 this.canvas = null;
644 }
645
646 var canvasHeight = this.options.canvasHeight;
647 var canvasWidth = this.options.canvasWidth;
648
649 for(var y=0; y < canvasHeight; y++){
650 for(var x=0; x < canvasWidth; x++){
651 var yp = y * 1.0 / canvasHeight * 2 - 1;
652 var xp = x * 1.0 / canvasWidth * 2 - 1;
653
654 var ray = scene.camera.getRay(xp, yp);
655
656 var color = this.getPixelColor(ray, scene);
657
658 this.setPixel(x, y, color);
659 }
660 }
661 if (checkNumber !== 2321) {
662 throw new Error("Scene rendered incorrectly");
663 }
664 },
665
666 getPixelColor: function(ray, scene){
667 var info = this.testIntersection(ray, scene, null);
668 if(info.isHit){
669 var color = this.rayTrace(info, ray, scene, 0);
670 return color;
671 }
672 return scene.background.color;
673 },
674
675 testIntersection: function(ray, scene, exclude){
676 var hits = 0;
677 var best = new Flog.RayTracer.IntersectionInfo();
678 best.distance = 2000;
679
680 for(var i=0; i<scene.shapes.length; i++){
681 var shape = scene.shapes[i];
682
683 if(shape != exclude){
684 var info = shape.intersect(ray);
685 if(info.isHit && info.distance >= 0 && info.distance < best.distance){
686 best = info;
687 hits++;
688 }
689 }
690 }
691 best.hitCount = hits;
692 return best;
693 },
694
695 getReflectionRay: function(P,N,V){
696 var c1 = -N.dot(V);
697 var R1 = Flog.RayTracer.Vector.prototype.add(
698 Flog.RayTracer.Vector.prototype.multiplyScalar(N, 2*c1),
699 V
700 );
701 return new Flog.RayTracer.Ray(P, R1);
702 },
703
704 rayTrace: function(info, ray, scene, depth){
705 // Calc ambient
706 var color = Flog.RayTracer.Color.prototype.multiplyScalar(info.color, scene.background.ambience);
707 var oldColor = color;
708 var shininess = Math.pow(10, info.shape.material.gloss + 1);
709
710 for(var i=0; i<scene.lights.length; i++){
711 var light = scene.lights[i];
712
713 // Calc diffuse lighting
714 var v = Flog.RayTracer.Vector.prototype.subtract(
715 light.position,
716 info.position
717 ).normalize();
718
719 if(this.options.renderDiffuse){
720 var L = v.dot(info.normal);
721 if(L > 0.0){
722 color = Flog.RayTracer.Color.prototype.add(
723 color,
724 Flog.RayTracer.Color.prototype.multiply(
725 info.color,
726 Flog.RayTracer.Color.prototype.multiplyScalar(
727 light.color,
728 L
729 )
730 )
731 );
732 }
733 }
734
735 // The greater the depth the more accurate the colours, but
736 // this is exponentially (!) expensive
737 if(depth <= this.options.rayDepth){
738 // calculate reflection ray
739 if(this.options.renderReflections && info.shape.material.reflection > 0)
740 {
741 var reflectionRay = this.getReflectionRay(info.position, info.normal, ray.direction);
742 var refl = this.testIntersection(reflectionRay, scene, info.shape);
743
744 if (refl.isHit && refl.distance > 0){
745 refl.color = this.rayTrace(refl, reflectionRay, scene, depth + 1);
746 } else {
747 refl.color = scene.background.color;
748 }
749
750 color = Flog.RayTracer.Color.prototype.blend(
751 color,
752 refl.color,
753 info.shape.material.reflection
754 );
755 }
756
757 // Refraction
758 /* TODO */
759 }
760
761 /* Render shadows and highlights */
762
763 var shadowInfo = new Flog.RayTracer.IntersectionInfo();
764
765 if(this.options.renderShadows){
766 var shadowRay = new Flog.RayTracer.Ray(info.position, v);
767
768 shadowInfo = this.testIntersection(shadowRay, scene, info.shape);
769 if(shadowInfo.isHit && shadowInfo.shape != info.shape /*&& shadowInfo.shape.type != 'PLANE'*/){
770 var vA = Flog.RayTracer.Color.prototype.multiplyScalar(color, 0.5);
771 var dB = (0.5 * Math.pow(shadowInfo.shape.material.transparency, 0.5));
772 color = Flog.RayTracer.Color.prototype.addScalar(vA,dB);
773 }
774 }
775
776 // Phong specular highlights
777 if(this.options.renderHighlights && !shadowInfo.isHit && info.shape.material.gloss > 0){
778 var Lv = Flog.RayTracer.Vector.prototype.subtract(
779 info.shape.position,
780 light.position
781 ).normalize();
782
783 var E = Flog.RayTracer.Vector.prototype.subtract(
784 scene.camera.position,
785 info.shape.position
786 ).normalize();
787
788 var H = Flog.RayTracer.Vector.prototype.subtract(
789 E,
790 Lv
791 ).normalize();
792
793 var glossWeight = Math.pow(Math.max(info.normal.dot(H), 0), shininess);
794 color = Flog.RayTracer.Color.prototype.add(
795 Flog.RayTracer.Color.prototype.multiplyScalar(light.color, glossWeight),
796 color
797 );
798 }
799 }
800 color.limit();
801 return color;
802 }
803};
804
805
806function renderScene(){
807 var scene = new Flog.RayTracer.Scene();
808
809 scene.camera = new Flog.RayTracer.Camera(
810 new Flog.RayTracer.Vector(0, 0, -15),
811 new Flog.RayTracer.Vector(-0.2, 0, 5),
812 new Flog.RayTracer.Vector(0, 1, 0)
813 );
814
815 scene.background = new Flog.RayTracer.Background(
816 new Flog.RayTracer.Color(0.5, 0.5, 0.5),
817 0.4
818 );
819
820 var sphere = new Flog.RayTracer.Shape.Sphere(
821 new Flog.RayTracer.Vector(-1.5, 1.5, 2),
822 1.5,
823 new Flog.RayTracer.Material.Solid(
824 new Flog.RayTracer.Color(0,0.5,0.5),
825 0.3,
826 0.0,
827 0.0,
828 2.0
829 )
830 );
831
832 var sphere1 = new Flog.RayTracer.Shape.Sphere(
833 new Flog.RayTracer.Vector(1, 0.25, 1),
834 0.5,
835 new Flog.RayTracer.Material.Solid(
836 new Flog.RayTracer.Color(0.9,0.9,0.9),
837 0.1,
838 0.0,
839 0.0,
840 1.5
841 )
842 );
843
844 var plane = new Flog.RayTracer.Shape.Plane(
845 new Flog.RayTracer.Vector(0.1, 0.9, -0.5).normalize(),
846 1.2,
847 new Flog.RayTracer.Material.Chessboard(
848 new Flog.RayTracer.Color(1,1,1),
849 new Flog.RayTracer.Color(0,0,0),
850 0.2,
851 0.0,
852 1.0,
853 0.7
854 )
855 );
856
857 scene.shapes.push(plane);
858 scene.shapes.push(sphere);
859 scene.shapes.push(sphere1);
860
861 var light = new Flog.RayTracer.Light(
862 new Flog.RayTracer.Vector(5, 10, -1),
863 new Flog.RayTracer.Color(0.8, 0.8, 0.8)
864 );
865
866 var light1 = new Flog.RayTracer.Light(
867 new Flog.RayTracer.Vector(-3, 5, -15),
868 new Flog.RayTracer.Color(0.8, 0.8, 0.8),
869 100
870 );
871
872 scene.lights.push(light);
873 scene.lights.push(light1);
874
875 var imageWidth = 100; // $F('imageWidth');
876 var imageHeight = 100; // $F('imageHeight');
877 var pixelSize = "5,5".split(','); // $F('pixelSize').split(',');
878 var renderDiffuse = true; // $F('renderDiffuse');
879 var renderShadows = true; // $F('renderShadows');
880 var renderHighlights = true; // $F('renderHighlights');
881 var renderReflections = true; // $F('renderReflections');
882 var rayDepth = 2;//$F('rayDepth');
883
884 var raytracer = new Flog.RayTracer.Engine(
885 {
886 canvasWidth: imageWidth,
887 canvasHeight: imageHeight,
888 pixelWidth: pixelSize[0],
889 pixelHeight: pixelSize[1],
890 "renderDiffuse": renderDiffuse,
891 "renderHighlights": renderHighlights,
892 "renderShadows": renderShadows,
893 "renderReflections": renderReflections,
894 "rayDepth": rayDepth
895 }
896 );
897
898 raytracer.renderScene(scene, null, 0);
899}
900
901for (var i = 0; i < 6; ++i)
902 renderScene();