// The ray tracer code in this file is written by Adam Burmister. It // is available in its original form from: // // http://labs.flog.nz.co/raytracer/ // // It has been modified slightly by Google to work as a standalone // benchmark, but the all the computational code remains // untouched. This file also contains a copy of parts of the Prototype // JavaScript framework which is used by the ray tracer.
//var RayTrace = new BenchmarkSuite('RayTrace', 932666, [ // new Benchmark('RayTrace', renderScene) //]);
// Variable used to hold a number that can be used to verify that // the scene was ray traced correctly. var checkNumber;
// The following is a copy of parts of the Prototype JavaScript library:
// Prototype JavaScript framework, version 1.5.0 // (c) 2005-2007 Sam Stephenson // // Prototype is freely distributable under the terms of an MIT-style license. // For details, see the Prototype web site: http://prototype.conio.net/
// The rest of this file is the actual ray tracer written by Adam // Burmister. It's a concatenation of the following files: // // flog/color.js // flog/light.js // flog/vector.js // flog/ray.js // flog/scene.js // flog/material/basematerial.js // flog/material/solid.js // flog/material/chessboard.js // flog/shape/baseshape.js // flog/shape/sphere.js // flog/shape/plane.js // flog/intersectioninfo.js // flog/camera.js // flog/background.js // flog/engine.js
/* Fake a Flog.* namespace */ if(typeof(Flog) == 'undefined') var Flog = {}; if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
Flog.RayTracer.Color = Class.create();
Flog.RayTracer.Color.prototype = {
red : 0.0,
green : 0.0,
blue : 0.0,
initialize : function(r, g, b) { if(!r) r = 0.0; if(!g) g = 0.0; if(!b) b = 0.0;
this.red = r; this.green = g; this.blue = b;
},
add : function(c1, c2){ var result = new Flog.RayTracer.Color(0,0,0);
blend: function(c1, c2, w){ var result = new Flog.RayTracer.Color(0,0,0);
result = Flog.RayTracer.Color.prototype.add(
Flog.RayTracer.Color.prototype.multiplyScalar(c1, 1 - w),
Flog.RayTracer.Color.prototype.multiplyScalar(c2, w)
); return result;
},
brightness : function() { var r = Math.floor(this.red*255); var g = Math.floor(this.green*255); var b = Math.floor(this.blue*255); return (r * 77 + g * 150 + b * 29) >> 8;
},
toString : function () { var r = Math.floor(this.red*255); var g = Math.floor(this.green*255); var b = Math.floor(this.blue*255);
return"rgb("+ r +","+ g +","+ b +")";
}
} /* Fake a Flog.* namespace */ if(typeof(Flog) == 'undefined') var Flog = {}; if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
if(this.material.hasTexture){ var vU = new Flog.RayTracer.Vector(this.position.y, this.position.z, -this.position.x); var vV = vU.cross(this.position); var u = info.position.dot(vU); var v = info.position.dot(vV);
info.color = this.material.getColor(u,v);
} else {
info.color = this.material.getColor(0,0);
}
var canvasHeight = this.options.canvasHeight; var canvasWidth = this.options.canvasWidth;
for(var y=0; y < canvasHeight; y++){ for(var x=0; x < canvasWidth; x++){ var yp = y * 1.0 / canvasHeight * 2 - 1; var xp = x * 1.0 / canvasWidth * 2 - 1;
var ray = scene.camera.getRay(xp, yp);
var color = this.getPixelColor(ray, scene);
this.setPixel(x, y, color);
}
}
assertEq(checkNumber, 2321);
},
getPixelColor: function(ray, scene){ var info = this.testIntersection(ray, scene, null); if(info.isHit){ var color = this.rayTrace(info, ray, scene, 0); return color;
} return scene.background.color;
},
testIntersection: function(ray, scene, exclude){ var hits = 0; var best = new Flog.RayTracer.IntersectionInfo();
best.distance = 2000;
for(var i=0; i<scene.shapes.length; i++){ var shape = scene.shapes[i];
if(shape != exclude){ var info = shape.intersect(ray); if(info.isHit && info.distance >= 0 && info.distance < best.distance){
best = info;
hits++;
}
}
}
best.hitCount = hits; return best;
},
getReflectionRay: function(P,N,V){ var c1 = -N.dot(V); var R1 = Flog.RayTracer.Vector.prototype.add(
Flog.RayTracer.Vector.prototype.multiplyScalar(N, 2*c1),
V
); returnnew Flog.RayTracer.Ray(P, R1);
},
rayTrace: function(info, ray, scene, depth){ // Calc ambient var color = Flog.RayTracer.Color.prototype.multiplyScalar(info.color, scene.background.ambience); var oldColor = color; var shininess = Math.pow(10, info.shape.material.gloss + 1);
for(var i=0; i<scene.lights.length; i++){ var light = scene.lights[i];
// Calc diffuse lighting var v = Flog.RayTracer.Vector.prototype.subtract(
light.position,
info.position
).normalize();
if(this.options.renderDiffuse){ var L = v.dot(info.normal); if(L > 0.0){
color = Flog.RayTracer.Color.prototype.add(
color,
Flog.RayTracer.Color.prototype.multiply(
info.color,
Flog.RayTracer.Color.prototype.multiplyScalar(
light.color,
L
)
)
);
}
}
// The greater the depth the more accurate the colours, but // this is exponentially (!) expensive if(depth <= this.options.rayDepth){ // calculate reflection ray if(this.options.renderReflections && info.shape.material.reflection > 0)
{ var reflectionRay = this.getReflectionRay(info.position, info.normal, ray.direction); var refl = this.testIntersection(reflectionRay, scene, info.shape);
var E = Flog.RayTracer.Vector.prototype.subtract(
scene.camera.position,
info.shape.position
).normalize();
var H = Flog.RayTracer.Vector.prototype.subtract(
E,
Lv
).normalize();
var glossWeight = Math.pow(Math.max(info.normal.dot(H), 0), shininess);
color = Flog.RayTracer.Color.prototype.add(
Flog.RayTracer.Color.prototype.multiplyScalar(light.color, glossWeight),
color
);
}
}
color.limit(); return color;
}
};
function renderScene(){ var scene = new Flog.RayTracer.Scene();
scene.camera = new Flog.RayTracer.Camera( new Flog.RayTracer.Vector(0, 0, -15), new Flog.RayTracer.Vector(-0.2, 0, 5), new Flog.RayTracer.Vector(0, 1, 0)
);
scene.background = new Flog.RayTracer.Background( new Flog.RayTracer.Color(0.5, 0.5, 0.5),
0.4
);
var sphere = new Flog.RayTracer.Shape.Sphere( new Flog.RayTracer.Vector(-1.5, 1.5, 2),
1.5, new Flog.RayTracer.Material.Solid( new Flog.RayTracer.Color(0,0.5,0.5),
0.3,
0.0,
0.0,
2.0
)
);
var sphere1 = new Flog.RayTracer.Shape.Sphere( new Flog.RayTracer.Vector(1, 0.25, 1),
0.5, new Flog.RayTracer.Material.Solid( new Flog.RayTracer.Color(0.9,0.9,0.9),
0.1,
0.0,
0.0,
1.5
)
);
var plane = new Flog.RayTracer.Shape.Plane( new Flog.RayTracer.Vector(0.1, 0.9, -0.5).normalize(),
1.2, new Flog.RayTracer.Material.Chessboard( new Flog.RayTracer.Color(1,1,1), new Flog.RayTracer.Color(0,0,0),
0.2,
0.0,
1.0,
0.7
)
);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.