def color(ray: Ray, world: HittableList) -> Vec3:
    hit_attempt: Optional[HitRecord] = world.hit(ray, 0.0, sys.float_info.max)
    if hit_attempt is not None:
        return 0.5 * Vec3(hit_attempt.normal.x + 1, hit_attempt.normal.y + 1,
                          hit_attempt.normal.z + 1)
    else:
        unit_direction: Vec3 = ray.direction.unit_vector()
        t: float = 0.5 * (unit_direction.y + 1)
        return ((1.0 - t) * UNIT_VEC3) + (t * Vec3(0.5, 0.7, 1.0))
Beispiel #2
0
def color(ray: Ray, world: HittableList) -> Vec3:
    # Some reflected rays hit not at zero but at some near-zero value due to
    # floating point shennanigans. So we try to compensate for that.
    hit_attempt: Optional[HitRecord] = world.hit(ray, 0.001,
                                                 sys.float_info.max)
    if hit_attempt is not None:
        target: Vec3 = hit_attempt.p + hit_attempt.normal + random_unit_sphere_point(
        )
        # FIXME mmm recursion
        # reflector_rate * reflected_color
        # So in this case, the matterial is a 50% reflector.
        return 0.5 * color(Ray(hit_attempt.p, target - hit_attempt.p), world)
    else:
        unit_direction: Vec3 = ray.direction.unit_vector()
        t: float = 0.5 * (unit_direction.y + 1)
        return ((1.0 - t) * UNIT_VEC3) + (t * Vec3(0.5, 0.7, 1.0))
def color(ray: Ray, world: HittableList, depth: int = 0) -> Vec3:
    # Some reflected rays hit not at zero but at some near-zero value due to
    # floating point shennanigans. So we try to compensate for that.
    hit_attempt: Optional[HitRecord] = world.hit(ray, 0.001,
                                                 sys.float_info.max)
    if hit_attempt is not None:
        reflection: ReflectionRecord = hit_attempt.material.scatter(
            ray, hit_attempt)
        if depth < 50 and reflection is not None:
            return reflection.attenuation * color(reflection.scattering, world,
                                                  depth + 1)
        else:
            return Vec3(0, 0, 0)
    else:
        unit_direction: Vec3 = ray.direction.unit_vector()
        t: float = 0.5 * (unit_direction.y + 1)
        return ((1.0 - t) * UNIT_VEC3) + (t * Vec3(0.5, 0.7, 1.0))
def color(ray: Ray, world: HittableList, depth: int) -> Vec3:
    # Some reflected rays hit not at zero but at some near-zero value due to
    # floating point shennanigans. So we try to compensate for that.
    hit_attempt: Optional[HitRecord] = world.hit(ray, 0.001, sys.float_info.max)
    if hit_attempt is not None:
        scattering: ReflectionRecord = hit_attempt.material.scatter(ray, hit_attempt)
        # FIXME Is it really worthwhile to check if reflection is not None here?
        # All our Materials assume that a hit has been made, and therefore some
        # reflection should happen (unless it is Vanta).
        if depth < 50 and scattering is not None:
            # Compare this with the hard-coded reflection in 6_matterial.
            return scattering.attenuation * color(scattering.scattering, world, depth + 1)
        else:
            return Vec3(0, 0, 0)
    else:
        unit_direction: Vec3 = ray.direction.unit_vector()
        t: float = 0.5 * (unit_direction.y + 1)
        return ((1.0 - t) * UNIT_VEC3) + (t * Vec3(0.5, 0.7, 1.0))
                                                  depth + 1)
        else:
            return Vec3(0, 0, 0)
    else:
        unit_direction: Vec3 = ray.direction.unit_vector()
        t: float = 0.5 * (unit_direction.y + 1)
        return ((1.0 - t) * UNIT_VEC3) + (t * Vec3(0.5, 0.7, 1.0))


if __name__ == "__main__":
    width: int = 1200
    height: int = 800
    sampling_size: int = 10
    ppm: PPM = PPM(width, height)
    spam: List[Hittable] = random_scene(-11, 11, -11, 11)
    world = HittableList(spam)
    print(spam)

    lookfrom: Vec3 = Vec3(9, -2, -1)
    lookat: Vec3 = Vec3(-4, 1, 0)
    focus_distance: float = 10.0
    aperture: float = 0.1

    camera: Camera = PositionableCamera(lookfrom, lookat, Vec3(0, 1, 0), 20,
                                        width / height, aperture,
                                        focus_distance)

    for j in range(height - 1, -1, -1):
        for i in range(width):
            #print("Tracing on row %s, col %s" % (j, i))
            accumulator: Vec3 = Vec3(0, 0, 0)
if __name__ == "__main__":
    width = 400
    height = 200
    sampling_size = 200
    ppm: PPM = PPM(width, height)
    lower_left_corner: Vec3 = Vec3(-2, -1, -1)
    h_movement: Vec3 = Vec3(4, 0, 0)
    v_movement: Vec3 = Vec3(0, 2, 0)
    origin: Vec3 = Vec3(0, 0, 0)
    cam = Camera(lower_left_corner, h_movement, v_movement, origin)

    hittables: List[Hittable] = [
        Sphere(Vec3(0, 0, -1), 0.5),
        Sphere(Vec3(0, -100.5, -1), 100)
    ]
    world: HittableList = HittableList(hittables)

    for j in range(height - 1, -1, -1):
        for i in range(width):
            print("Tracing on row %s, col %s" % (j, i))
            print("antialiasing...", end="")
            accumulator: Vec3 = Vec3(0, 0, 0)
            for sample in range(sampling_size):
                # In this instance, instead of u and v being mere ratios to
                # our distance from the edges, they feature a random "jitter"
                # which we use to sample the pixels around our current pixel.
                # In this sense, the current pixel is a combination of its
                # surroundings.
                u: float = float(i + random.random()) / float(width)
                v: float = float(j + random.random()) / float(height)
                r: Ray = cam.get_ray(u, v)