Esempio n. 1
0
    def lighting(
        self,
        eyev: Vector,
        normalv: Vector,
        point: Point,
        light: PointLight,
        inShadow: bool = False,
    ):
        diffuse = Color(0, 0, 0)
        specular = Color(0, 0, 0)
        effective_color = self.color * light.intensity
        ambient = effective_color * self.ambient
        if inShadow:
            return ambient

        lightv = (light.position - point).normalize()
        light_dot_normal = lightv.dot(normalv)
        if light_dot_normal >= 0:
            diffuse = effective_color * self.diffuse * light_dot_normal
            reflectv = -lightv.reflect(normalv)
            reflect_dot_eye = reflectv.dot(eyev)
            if reflect_dot_eye > 0:
                factor = pow(reflect_dot_eye, self.shininess)
                specular = light.intensity * self.specular * factor

        return ambient + diffuse + specular
Esempio n. 2
0
 def reflected_color(self, comps, remaining: int = MAXBOUNCE) -> Color:
     if remaining < 1:
         return Color(0, 0, 0)
     if comps.object.material.reflective == 0:
         return Color(0, 0, 0)
     reflect_ray = Ray(comps.over_point, comps.reflectv)
     color = self.color_at(reflect_ray, remaining - 1)
     return color * comps.object.material.reflective
Esempio n. 3
0
def test_lighting_eye_in_path():  # eye in reflection path
    s = Sphere()
    m = Material()
    p = Point(0, 0, 0)
    eyev = Vector(0, -math.sqrt(2) / 2, -math.sqrt(2) / 2)
    normalv = Vector(0, 0, -1)
    light = PointLight(Point(0, 10, -10), Color(1, 1, 1))
    res = m.lighting(s, light, p, eyev, normalv)
    assert res == Color(1.6364, 1.6364, 1.6364)
Esempio n. 4
0
def test_lighting_eye_opposite():  # eye opposite surface, 45 offset
    s = Sphere()
    m = Material()
    p = Point(0, 0, 0)
    eyev = Vector(0, 0, -1)
    normalv = Vector(0, 0, -1)
    light = PointLight(Point(0, 10, -10), Color(1, 1, 1))
    res = m.lighting(s, light, p, eyev, normalv)
    assert res == Color(0.7364, 0.7364, 0.7364)
Esempio n. 5
0
def test_lighting_eye_offset():  # eye between light and surface, 45 offset
    s = Sphere()
    m = Material()
    p = Point(0, 0, 0)
    eyev = Vector(0, math.sqrt(2) / 2, -math.sqrt(2) / 2)
    normalv = Vector(0, 0, -1)
    light = PointLight(Point(0, 0, -10), Color(1, 1, 1))
    res = m.lighting(s, light, p, eyev, normalv)
    assert res == Color(1.0, 1.0, 1.0)
Esempio n. 6
0
def test_lighting_eye_between():  # eye between light and surface
    s = Sphere()
    m = Material()
    p = Point(0, 0, 0)
    eyev = Vector(0, 0, -1)
    normalv = Vector(0, 0, -1)
    light = PointLight(Point(0, 0, -10), Color(1, 1, 1))
    res = m.lighting(s, light, p, eyev, normalv)
    assert res == Color(1.9, 1.9, 1.9)
Esempio n. 7
0
def test_lighting_behind_surface():  # eye behind surface
    s = Sphere()
    m = Material()
    p = Point(0, 0, 0)
    eyev = Vector(0, 0, -1)
    normalv = Vector(0, 0, -1)
    light = PointLight(Point(0, 0, 10), Color(1, 1, 1))
    res = m.lighting(s, light, p, eyev, normalv)
    assert res == Color(0.1, 0.1, 0.1)
Esempio n. 8
0
def test_inside_intersection_shading():
    w = World.default()
    w.light = PointLight(Point(0, 0.25, 0), Color(1, 1, 1))
    r = Ray(Point(0, 0, 0), Vector(0, 0, 1))
    shape = w.objects[1]
    i = Intersection(0.5, shape)
    comps = i.prepare_computation(r)
    c = w.shade_hit(comps)
    assert c == Color(0.90498, 0.90498, 0.90498)
Esempio n. 9
0
def test_surface_shadow():
    s = Sphere()
    m = Material()
    p = Point(0, 0, 0)
    eyev = Vector(0, 0, -1)
    normalv = Vector(0, 0, -1)
    light = PointLight(Point(0, 0, -10), Color(1, 1, 1))
    in_shadow = True
    result = m.lighting(s, light, p, eyev, normalv, in_shadow)
    assert result == Color(0.1, 0.1, 0.1)
Esempio n. 10
0
def test_ppm():
    c = Canvas(5, 3)
    c1 = Color(1.5, 0, 0)
    c2 = Color(0, 0.5, 0)
    c3 = Color(-0.5, 0, 1)
    c.write_pixel(0, 0, c1)
    c.write_pixel(2, 1, c2)
    c.write_pixel(4, 2, c3)
    assert (
        "255 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n0 0 0 0 0 0 0 128 0 0 0 0 0 0 0\n0 0 0 0 0 0 0 0 0 0 0 0 0 0 255"
        in c.to_ppm()
    )
