cvs: php-benchmarks /raytracer Background.php Camera.php Color.php Engine.php IntersectionInfo.php Light.php Ray.php Scene.php Vector.php base.php
raytrace.php /raytracer/Material BaseMaterial.php Chessboard.php Solid.php /raytracer/Shape BaseShape.php Plane.php Sphere.php

From: Date: Tue, 28 Apr 2009 09:52:12 +0000
Subject: cvs: php-benchmarks /raytracer Background.php Camera.php Color.php Engine.php IntersectionInfo.php Light.php Ray.php Scene.php Vector.php base.php
raytrace.php /raytracer/Material BaseMaterial.php Chessboard.php Solid.php /raytracer/Shape BaseShape.php Plane.php Sphere.php
Groups: php.qa 
Request: Send a blank email to php-qa+get-64809@lists.php.net to get a copy of this message
pbiggar Tue Apr 28 09:52:12 2009 UTC Added files: /php-benchmarks/raytracer Background.php Camera.php Color.php Engine.php IntersectionInfo.php Light.php Ray.php Scene.php Vector.php base.php raytrace.php /php-benchmarks/raytracer/Material BaseMaterial.php Chessboard.php Solid.php /php-benchmarks/raytracer/Shape BaseShape.php Plane.php Sphere.php Log: Add raytracer benchmark, contributed by Davide Mendolia. I've only given this a quick glance, so reviewers are welcome.

