예제 #1
0
def scan_frame(world: HittableList, cam: Camera, image_width: int,
               image_height: int, max_depth: int) -> Vec3List:
    length = image_width * image_height
    i_list = cp.tile(cp.arange(image_width), image_height)
    j_list = cp.concatenate(
        cp.transpose(cp.tile(cp.arange(image_height), (image_width, 1))))
    u: cp.ndarray = (random_float_list(length) + i_list) / (image_width - 1)
    v: cp.ndarray = (random_float_list(length) + j_list) / (image_height - 1)
    r: RayList = cam.get_ray(u, v)
    return ray_color_loop(r, world, max_depth)
예제 #2
0
 def random_in_unit_sphere_list(size: int) -> Vec3List:
     u = random_float_list(size)
     v = random_float_list(size)
     theta = u * 2 * cp.pi
     phi = cp.arccos(2 * v - 1)
     r = cp.cbrt(random_float_list(size))
     sinTheta = cp.sin(theta)
     cosTheta = cp.cos(theta)
     sinPhi = cp.sin(phi)
     cosPhi = cp.cos(phi)
     x = r * sinPhi * cosTheta
     y = r * sinPhi * sinTheta
     z = r * cosPhi
     return Vec3List(cp.transpose(cp.array([x, y, z])))
예제 #3
0
    def scatter(self, r_in: RayList, rec: HitRecordList) \
            -> Tuple[RayList, Vec3List]:
        etai_over_etat = cp.where(
            rec.front_face, 1 / self.ref_idx, self.ref_idx
        )

        unit_direction = r_in.direction().unit_vector()
        cos_theta = -unit_direction @ rec.normal
        cos_theta = cp.where(cos_theta > 1, 1, cos_theta)
        sin_theta = cp.sqrt(1 - cos_theta**2)
        reflect_prob = self.schlick(cos_theta, etai_over_etat)

        reflect_condition = (
            (etai_over_etat * sin_theta > 1)
            | (random_float_list(len(r_in)) < reflect_prob)
        )
        # total internal reflection
        reflected = (unit_direction.mul_ndarray(reflect_condition)).reflect(
            rec.normal.mul_ndarray(reflect_condition)
        )
        # refraction
        refracted = (unit_direction.mul_ndarray(~reflect_condition)).refract(
            rec.normal.mul_ndarray(~reflect_condition), etai_over_etat
        )
        direction = reflected + refracted

        condition = rec.t > 0
        scattered = RayList(
            rec.p.mul_ndarray(condition),
            direction.mul_ndarray(condition)
        )
        attenuation = Vec3List.from_array(condition) * Color(1, 1, 1)
        return scattered, attenuation
예제 #4
0
def scan_line(j: int, world: HittableList, cam: Camera, image_width: int,
              image_height: int, samples_per_pixel: int,
              max_depth: int) -> Img:
    img = Img(image_width, 1)
    row_pixel_color = Vec3List.from_vec3(Color(), image_width)

    for s in range(samples_per_pixel):
        u: np.ndarray = (random_float_list(image_width) +
                         np.arange(image_width)) / (image_width - 1)
        v: np.ndarray = (random_float_list(image_width) + j) / (image_height -
                                                                1)
        r: RayList = cam.get_ray(u, v)
        row_pixel_color += ray_color(r, world, max_depth)

    img.write_pixel_list(0, row_pixel_color, samples_per_pixel)
    return img
예제 #5
0
 def random(_min: float = 0, _max: float = 1) -> Vec3:
     return Vec3(*random_float_list(3, _min, _max))
예제 #6
0
 def random_in_unit_disk(size: int) -> cp.ndarray:
     r = cp.sqrt(random_float_list(size))
     theta = random_float_list(size) * 2 * cp.pi
     return cp.array([r * cp.cos(theta), r * cp.sin(theta)])
예제 #7
0
 def random_unit_vector(size: int) -> Vec3List:
     a = random_float_list(size, 0, 2 * cp.pi)
     z = random_float_list(size, -1, 1)
     r = cp.sqrt(1 - z**2)
     return Vec3List(
         cp.transpose(cp.array([r * cp.cos(a), r * cp.sin(a), z])))