Esempio n. 11
0
 def default(cls):
     world = cls()
     world.light = PointLight(Point(-10, 10, -10), Color(1, 1, 1))
     m = Material()
     m.color = Color(0.8, 1.0, 0.6)
     m.diffuse = 0.7
     m.specular = 0.2
     s1 = Sphere()
     s1.set_material(m)
     s2 = Sphere()
     s2.set_transform(Scaling(0.5, 0.5, 0.5))
     world.objects.extend([s1, s2])
     return world
Esempio n. 12
0
def test_shadow_shade_hit():
    w = World()
    w.light = PointLight(Point(0, 0, -10), Color(1, 1, 1))
    s1 = Sphere()
    s2 = Sphere()
    s2.set_transform(Translation(0, 0, 10))
    w.objects.extend([s1, s2])
    r = Ray(Point(0, 0, 5), Vector(0, 0, 1))
    i = Intersection(4, s2)
    comps = i.prepare_computation(r)
    c = w.shade_hit(comps)
    print(c)
    assert c == Color(0.1, 0.1, 0.1)
Esempio n. 13
0
def test_lighting_pattern():
    s = Sphere()
    m = Material()
    m.pattern = StripePattern(Color(1, 1, 1), Color(0, 0, 0))
    m.ambient = 1
    m.diffuse = 0
    m.specular = 0
    eyev = Vector(0, 0, -1)
    normalv = Vector(0, 0, -1)
    light = PointLight(Point(0, 0, -10), Color(1, 1, 1))
    c1 = m.lighting(s, light, Point(0.9, 0, 0), eyev, normalv, False)
    c2 = m.lighting(s, light, Point(1.1, 0, 0), eyev, normalv, False)
    assert c1 == Color(1, 1, 1)
    assert c2 == Color(0, 0, 0)
Esempio n. 14
0
def test_default_world():
    light = PointLight(Point(-10, 10, -10), Color(1, 1, 1))
    s1 = Sphere()
    m = Material()
    m.color = Color(0.8, 1.0, 0.6)
    m.diffuse = 0.7
    m.specular = 0.2
    s1.set_material(m)
    s2 = Sphere()
    t = Scaling(0.5, 0.5, 0.5)
    s2.set_transform(t)
    w = World.default()
    assert w.light == light
    assert s1 in w.objects
    assert s2 in w.objects
Esempio n. 15
0
 def color_at(self, ray: Ray, remaining: int = MAXBOUNCE) -> Color:
     xs = self.intersect(ray)
     hit = xs.hit()
     if hit is None:
         return Color(0, 0, 0)
     else:
         return self.shade_hit(hit.prepare_computation(ray, xs), remaining)
Esempio n. 16
0
def test_default_material():
    m = Material()
    assert m.color == Color(1, 1, 1)
    assert m.ambient == 0.1
    assert m.diffuse == 0.9
    assert m.specular == 0.9
    assert m.shininess == 200
Esempio n. 17
0
def test_canvas():
    c = Canvas(10, 20)
    assert c.width == 10
    assert c.height == 20
    for row in c.pixels:
        for pixel in row:
            assert pixel == Color(0, 0, 0)
Esempio n. 18
0
 def test_pixel_data(self):
     canvas = Canvas(5, 3)
     c1 = Color(1.5, 0, 0)
     c2 = Color(0, 0.5, 0)
     c3 = Color(-0.5, 0, 1)
     canvas.write_pixel(0, 0, c1)
     canvas.write_pixel(2, 1, c2)
     canvas.write_pixel(4, 2, c3)
     ppm = canvas.to_ppm()
     pixel_data = [s.strip() for s in ppm.splitlines()][3:6]
     expected_data = [
         "255 0 0 0 0 0 0 0 0 0 0 0 0 0 0",
         "0 0 0 0 0 0 0 128 0 0 0 0 0 0 0",
         "0 0 0 0 0 0 0 0 0 0 0 0 0 0 255",
     ]
     self.assertEqual(pixel_data, expected_data)
Esempio n. 19
0
def test_both_transform():
    s = Sphere()
    s.set_transform(Scaling(2, 2, 2))
    pattern = _TestPattern()
    pattern.set_pattern_transform(Translation(0.5, 1, 1.5))
    c = pattern.pattern_at_shape(s, Point(2.5, 3, 3.5))
    assert c == Color(0.75, 0.5, 0.25)
Esempio n. 20
0
def shade_hit_transparent():
    w = World().default()
    floor = Plane()
    floor.set_transform(Translation(0, -1, 0))
    floor.material.transparency = 0.5
    floor.material.refractive_index = 1.5
    w.objects.append(floor)
    ball = Sphere()
    ball.material.color = Color(1, 0, 0)
    ball.material.ambient = 0.5
    ball.set_transform(Translation(0, -3.5, -0.5))
    w.objects.append(ball)
    r = Ray(Point(0, 0, -3), Vector(0, -math.sqrt(2) / 2, math.sqrt(2) / 2))
    xs = Intersections(Intersection(math.sqrt(2), floor))
    comps = xs[0].prepare_computations(r, xs)
    color = w.shade_hit(comps, 5)
    assert color == Color(0.93642, 0.68642, 0.68642)