http://cvs.php.net/viewvc.cgi/php-benchmarks/raytracer/Background.php?view=markup&rev=1.1 Index: php-benchmarks/raytracer/Background.php +++ php-benchmarks/raytracer/Background.php <?php class RayTracer_Background { public $color = null; public $ambience = 0.0; /** * * * @param RayTracer_Color $color * @param float $ambience */ public function __construct(RayTracer_Color $color, $ambience) { $this->color = $color; $this->ambience = $ambience; } } http://cvs.php.net/viewvc.cgi/php-benchmarks/raytracer/Camera.php?view=markup&rev=1.1 Index: php-benchmarks/raytracer/Camera.php +++ php-benchmarks/raytracer/Camera.php <?php class RayTracer_Camera { public $position = null; public $lookAt = null; public $equator = null; public $up = null; public $screen = null; public function __construct(RayTracer_Vector $pos, RayTracer_Vector $lookAt, RayTracer_Vector $up) { $this->up = $up->normalize(); $this->position = $pos; $this->lookAt = $lookAt; $this->equator = $lookAt->normalize()->cross($this->up); $this->screen = RayTracer_Vector::add($this->position, $this->lookAt); } public function getRay($vx, $vy) { $pos = RayTracer_Vector::subtract( $this->screen, RayTracer_Vector::subtract( RayTracer_Vector::multiplyScalar($this->equator, $vx), RayTracer_Vector::multiplyScalar($this->up, $vy) ) ); $pos->y = $pos->y * -1; $dir = RayTracer_Vector::subtract( $pos, $this->position ); require_once 'Ray.php'; $ray = new RayTracer_Ray($pos, $dir->normalize()); return $ray; } public function __toString() { return 'Ray []'; } } http://cvs.php.net/viewvc.cgi/php-benchmarks/raytracer/Color.php?view=markup&rev=1.1 Index: php-benchmarks/raytracer/Color.php +++ php-benchmarks/raytracer/Color.php <?php class RayTracer_Color { public $red = 0.0; public $green = 0.0; public $blue = 0.0; public function __construct($r = 0.0, $g = 0.0, $b = 0.0) { $this->red = $r; $this->green = $g; $this->blue = $b; } public static function add(RayTracer_Color $c1, RayTracer_Color $c2) { $result = new RayTracer_Color(0,0,0); $result->red = $c1->red + $c2->red; $result->green = $c1->green + $c2->green; $result->blue = $c1->blue + $c2->blue; return $result; } /** * * * @param RayTracer_Color $c1 * @param float $s * @return RayTracer_Color */ public static function addScalar(RayTracer_Color $c1, $s) { $result = new RayTracer_Color(0,0,0); $result->red = $c1->red + $s; $result->green = $c1->green + $s; $result->blue = $c1->blue + $s; $result->limit(); return $result; } public static function subtract(RayTracer_Color $c1, RayTracer_Color $c2) { $result = new RayTracer_Color(0,0,0); $result->red = $c1->red - $c2->red; $result->green = $c1->green - $c2->green; $result->blue = $c1->blue - $c2->blue; return $result; } public static function multiply(RayTracer_Color $c1, RayTracer_Color $c2) { $result = new RayTracer_Color(0,0,0); $result->red = $c1->red * $c2->red; $result->green = $c1->green * $c2->green; $result->blue = $c1->blue * $c2->blue; return $result; } /** * * * @param RayTracer_Color $c1 * @param float $f * @return RayTracer_Color */ public static function multiplyScalar(RayTracer_Color $c1, $f) { $result = new RayTracer_Color(0,0,0); $result->red = $c1->red * $f; $result->green = $c1->green * $f; $result->blue = $c1->blue * $f; return $result; } /** * * * @param RayTracer_Color $c1 * @param float $f * @return Raytracer_Color */ public static function divideFactor(RayTracer_Color $c1, $f) { $result = new RayTracer_Color(0,0,0); $result->red = $c1->red / $f; $result->green = $c1->green / $f; $result->blue = $c1->blue / $f; return $result; } public function 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; } public function distance(RayTracer_Color $color) { $d = abs($this->red - $color->red) + abs($this->green - $color->green) + abs($this->blue - $color->blue); return $d; } /** * * * @param RayTracer_Color $c1 * @param RayTracer_Color $c2 * @param float $w * @return unknown */ public function blend(RayTracer_Color $c1, RayTracer_Color $c2, $w) { $result = RayTracer_Color::add( RayTracer_Color::multiplyScalar($c1, 1 - $w), RayTracer_Color::multiplyScalar($c2, $w) ); return $result; } public function brightness() { $r = floor($this->red*255); $g = floor($this->green*255); $b = floor($this->blue*255); return ($r * 77 + $g * 150 + $b * 29) >> 8; } public function __toString() { $r = floor($this->red*255); $g = floor($this->green*255); $b = floor($this->blue*255); return "rgb("+ $r +","+ $g +","+ $b +")"; } } http://cvs.php.net/viewvc.cgi/php-benchmarks/raytracer/Engine.php?view=markup&rev=1.1 Index: php-benchmarks/raytracer/Engine.php +++ php-benchmarks/raytracer/Engine.php <?php class RayTracer_Engine { public $canvas = null; /* 2d context we can render to */ public function __construct($options = array()) { $this->options = array_merge(array( 'canvasHeight' => 100, 'canvasWidth'=> 100, 'pixelWidth'=> 2, 'pixelHeight'=> 2, 'renderDiffuse'=> false, 'renderShadows'=> false, 'renderHighlights'=> false, 'renderReflections'=> false, 'rayDepth'=> 2 ), $options); $this->options['canvasHeight'] /= $this->options['pixelHeight']; $this->options['canvasWidth'] /= $this->options['pixelWidth']; /* TODO: dynamically include other scripts */ } public function setPixel($x, $y, RayTracer_Color $color){ $pxW = $this->options['pixelWidth']; $pxH = $this->options['pixelHeight']; if ($this->canvas) { $colorId = imagecolorallocate($this->canvas, $color->red*255, $color->green*255, $color->blue*255); $x1 = $x * $pxW; $y1 = $y * $pxH; imagefilledrectangle($this->canvas, $x1, $y1, $x1 + $pxW, $y1 + $pxH, $colorId); /* $this->canvas->fillStyle = $color->__toString(); $this->canvas->fillRect ($x * $pxW, $y * $pxH, $pxW, $pxH); */ } else { if ($x === $y) { $this->checkNumber += $color->brightness(); } //echo $x * $pxW, $y * $pxH, $pxW, $pxH, PHP_EOL; } } public function renderScene(RayTracer_Scene $scene, $canvas) { $this->checkNumber = 0; /* Get canvas */ if ($canvas) { // $this->canvas = $canvas->getContext("2d"); $this->canvas = $canvas; } else { $this->canvas = null; } $canvasHeight = $this->options['canvasHeight']; $canvasWidth = $this->options['canvasWidth']; for($y=0; $y < $canvasHeight; $y++) { for($x=0; $x < $canvasWidth; $x++) { $yp = $y * 1.0 / $canvasHeight * 2 - 1; $xp = $x * 1.0 / $canvasWidth * 2 - 1; $ray = $scene->camera->getRay($xp, $yp); $color = $this->getPixelColor($ray, $scene); $this->setPixel($x, $y, $color); } } /* if ($this->checkNumber !== 2321) { var_dump($this->checkNumber); throw new Exception("Scene rendered incorrectly"); }*/ } public function getPixelColor($ray, $scene) { $info = $this->testIntersection($ray, $scene, null); if ($info->isHit) { $color = $this->rayTrace($info, $ray, $scene, 0); return $color; } return $scene->background->color; } public function testIntersection($ray, $scene, $exclude) { $hits = 0; require_once 'IntersectionInfo.php'; $best = new RayTracer_IntersectionInfo(); $best->distance = PHP_INT_MAX * 1.0; foreach ($scene->shapes as $shape) { //@var $shape Raytracer_BaseShape if ($shape != $exclude) { $info = $shape->intersect($ray); if ($info->isHit && $info->distance >= 0 && $info->distance < $best->distance) { $best = $info; $hits++; } } } $best->hitCount = $hits; return $best; } public function getReflectionRay($P, $N, $V) { $c1 = -$N->dot($V); $R1 = RayTracer_Vector::add( RayTracer_Vector::multiplyScalar($N, 2*$c1), $V ); return new Raytracer_Ray($P, $R1); } public function rayTrace(RayTracer_IntersectionInfo $info, RayTracer_Ray $ray, RayTracer_Scene $scene, $depth) { // Calc ambient $color = RayTracer_Color::multiplyScalar($info->color, $scene->background->ambience); $shininess = pow(10, $info->shape->material->gloss + 1); foreach ($scene->lights as $light) { // Calc diffuse lighting $v = RayTracer_Vector::subtract( $light->position, $info->position )->normalize(); if ($this->options['renderDiffuse']) { $L = $v->dot($info->normal); if ($L > 0.0) { $color = RayTracer_Color::add( $color, RayTracer_Color::multiply( $info->color, RayTracer_Color::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) { $reflectionRay = $this->getReflectionRay($info->position, $info->normal, $ray->direction); $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 = RayTracer_Color::blend( $color, $refl->color, $info->shape->material->reflection ); } // Refraction /* TODO */ } /* Render shadows and highlights */ $shadowInfo = new RayTracer_IntersectionInfo(); if($this->options['renderShadows']){ $shadowRay = new RayTracer_Ray($info->position, $v); $shadowInfo = $this->testIntersection($shadowRay, $scene, $info->shape); if($shadowInfo->isHit && $shadowInfo->shape != $info->shape /*&& shadowInfo.shape.type != 'PLANE'*/){ $vA = RayTracer_Color::multiplyScalar($color, 0.5); $dB = (0.5 * pow($shadowInfo->shape->material->transparency, 0.5)); $color = RayTracer_Color::addScalar($vA, $dB); } } // Phong specular highlights if($this->options['renderHighlights'] && !$shadowInfo->isHit && $info->shape->material->gloss > 0){ $Lv = RayTracer_Vector::subtract( $info->shape->position, $light->position )->normalize(); $E = RayTracer_Vector::subtract( $scene->camera->position, $info->shape->position )->normalize(); $H = RayTracer_Vector::subtract( $E, $Lv )->normalize(); $glossWeight = pow(max($info->normal->dot($H), 0), $shininess); $color = RayTracer_Color::add( RayTracer_Color::multiplyScalar($light->color, $glossWeight), $color ); } } $color->limit(); return $color; } } http://cvs.php.net/viewvc.cgi/php-benchmarks/raytracer/IntersectionInfo.php?view=markup&rev=1.1 Index: php-benchmarks/raytracer/IntersectionInfo.php +++ php-benchmarks/raytracer/IntersectionInfo.php <?php class RayTracer_IntersectionInfo { public $isHit = false; public $hitCount = 0; public $shape = null; public $position = null; public $normal = null; public $color = null; public $distance = null; public function __construct() { $this->color = new RayTracer_Color(0,0,0); } public function __toString() { return 'Intersection [' . $this->position . ']'; } } http://cvs.php.net/viewvc.cgi/php-benchmarks/raytracer/Light.php?view=markup&rev=1.1 Index: php-benchmarks/raytracer/Light.php +++ php-benchmarks/raytracer/Light.php <?php class RayTracer_Light { public $position = null; public $color = null; public $intensity = 10.0; /** * * * @param RayTracer_Vector $pos * @param RayTracer_Color $color * @param float $intensity */ public function __construct(RayTracer_Vector $pos, RayTracer_Color $color, $intensity = 10.0) { $this->position = $pos; $this->color = $color; $this->intensity = $intensity; } //TODO Review public function getIntensity($distance){ if($distance >= $this->intensity) return 0; return pow(($this->intensity - $distance) / $strength, 0.2); } public function __toString() { return 'Light [' . $this->position.x + ',' . $this->position->y + ',' . $this->position->z . ']'; } } http://cvs.php.net/viewvc.cgi/php-benchmarks/raytracer/Ray.php?view=markup&rev=1.1 Index: php-benchmarks/raytracer/Ray.php +++ php-benchmarks/raytracer/Ray.php <?php class RayTracer_Ray { public $position = null; public $direction = null; public function __construct(RayTracer_Vector $pos, RayTracer_Vector $dir) { $this->position = $pos; $this->direction = $dir; } public function __toString() { return 'Ray [' . $this->position + ',' . $this->direction + ']'; } } http://cvs.php.net/viewvc.cgi/php-benchmarks/raytracer/Scene.php?view=markup&rev=1.1 Index: php-benchmarks/raytracer/Scene.php +++ php-benchmarks/raytracer/Scene.php <?php class RayTracer_Scene { public $camera = null; /** * * @var array */ public $shapes; /** * * @var array */ public $lights; public $background = null; public function __construct() { require_once 'Camera.php'; require_once 'Vector.php'; $this->camera = new RayTracer_Camera( new RayTracer_Vector(0,0,-5), new RayTracer_Vector(0,0,1), new RayTracer_Vector(0,1,0) ); $this->shapes = array(); $this->lights = array(); require_once 'Background.php'; require_once 'Color.php'; $this->background = new RayTracer_Background(new RayTracer_Color(0,0,0.5), 0.2); } } http://cvs.php.net/viewvc.cgi/php-benchmarks/raytracer/Vector.php?view=markup&rev=1.1 Index: php-benchmarks/raytracer/Vector.php +++ php-benchmarks/raytracer/Vector.php <?php class RayTracer_Vector { public $x = 0.0; public $y = 0.0; public $z = 0.0; /** * * * @param float $x * @param float $y * @param float $z */ public function __construct($x = 0.0, $y = 0.0, $z = 0.0) { $this->x = $x; $this->y = $y; $this->z = $z; } public function copy(RayTracer_Vector $vector){ $this->x = $vector->x; $this->y = $vector->y; $this->z = $vector->z; } public function normalize() { $m = $this->magnitude(); return new RayTracer_Vector($this->x / $m, $this->y / $m, $this->z / $m); } public function magnitude() { return sqrt(($this->x * $this->x) + ($this->y * $this->y) + ($this->z * $this->z)); } public function cross(RayTracer_Vector $w) { return new RayTracer_Vector( -$this->z * $w->y + $this->y * $w->z, $this->z * $w->x - $this->x * $w->z, -$this->y * $w->x + $this->x * $w->y ); } public function dot(RayTracer_Vector $w) { return $this->x * $w->x + $this->y * $w->y + $this->z * $w->z; } public static function add(RayTracer_Vector $v, RayTracer_Vector $w) { return new RayTracer_Vector($w->x + $v->x, $w->y + $v->y, $w->z + $v->z); } public static function subtract(RayTracer_Vector $v, RayTracer_Vector $w) { return new RayTracer_Vector($v->x - $w->x, $v->y - $w->y, $v->z - $w->z); } public static function multiplyVector(RayTracer_Vector $v, RayTracer_Vector $w) { return new RayTracer_Vector($v->x * $w->x, $v->y * $w->y, $v->z * $w->z); } /** * * * @param RayTracer_Vector $v * @param float $w * @return RayTracer_Vector */ public static function multiplyScalar(RayTracer_Vector $v, $w) { return new RayTracer_Vector($v->x * $w, $v->y * $w, $v->z * $w); } public function __toString() { return 'Vector [' . $this->x . ',' . $this->y . ',' . $this->z . ']'; } } http://cvs.php.net/viewvc.cgi/php-benchmarks/raytracer/base.php?view=markup&rev=1.1 Index: php-benchmarks/raytracer/base.php +++ php-benchmarks/raytracer/base.php <?php // Suites of benchmarks consist of a name and the set of benchmarks in // addition to the reference timing that the final score will be based // on. This way, all scores are relative to a reference run and higher // scores implies better performance. function BenchmarkSuite(name, reference, benchmarks) { this.name = name; this.reference = reference; this.benchmarks = benchmarks; BenchmarkSuite.suites.push(this); } // Keep track of all declared benchmark suites. BenchmarkSuite.suites = []; // Scores are not comparable across versions. Bump the version if // you're making changes that will affect that scores, e.g. if you add // a new benchmark or change an existing one. BenchmarkSuite.version = '3'; http://cvs.php.net/viewvc.cgi/php-benchmarks/raytracer/raytrace.php?view=markup&rev=1.1 Index: php-benchmarks/raytracer/raytrace.php +++ php-benchmarks/raytracer/raytrace.php <?php function renderScene(){ require_once 'Scene.php'; $scene = new RayTracer_Scene(); $scene->camera = new RayTracer_Camera( new RayTracer_Vector(0, 0, -15), new RayTracer_Vector(-0.2, 0, 5), new RayTracer_Vector(0, 1, 0) ); $scene->background = new RayTracer_Background( new RayTracer_Color(0.5, 0.5, 0.5), 0.4 ); require_once 'Shape/Sphere.php'; require_once 'Material/Solid.php'; $sphere = new RayTracer_Shape_Sphere( new RayTracer_Vector(-1.5, 1.5, 2), 1.5, new RayTracer_Material_Solid( new RayTracer_Color(0,0.5,0.5), 0.3, 0.0, 0.0, 2.0 ) ); $sphere1 = new RayTracer_Shape_Sphere( new RayTracer_Vector(1, 0.25, 1), 0.5, new RayTracer_Material_Solid( new RayTracer_Color(0.9,0.9,0.9), 0.1, 0.0, 0.0, 1.5 ) ); $v = new RayTracer_Vector(0.1, 0.9, -0.5); require_once 'Shape/Plane.php'; require_once 'Material/Chessboard.php'; $plane = new RayTracer_Shape_Plane( $v->normalize(), 1.2, new RayTracer_Material_Chessboard( new RayTracer_Color(1.0, 1.0, 1.0), new RayTracer_Color(0.0, 0.0, 0.0), 0.2, 0.0, 1.0, 0.7 ) ); $scene->shapes[] = $plane; $scene->shapes[] = $sphere; $scene->shapes[] = $sphere1; require_once 'Light.php'; $light = new RayTracer_Light( new RayTracer_Vector(5, 10, -1), new RayTracer_Color(0.8, 0.8, 0.8) ); $light1 = new RayTracer_Light( new RayTracer_Vector(-3, 5, -15), new RayTracer_Color(0.8, 0.8, 0.8), 100 ); $scene->lights[] = $light; $scene->lights[] = $light1; $imageWidth = 100; // $F('imageWidth'); $imageHeight = 100; // $F('imageHeight'); $pixelSize = split(',', "5,5"); // $F('pixelSize').split(','); $renderDiffuse = true; // $F('renderDiffuse'); $renderShadows = true; // $F('renderShadows'); $renderHighlights = true; // $F('renderHighlights'); $renderReflections = true; // $F('renderReflections'); $rayDepth = 2;//$F('rayDepth'); require_once 'Engine.php'; $raytracer = new RayTracer_Engine( array( "canvasWidth" => $imageWidth, "canvasHeight" => $imageHeight, "pixelWidth" => $pixelSize[0], "pixelHeight" => $pixelSize[1], "renderDiffuse" => $renderDiffuse, "renderHighlights" => $renderHighlights, "renderShadows" => $renderShadows, "renderReflections" => $renderReflections, "rayDepth" => $rayDepth ) ); // Create a 55x30 image //$im = imagecreatetruecolor(500, 500); $im = null; $raytracer->renderScene($scene, $im, 0); /* // Save the image imagepng($im, './imagefilledrectangle.png'); imagedestroy($im); */ } $elapsed = 0; $start = microtime(true); for ($i = 0;$i<6; $i++){ renderScene(); } $usec = microtime(true) - $start; echo ($usec * 1000).'ms'. PHP_EOL; /* var RayTrace = new BenchmarkSuite('RayTrace', 932666, [ new Benchmark('RayTrace', renderScene) ]); var checkNumber; */ /*Execute at minimum 1 second the benchmark*/ /* $elapsed = 0; $start = microtime(true) * 1000; for ($n = 0;$elapsed < 1000; $n++) { renderScene(); $elapsed = (microtime(true) * 1000) - $start; } $usec = ($elapsed * 1000) / $n; echo ($usec). PHP_EOL; // Computes the geometric mean of a set of numbers. function GeometricMean($numbers) { $log = 0; foreach ($numbers as $number) { $log += log($number); } return pow(M_E, $log / count($numbers)); } $reference = 932666; $mean = GeometricMean(array($usec)); echo "score : ". (100 *($reference / $mean));*/ http://cvs.php.net/viewvc.cgi/php-benchmarks/raytracer/Material/BaseMaterial.php?view=markup&rev=1.1 Index: php-benchmarks/raytracer/Material/BaseMaterial.php +++ php-benchmarks/raytracer/Material/BaseMaterial.php <?php abstract class RayTracer_Material_BaseMaterial { public $gloss = 2.0; // [0...infinity] 0 = matt public $transparency = 0.0; // 0=opaque public $reflection = 0.0; // [0...infinity] 0 = no reflection public $refraction = 0.50; public $hasTexture = false; public function __construct() { } /** * * * @param float $u * @param float $v * return RayTracer_Color */ abstract public function getColor($u, $v); public function wrapUp($t) { $t = fmod($t, 2.0); if($t < -1) $t += 2.0; if($t >= 1) $t -= 2.0; return $t; } public function __toString() { return 'Material [gloss=' . $this->gloss . ', transparency=' . $this->transparency . ', hasTexture=' . $this->hasTexture .']'; } } http://cvs.php.net/viewvc.cgi/php-benchmarks/raytracer/Material/Chessboard.php?view=markup&rev=1.1 Index: php-benchmarks/raytracer/Material/Chessboard.php +++ php-benchmarks/raytracer/Material/Chessboard.php <?php class RayTracer_Material_Chessboard extends RayTracer_Material_BaseMaterial { public $colorEven = null; public $colorOdd = null; public $density = 0.5; public function __construct($colorEven, $colorOdd, $reflection, $transparency, $gloss, $density) { $this->colorEven = $colorEven; $this->colorOdd = $colorOdd; $this->reflection = $reflection; $this->transparency = $transparency; $this->gloss = $gloss; $this->density = $density; $this->hasTexture = true; } public function getColor($u, $v) { $t = $this->wrapUp($u * $this->density) * $this->wrapUp($v * $this->density); if($t < 0.0) return $this->colorEven; else return $this->colorOdd; } public function __toString() { return 'ChessMaterial [gloss=' . $this->gloss . ', transparency=' . $this->transparency . ', hasTexture=' . $this->hasTexture .']'; } } http://cvs.php.net/viewvc.cgi/php-benchmarks/raytracer/Material/Solid.php?view=markup&rev=1.1 Index: php-benchmarks/raytracer/Material/Solid.php +++ php-benchmarks/raytracer/Material/Solid.php <?php require_once 'Material/BaseMaterial.php'; class RayTracer_Material_Solid extends RayTracer_Material_BaseMaterial { public function __construct($color, $reflection, $refraction, $transparency, $gloss) { $this->color = $color; $this->reflection = $reflection; $this->transparency = $transparency; $this->gloss = $gloss; $this->hasTexture = false; } public function getColor($u, $v){ return $this->color; } public function __toString() { return 'SolidMaterial [gloss=' . $this->gloss . ', transparency=' . $this->transparency . ', hasTexture=' . $this->hasTexture .']'; } } http://cvs.php.net/viewvc.cgi/php-benchmarks/raytracer/Shape/BaseShape.php?view=markup&rev=1.1 Index: php-benchmarks/raytracer/Shape/BaseShape.php +++ php-benchmarks/raytracer/Shape/BaseShape.php <?php class RayTracer_Shape_BaseShape { /** * * * @var RayTracer_Vector */ public $position = null; /** * * * @var RayTracer_Material_BaseMaterial */ public $material = null; public function __construct() { $this->position = new RayTracer_Vector(0.0, 0.0, 0.0); $this->material = new RayTracer_Material_Solid( new RayTracer_Color(1.0, 0.0, 1.0), 0.0, 0.0, 0.0 ); } public function __toString() { return 'Material [gloss=' . $this->gloss . ', transparency=' . $this->transparency . ', hasTexture=' . $this->hasTexture .']'; } } http://cvs.php.net/viewvc.cgi/php-benchmarks/raytracer/Shape/Plane.php?view=markup&rev=1.1 Index: php-benchmarks/raytracer/Shape/Plane.php +++ php-benchmarks/raytracer/Shape/Plane.php <?php require_once 'Shape/BaseShape.php'; class RayTracer_Shape_Plane extends RayTracer_Shape_BaseShape { private $d = 0.0; public function __construct(RayTracer_Vector $pos, $d, RayTracer_Material_BaseMaterial $material) { $this->position = $pos; $this->d = $d; $this->material = $material; } public function intersect($ray) { $info = new RayTracer_IntersectionInfo(); $Vd = $this->position->dot($ray->direction); if($Vd == 0) return $info; // no intersection $t = -($this->position->dot($ray->position) + $this->d) / $Vd; if($t <= 0) return $info; $info->shape = $this; $info->isHit = true; $info->position = RayTracer_Vector::add( $ray->position, RayTracer_Vector::multiplyScalar( $ray->direction, $t ) ); $info->normal = $this->position; $info->distance = $t; if($this->material->hasTexture){ $vU = new RayTracer_Vector($this->position->y, $this->position->z, -$this->position->x); $vV = $vU->cross($this->position); $u = $info->position->dot($vU); $v = $info->position->dot($vV); $info->color = $this->material->getColor($u, $v); } else { $info->color = $this->material->getColor(0,0); } return $info; } public function __toString() { return 'Plane [' . $this->position . ', d=' . $this->d . ']'; } } http://cvs.php.net/viewvc.cgi/php-benchmarks/raytracer/Shape/Sphere.php?view=markup&rev=1.1 Index: php-benchmarks/raytracer/Shape/Sphere.php +++ php-benchmarks/raytracer/Shape/Sphere.php <?php class RayTracer_Shape_Sphere { /** * * * @param RayTracer_Vector $pos * @param float $radius * @param RayTracer_Material_BaseMaterial $material */ public function __construct(RayTracer_Vector $pos, $radius, RayTracer_Material_BaseMaterial $material) { $this->radius = $radius; $this->position = $pos; $this->material = $material; } public function intersect($ray) { $info = new RayTracer_IntersectionInfo(); $info->shape = $this; $dst = RayTracer_Vector::subtract($ray->position, $this->position); $B = $dst->dot($ray->direction); $C = $dst->dot($dst) - ($this->radius * $this->radius); $D = ($B * $B) - $C; if($D > 0){ // intersection! $info->isHit = true; $info->distance = (-$B) - sqrt($D); $info->position = RayTracer_Vector::add( $ray->position, RayTracer_Vector::multiplyScalar( $ray->direction, $info->distance ) ); $info->normal = RayTracer_Vector::subtract( $info->position, $this->position )->normalize(); $info->color = $this->material->getColor(0,0); } else { $info->isHit = false; } return $info; } public function __toString() { return 'Sphere [position=' . $this->position . ', radius=' . $this->radius . ']'; } }
« previous php.qa (#64809) next »