예제 #1
0
파일: Color.php 프로젝트: michaelprem/phc
 /**
  * 
  *
  * @param RayTracer_Color $c1
  * @param RayTracer_Color $c2
  * @param float $w
  * @return unknown
  */
 public static 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;
 }
예제 #2
0
파일: Engine.php 프로젝트: michaelprem/phc
 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) {
                 $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;
 }