Esempio n. 21
0
def test_intersection_shading():
    w = World.default()
    r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
    shape = w.objects[0]
    i = Intersection(4, shape)
    comps = i.prepare_computation(r)
    c = w.shade_hit(comps)
    assert c == Color(0.38066, 0.47583, 0.2855)
Esempio n. 22
0
 def test_creation(self):
     canvas = Canvas(10, 20)
     self.assertEqual(canvas.width, 10)
     self.assertEqual(canvas.height, 20)
     black = Color(0, 0, 0)
     for row in canvas.pixels:
         for elem in row:
             self.assertEqual(elem, black)
Esempio n. 23
0
def test_refracted_opaque():
    w = World().default()
    s = w.objects[0]
    r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
    xs = Intersections(Intersection(4, s), Intersection(6, s))
    comps = xs[0].prepare_computation(r, xs)
    c = w.refracted_color(comps, 5)
    assert c == Color(0, 0, 0)
Esempio n. 24
0
def test_render():
    w = World.default()
    c = Camera(11, 11, math.pi / 2)
    f = Point(0, 0, -5)
    to = Point(0, 0, 0)
    up = Vector(0, 1, 0)
    c.transform = ViewTransform(f, to, up)
    image = c.render(w)
    assert image.read_pixel(5, 5) == Color(0.38066, 0.47583, 0.2855)
Esempio n. 25
0
def test_reflected_color_nonreflective():
    w = World().default()
    r = Ray(Point(0, 0, 0), Vector(0, 0, 1))
    s = w.objects[0]
    s.material.ambient = 1
    i = Intersection(1, s)
    comps = i.prepare_computation(r)
    c = w.reflected_color(comps)
    assert c == Color(0, 0, 0)
Esempio n. 26
0
    def refracted_color(self, comps, remaining: int = MAXBOUNCE) -> Color:
        if remaining < 1:
            return Color(0, 0, 0)
        if comps.object.material.transparency == 0:
            return Color(0, 0, 0)

        n_ratio = comps.n1 / comps.n2
        cos_i = comps.eyev.dot(comps.normalv)
        sin2_t = (n_ratio**2) * (1 - (cos_i**2))
        if sin2_t > 1:
            return Color(0, 0, 0)

        cos_t = math.sqrt(1.0 - sin2_t)
        direction = comps.normalv * (n_ratio * cos_i -
                                     cos_t) - comps.eyev * n_ratio
        refract_ray = Ray(comps.under_point, direction)
        color = (self.color_at(refract_ray, remaining - 1) *
                 comps.object.material.transparency)
        return color
Esempio n. 27
0
def test_refracted_max_depth():
    w = World().default()
    s = w.objects[0]
    s.material.transparency = 1.0
    s.material.refractive_index = 1.5
    r = Ray(Point(0, 0, -5), Vector(0, 0, 1))
    xs = Intersections(Intersection(4, s), Intersection(6, s))
    comps = xs[0].prepare_computation(r, xs)
    c = w.refracted_color(comps, 0)
    assert c == Color(0, 0, 0)
Esempio n. 28
0
 def test_line_length(self):
     canvas = Canvas(10, 2, Color(1, 0.8, 0.6))
     ppm = canvas.to_ppm()
     pixel_data = [s.strip() for s in ppm.splitlines()][3:7]
     expected_data = [
         "255 204 153 255 204 153 255 204 153 255 204 153 255 204 153 255 204",
         "153 255 204 153 255 204 153 255 204 153 255 204 153",
         "255 204 153 255 204 153 255 204 153 255 204 153 255 204 153 255 204",
         "153 255 204 153 255 204 153 255 204 153 255 204 153",
     ]
     self.assertEqual(pixel_data, expected_data)
Esempio n. 29
0
def test_shade_hit_reflective():
    w = World().default()
    s = Plane()
    s.material.reflective = 0.5
    s.set_transform(Translation(0, -1, 0))
    w.objects.append(s)
    r = Ray(Point(0, 0, -3), Vector(0, -math.sqrt(2) / 2, math.sqrt(2) / 2))
    i = Intersection(math.sqrt(2), s)
    comps = i.prepare_computation(r)
    c = w.shade_hit(comps)
    assert c == Color(0.87677, 0.92436, 0.82918)
Esempio n. 30
0
def test_maximum_recursion_depth_color_at():
    w = World().default()
    s = Plane()
    s.material.reflective = 0.5
    s.set_transform(Translation(0, -1, 0))
    w.objects.append(s)
    r = Ray(Point(0, 0, -3), Vector(0, -math.sqrt(2) / 2, math.sqrt(2) / 2))
    i = Intersection(math.sqrt(2), s)
    comps = i.prepare_computation(r)
    color = w.reflected_color(comps, 0)
    assert color == Color(0, 0, 0)