Example #1
0
    def scatter(self, ray_in: Ray, hit_record: hit_record):
        outward_normal = Vector3(1, 1, 1)
        reflected = ray_in.direction().reflect(hit_record.normal)
        ni_over_nt = 0
        attenuation = Vector3(1, 1, 1)
        scattered = Vector3(0, 0, 0)
        reflect_prob = 0
        cosine = 0

        if (ray_in.direction().dot(hit_record.normal) > 0):
            outward_normal = Vector3(0, 0, 0) - hit_record.normal
            ni_over_nt = self.ref_idx
            cosine = self.ref_idx * ray_in.direction().dot(
                hit_record.normal) / ray_in.direction().length()
        else:
            outward_normal = hit_record.normal
            ni_over_nt = 1 / self.ref_idx
            cosine = -ray_in.direction().dot(
                hit_record.normal) / ray_in.direction().length()

        is_scattered, refracted = refract(ray_in.direction(), outward_normal,
                                          ni_over_nt)
        if (is_scattered):
            reflect_prob = schlick(cosine, self.ref_idx)
        else:
            scattered = Ray(hit_record.p, reflected)
            reflect_prob = 1.0

        if (random.uniform(0, 1) < reflect_prob):
            scattered = Ray(hit_record.p, reflected)
        else:
            scattered = Ray(hit_record.p, refracted)

        return (True, scattered, attenuation)
Example #2
0
def random_in_unit_disk():
    p = Vector3(0,0,0)

    while (p.dot(p) >= 1.0):
        p = Vector3(random.uniform(0,1), random.uniform(0,1), 0).scalar_mul(2.0) - Vector3(1,1,0)

    return p
Example #3
0
def random_in_unit_sphere():
    p = Vector3(random.uniform(0, 1), random.uniform(0, 1), random.uniform(
        0, 1)).scalar_mul(2.0) - Vector3(1, 1, 1)

    while (p.squared_length() >= 1.0):
        p = Vector3(random.uniform(0, 1), random.uniform(0, 1),
                    random.uniform(0, 1)).scalar_mul(2.0) - Vector3(1, 1, 1)

    return p
Example #4
0
def refract(v: Vector3, n: Vector3, ni_over_nt: float):
    uv = v.normalize()
    dt = uv.dot(n)
    discriminant = 1.0 - ni_over_nt * ni_over_nt * (1 - dt * dt)
    if (discriminant > 0):
        refracted = (uv -
                     n.scalar_mul(dt)).scalar_mul(ni_over_nt) - n.scalar_mul(
                         math.sqrt(discriminant))
        return (True, refracted)

    return (False, Vector3(0, 0, 0))
Example #5
0
    def hit(self, ray: Ray, t_min: float, t_max: float):
        temp_rec = hit_record(0, Vector3(0, 0, 0), Vector3(0, 0, 0),
                              Material())
        hit_anything = False
        closest_so_far = t_max

        for item in self.list:
            if (item.hit(ray, t_min, closest_so_far, temp_rec)):
                hit_anything = True
                closest_so_far = temp_rec.t
                temp_rec.material = item.material

        return (hit_anything, temp_rec)
Example #6
0
 def __init__(self, lookfrom: Vector3, lookat: Vector3, vup: Vector3, fov, aspect, aperture, focus_dist):
     theta = fov * (3.145 / 180.0)
     half_height = math.tan(theta/2.0)
     half_width = aspect * half_height
     self.origin = lookfrom
     self.w = (lookfrom - lookat).normalize()
     self.u = vup.cross(self.w).normalize()
     self.v = self.w.cross(self.u)
     self.lower_left_corner = self.origin - self.u.scalar_mul(half_width) - self.v.scalar_mul(half_height * focus_dist) - self.w.scalar_mul(focus_dist)
     self.horizontal  = self.u.scalar_mul(2 * half_width * focus_dist)
     self.vertical    = self.v.scalar_mul(2 * half_height * focus_dist)
     self.lens_radius = 0.0
Example #7
0
    def hit(self, ray: Ray, t_min: float, t_max: float, rec: hit_record):
        oc = ray.origin() - self.center
        a = Vector3.dot(ray.direction(), ray.direction())
        b = Vector3.dot(oc, ray.direction())
        c = Vector3.dot(oc, oc) - self.radius * self.radius
        discriminant = b * b - a * c

        if (discriminant > 0):
            temp = (-b - math.sqrt(discriminant)) / a
            if (temp < t_max and temp > t_min):
                rec.t = temp
                rec.p = ray.point_at_parameter(rec.t)
                rec.normal = (rec.p - self.center).scalar_div(self.radius)
                return True
            temp = (-b + math.sqrt(discriminant)) / a
            if (temp < t_max and temp > t_min):
                rec.t = temp
                rec.p = ray.point_at_parameter(rec.t)
                rec.normal = (rec.p - self.center).scalar_div(self.radius)
                return True

        return False
Example #8
0
 def scatter(self, ray_in: Ray, rec):
     return (False, Ray(Vector3(0, 0, 0), Vector3(0, 0, 0)))