def consume_color(width, height, cam, world, max_depth, samples_per_pixel, queue, coord): pixel_color = Color(0.0, 0.0, 0.0) j, i = coord queue.put(height - j) for _ in range(1, samples_per_pixel + 1): u = (i + random_double()) / (width - 1) v = (j + random_double()) / (height - 1) ray = cam.get_ray(u, v) pixel_color += ray_color(ray, world, max_depth) return pixel_color
def random_scene() -> HittableList: world = HittableList() ground_material = Lambertian(albedo=Color(0.5, 0.5, 0.5)) world.add(Sphere(Point3(0.0, -1000.0, 0.0), 1000.0, ground_material)) for a, b in itertools.product(range(-11, 11), range(-11, 11)): choose_mat = random_double() center = Point3(a + 0.9 * random_double(), 0.2, b + 0.9 * random_double()) if (center - Point3(4.0, 0.2, 0.0)).length > 0.9: if choose_mat < 0.8: # diffuse albedo = Color.random() * Color.random() sphere_material = Lambertian(albedo) elif choose_mat < 0.95: # metal albedo = Color.random(0.5, 1.0) fuzz = random_double(0.0, 0.5) sphere_material = Metal(albedo, fuzz) else: # glass sphere_material = Dielectric(1.5) world.add(Sphere(center, 0.2, sphere_material)) material_1 = Dielectric(1.5) world.add(Sphere(Point3(0.0, 1.0, 0.0), 1.0, material_1)) material_2 = Lambertian(Color(0.4, 0.2, 0.1)) world.add(Sphere(Point3(-4.0, 1.0, 0.0), 1.0, material_2)) material_3 = Metal(Color(0.7, 0.6, 0.5), 0.0) world.add(Sphere(Point3(4.0, 1.0, 0.0), 1.0, material_3)) return world
def scatter( self, r_in: Ray, rec: "HitRecord") -> typing.Union[typing.Tuple[Ray, Color], None]: attenuation = Color(1.0, 1.0, 1.0) etai_over_etat = 1.0 / self.ref_idx if rec.front_face is True else self.ref_idx unit_direction = unit_vector(r_in.direction) cos_theta = min(dot(-unit_direction, rec.normal), 1.0) sin_theta = pow(1.0 - pow(cos_theta, 2), 0.5) reflect_prob = schlick(cos_theta, etai_over_etat) if etai_over_etat * sin_theta > 1.0 or random_double() < reflect_prob: direction = reflect(unit_direction, rec.normal) else: direction = refract(unit_direction, rec.normal, etai_over_etat) scattered = Ray(rec.p, direction) return scattered, attenuation
def random_in_unit_disk() -> Vec3: while True: p = Vec3(random_double(-1, 1), random_double(-1, 1), 0) if p.length_squared >= 1: continue return p
def random_unit_vector() -> Vec3: a = random_double(0.0, 2 * math.pi) z = random_double(-1, 1) r = pow(1 - pow(z, 2), 0.5) return Vec3(r * math.cos(a), r * math.sin(a), z)