Exemplo n.º 1
0
 def get_ray(self, s, t, sample):
     rd = Vector3.random_in_unit_disk(s, t, sample) * self.lens_radius
     # rd = Vector3.concentric_sample_disk(s*2-1, t*2-1) * self.lens_radius
     offset = self.u * rd.x + self.v * rd.y
     return Ray(
         self.origin + offset,
         self.lower_left_corner + self.horizontal*s + self.vertical*t - self.origin - offset)
Exemplo n.º 2
0
    def __init__(self, pos, t):
        self.pos = pos
        self.normal = Vector3(0, 0, 0)
        self.t = t
        self.material = None

        self.front_face = False
Exemplo n.º 3
0
 def scatter(self, r_in, rec):
     reflected = Vector3.reflect(r_in.direction.normalized(), rec.normal)
     # Catch degenerate scatter direction
     if reflected.near_zero():
         reflected = rec.normal
     scattered = Ray(rec.pos, reflected)
     attenuation = self.albedo
     return scattered.direction.dot(rec.normal) > 0, scattered, attenuation
Exemplo n.º 4
0
    def scatter(self, r_in, rec):
        scatter_direction = rec.normal + Vector3.random_unit_vector()

        # Catch degenerate scatter direction
        if scatter_direction.near_zero():
            scatter_direction = rec.normal

        scattered = Ray(rec.pos, scatter_direction)
        attenuation = self.albedo
        return True, scattered, attenuation
Exemplo n.º 5
0
    def hit(self, r, t_min, t_max, recc=None):
        temp_rec = HitRecord(Vector3(0, 0, 0), 0.0)
        hit_anything = False
        closest_so_far = t_max
        rec = None
        for obj in self.objects:
            if obj.hit(r, t_min, closest_so_far, temp_rec):
                hit_anything = True
                closest_so_far = temp_rec.t
                rec = temp_rec

        return hit_anything, rec
Exemplo n.º 6
0
def ray_colour(r, background, world, depth):
    hit, rec = world.hit(r, 0.001, utils.INFINITY)

    if depth <= 0:
        return Vector3(0, 0, 0)

    if not hit:
        return background

    emitted = rec.material.emitted()
    result, scattered, attenuation = rec.material.scatter(r, rec)
    if not result:
        return emitted

    return emitted + attenuation.mul(ray_colour(scattered, background, world, depth-1))
Exemplo n.º 7
0
 def scatter(self, r_in, rec):
     return True, Ray(Vector3(0, 0, 0),
                      Vector3(0, 0, 0)), HitRecord(Vector3(0, 0, 0), 0.0)
Exemplo n.º 8
0
 def emitted(self):
     return Vector3(0, 0, 0)
Exemplo n.º 9
0
def main():
    # Image
    aspect_ratio = 16.0 / 9.0
    image_width = 256
    image_height = image_width/aspect_ratio
    background = Vector3(0, 0, 0)
    samples_per_pixel = 20
    max_depth = 1

    # World
    world = HittableList()

    # material_ground = Lambertian(Vector3(0.8, 0.8, 0.0))
    # material_center = Lambertian(Vector3(0.7, 0.3, 0.3))
    # material_left = Metal(Vector3(0.8, 0.8, 0.8))
    material_emissive = DiffuseLight(Vector3(1,1,1), Vector3(1,1,1))
    # material_right = Metal(Vector3(0.8, 0.6, 0.2))

    # world.append(Sphere(Vector3(0, 0, -1), 0.5, material_center))
    # world.append(Sphere(Vector3(1, 0.5, -0.5), 1, material_emissive))
    # world.append(Sphere(Vector3(-1, 0, -1), 0.5, material_right))
    # world.append(Sphere(Vector3(0, -100.5, -1), 100, material_ground))
    sphere_count = 35
    sphere_dist = 100
    for i in range(0, sphere_count):
        world.append(Sphere(Vector3(utils.rand_range(-50, 50), utils.rand_range(-40, 40),
                                    sphere_dist),
                            1,
                            material_emissive))

    # Camera
    look_from = Vector3(0, 0, 0)
    look_at = Vector3(0, 0, 1)
    v_up = Vector3(0, 1, 0)
    dist_to_focus = (look_from - look_at).length()
    f_stop = 8
    aperture = 1/f_stop
    cam = Camera(look_from, look_at, v_up, 30.0, aspect_ratio, aperture, dist_to_focus)

    # Render
    render_data = list()
    print("Commencing Rendering.")
    start_time = datetime.now()
    for j in reversed(range(0, int(image_height))):
        print("Scanlines remaining: %s" % j)
        for i in range(0, image_width):
            pixel_colour = Vector3(0, 0, 0)
            for s in range(0, samples_per_pixel):
                u = (i + utils.rand()) / (image_width-1)
                v = (j + utils.rand()) / (image_height-1)
                r = cam.get_ray(u, v, s)
                pixel_colour += ray_colour(r, background, world, max_depth)
            render_data.append(colour.write_colour(pixel_colour, samples_per_pixel))
    print("\nDone.\nTime Spent: %s" % (datetime.now() - start_time))

    file = image.write_image(
        width=image_width,
        height=image_height,
        data=render_data
    )
    return file