function traceRay(&$ray, &$light) { $p = $this->intersect($ray, new IntersectionPoint(INFINITY, new Vector(0.0, 0.0, 0.0))); if (is_infinite($p->distance)) { return 0.0; } $greyscale = -1.0 * $p->normal->dot($light); if ($greyscale <= 0.0) { return 0.0; } $rayOrigin = $ray->origin; $scaledDirection = $ray->direction->scaledBy($p->distance); $scaledNormal = $p->normal->scaledBy(EPSILON); $o = $rayOrigin->plus($scaledDirection); $o = $o->plus($scaledNormal); $v = new Vector(0.0, 0.0, 0.0); $shadowRay = new Ray($o, $v->minus($light)); $shadowp = $this->intersect($shadowRay, new IntersectionPoint(INFINITY, $p->normal)); if (is_infinite($shadowp->distance)) { return $greyscale; } else { return 0.0; } }
public function addLight(Color $col, Light $light, Vector $pos, Scene $scene, Thing $thing, Vector $reflectDir, Vector $norm) { $ldis = Vector::minus($light->pos, $pos); $livec = Vector::norm($ldis); $neatIsect = $this->testRay(new Ray($pos, $livec), $scene); $isInShadow = $neatIsect != null && $neatIsect <= Vector::mag($ldis); if ($isInShadow) { return $col; } $illum = Vector::dot($livec, $norm); $lcolor = Color::$defaultColor; if ($illum > 0) { $lcolor = Color::scale($illum, $light->color); } $specular = Vector::dot($livec, Vector::norm($reflectDir)); $scolor = Color::$defaultColor; $surface = $thing->surface(); if ($specular > 0) { $scolor = Color::scale(pow($specular, $surface->roughness()), $light->color); } return Color::plus($col, Color::plus(Color::times($surface->diffuse($pos), $lcolor), Color::times($surface->specular($pos), $scolor))); }