Skip to content

Commit

Permalink
Add RayTraceOO Dart and JS benchmark.
Browse files Browse the repository at this point in the history
  • Loading branch information
johnmccutchan committed Apr 16, 2013
1 parent ed052a0 commit 898af0e
Show file tree
Hide file tree
Showing 11 changed files with 1,530 additions and 0 deletions.
44 changes: 44 additions & 0 deletions pkgs/benchmark_harness/example/RayTraceOO/dart/RayTrace.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// The ray tracer code in this file is written by Adam Burmister. It
// is available in its original form from:
//
// http://labs.flog.co.nz/raytracer/
//
// Ported from the v8 benchmark suite by Google 2012.

library ray_trace;

import 'dart:math';

import 'package:benchmark_harness/benchmark_harness.dart';

part 'color.dart';
part 'engine.dart';
part 'materials.dart';
part 'scene.dart';
part 'shapes.dart';
part 'vector.dart';
part 'renderscene.dart';

// Dummy HTML definition.

query(a) {}

// Variable used to hold a number that can be used to verify that
// the scene was ray traced correctly.
var checkNumber;

class RaytraceBenchmark extends BenchmarkBase {
const RaytraceBenchmark() : super("RayTrace");

void warmup() {
renderScene(null);
}

void exercise() {
renderScene(null);
}
}

void main() {
new RaytraceBenchmark().report();
}
63 changes: 63 additions & 0 deletions pkgs/benchmark_harness/example/RayTraceOO/dart/color.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// The ray tracer code in this file is written by Adam Burmister. It
// is available in its original form from:
//
// http://labs.flog.co.nz/raytracer/
//
// Ported from the v8 benchmark suite by Google 2012.
part of ray_trace;

class Color {
double red;
double green;
double blue;

Color(this.red, this.green, this.blue);

void limit() {
this.red = (this.red > 0.0) ? ((this.red > 1.0) ? 1.0 : this.red) : 0.0;
this.green = (this.green > 0.0) ?
((this.green > 1.0) ? 1.0 : this.green) : 0.0;
this.blue = (this.blue > 0.0) ?
((this.blue > 1.0) ? 1.0 : this.blue) : 0.0;
}

Color operator +(Color c2) {
return new Color(red + c2.red, green + c2.green, blue + c2.blue);
}

Color addScalar(double s){
var result = new Color(red + s, green + s, blue + s);
result.limit();
return result;
}

Color operator *(Color c2) {
var result = new Color(red * c2.red, green * c2.green, blue * c2.blue);
return result;
}

Color multiplyScalar(double f) {
var result = new Color(red * f, green * f, blue * f);
return result;
}

Color blend(Color c2, double w) {
var result = this.multiplyScalar(1.0 - w) + c2.multiplyScalar(w);
return result;
}

int brightness() {
var r = (this.red * 255).toInt();
var g = (this.green * 255).toInt();
var b = (this.blue * 255).toInt();
return (r * 77 + g * 150 + b * 29) >> 8;
}

String toString() {
var r = (this.red * 255).toInt();
var g = (this.green * 255).toInt();
var b = (this.blue * 255).toInt();

return 'rgb($r,$g,$b)';
}
}
192 changes: 192 additions & 0 deletions pkgs/benchmark_harness/example/RayTraceOO/dart/engine.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
// The ray tracer code in this file is written by Adam Burmister. It
// is available in its original form from:
//
// http://labs.flog.co.nz/raytracer/
//
// Ported from the v8 benchmark suite by Google 2012.
part of ray_trace;

class IntersectionInfo {
bool isHit = false;
int hitCount = 0;
var shape, position, normal, color, distance;

IntersectionInfo() {
this.color = new Color(0.0, 0.0, 0.0);
}

String toString() => 'Intersection [$position]';
}


class Engine {
int canvasWidth;
int canvasHeight;
int pixelWidth, pixelHeight;
bool renderDiffuse, renderShadows, renderHighlights, renderReflections;
int rayDepth;
var canvas;

Engine({this.canvasWidth : 100, this.canvasHeight : 100,
this.pixelWidth : 2, this.pixelHeight : 2,
this.renderDiffuse : false, this.renderShadows : false,
this.renderHighlights : false, this.renderReflections : false,
this.rayDepth : 2}) {
canvasHeight = canvasHeight ~/ pixelHeight;
canvasWidth = canvasWidth ~/ pixelWidth;
}

void setPixel(int x, int y, Color color){
var pxW, pxH;
pxW = this.pixelWidth;
pxH = this.pixelHeight;

if (this.canvas != null) {
this.canvas.fillStyle = color.toString();
this.canvas.fillRect(x * pxW, y * pxH, pxW, pxH);
} else {
if (x == y) {
checkNumber += color.brightness();
}
}
}

// 'canvas' can be null if raytracer runs as benchmark
void renderScene(Scene scene, canvas) {
checkNumber = 0;
/* Get canvas */
this.canvas = canvas == null ? null : canvas.getContext("2d");

var canvasHeight = this.canvasHeight;
var canvasWidth = this.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);
this.setPixel(x, y, this.getPixelColor(ray, scene));
}
}
if ((canvas == null) && (checkNumber != 2321)) {
// Used for benchmarking.
throw "Scene rendered incorrectly";
}
}

Color getPixelColor(Ray ray, Scene 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;
}

IntersectionInfo testIntersection(Ray ray, Scene scene, BaseShape exclude) {
int hits = 0;
IntersectionInfo best = new IntersectionInfo();
best.distance = 2000;

for(var i=0; i < scene.shapes.length; i++){
var shape = scene.shapes[i];

if(shape != exclude){
IntersectionInfo info = shape.intersect(ray);
if (info.isHit &&
(info.distance >= 0) &&
(info.distance < best.distance)){
best = info;
hits++;
}
}
}
best.hitCount = hits;
return best;
}

Ray getReflectionRay(Vector P, Vector N, Vector V){
var c1 = -N.dot(V);
var R1 = N.multiplyScalar(2*c1) + V;
return new Ray(P, R1);
}

Color rayTrace(IntersectionInfo info, Ray ray, Scene scene, int depth) {
// Calc ambient
Color color = info.color.multiplyScalar(scene.background.ambience);
var oldColor = color;
var shininess = 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 = (light.position - info.position).normalize();

if (this.renderDiffuse) {
var L = v.dot(info.normal);
if (L > 0.0) {
color = color + info.color * light.color.multiplyScalar(L);
}
}

// The greater the depth the more accurate the colours, but
// this is exponentially (!) expensive
if (depth <= this.rayDepth) {
// calculate reflection ray
if (this.renderReflections && info.shape.material.reflection > 0) {
var reflectionRay = this.getReflectionRay(info.position,
info.normal,
ray.direction);
var refl = this.testIntersection(reflectionRay, scene, info.shape);

if (refl.isHit && refl.distance > 0){
refl.color = this.rayTrace(refl, reflectionRay, scene, depth + 1);
} else {
refl.color = scene.background.color;
}

color = color.blend(refl.color, info.shape.material.reflection);
}
// Refraction
/* TODO */
}
/* Render shadows and highlights */

IntersectionInfo shadowInfo = new IntersectionInfo();

if (this.renderShadows) {
var shadowRay = new Ray(info.position, v);

shadowInfo = this.testIntersection(shadowRay, scene, info.shape);
if (shadowInfo.isHit &&
shadowInfo.shape != info.shape
/*&& shadowInfo.shape.type != 'PLANE'*/) {
var vA = color.multiplyScalar(0.5);
var dB = (0.5 * pow(shadowInfo.shape.material.transparency, 0.5));
color = vA.addScalar(dB);
}
}
// Phong specular highlights
if (this.renderHighlights &&
!shadowInfo.isHit &&
(info.shape.material.gloss > 0)) {
var Lv = (info.shape.position - light.position).normalize();

var E = (scene.camera.position - info.shape.position).normalize();

var H = (E - Lv).normalize();

var glossWeight = pow(max(info.normal.dot(H), 0), shininess);
color = light.color.multiplyScalar(glossWeight) + color;
}
}
color.limit();
return color;
}

String toString() {
return 'Engine [canvasWidth: $canvasWidth, canvasHeight: $canvasHeight]';
}
}
65 changes: 65 additions & 0 deletions pkgs/benchmark_harness/example/RayTraceOO/dart/materials.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// The ray tracer code in this file is written by Adam Burmister. It
// is available in its original form from:
//
// http://labs.flog.co.nz/raytracer/
//
// Ported from the v8 benchmark suite by Google 2012.
part of ray_trace;

abstract class Materials {
final gloss; // [0...infinity] 0 = matt
final transparency; // 0=opaque
final reflection; // [0...infinity] 0 = no reflection
var refraction = 0.50;
var hasTexture = false;

Materials(this.reflection, this.transparency, this.gloss);

Color getColor(num u, num v);

wrapUp(t) {
t = t % 2.0;
if(t < -1) t += 2.0;
if(t >= 1) t -= 2.0;
return t;
}
}


class Chessboard extends Materials {
var colorEven, colorOdd, density;

Chessboard(this.colorEven,
this.colorOdd,
reflection,
transparency,
gloss,
this.density) : super(reflection, transparency, gloss) {
this.hasTexture = true;
}

Color getColor(num u, num v) {
var t = this.wrapUp(u * this.density) * this.wrapUp(v * this.density);

if (t < 0.0) {
return this.colorEven;
} else {
return this.colorOdd;
}
}
}


class Solid extends Materials {
var color;

Solid(this.color, reflection, refraction, transparency, gloss)
: super(reflection, transparency, gloss) {
this.hasTexture = false;
this.refraction = refraction;
}

Color getColor(num u, num v) {
return this.color;
}
}
Loading

0 comments on commit 898af0e

Please sign in to comment.