예제 #1
0
    def scatter(self, r_in: Ray, rec: hit_record):
        reflected: np.ndarray = reflect(r_in.direction(), rec.normal)
        attenuation = np.array((1, 1, 1), float)
        if np.dot(r_in.direction(), rec.normal) > 0:
            outward_normal = -rec.normal
            ni_over_nt = self.ref_idx
            cosine = self.ref_idx * np.dot(r_in.direction(),
                                           rec.normal) / np.linalg.norm(
                                               r_in.direction())

        else:
            outward_normal = rec.normal
            ni_over_nt = 1.0 / self.ref_idx
            cosine = float(-np.dot(r_in.direction(), rec.normal) /
                           np.linalg.norm(r_in.direction()))

        has_refracted, refracted = refract(r_in.direction(), outward_normal,
                                           ni_over_nt)
        if has_refracted:
            reflect_prob = schlick(cosine, self.ref_idx)

        else:
            reflect_prob = 1

        if random() < reflect_prob:
            scattered = Ray(rec.p, reflected, r_in.time())

        else:
            scattered = Ray(rec.p, refracted, r_in.time())

        return True, attenuation, scattered
예제 #2
0
    def hit(self, r: Ray, t_min: float, t_max: float):
        oc = r.origin() - self.center(r.time())
        a = np.dot(r.direction(), r.direction())
        b = np.dot(oc, r.direction())
        c = np.dot(oc, oc) - self.radius * self.radius
        discriminant = b * b - a * c

        if discriminant > 0:
            temp = (-b - sqrt(b * b - a * c)) / a
            if (temp < t_max) and (temp > t_min):
                t = float(temp)
                p = r.point_at_parameter(t)
                normal = (p - self.center(r.time())) / self.radius
                u, v = get_shpere_uv((p - self.center(r.time())) / self.radius)
                rec = hit_record(t, p, normal, self.material, u, v)
                return True, rec

            temp = (-b + sqrt(b * b - a * c)) / a
            if (temp < t_max) and (temp > t_min):
                t = float(temp)
                p = r.point_at_parameter(t)
                normal = (p - self.center(r.time())) / self.radius
                u, v = get_shpere_uv((p - self.center(r.time())) / self.radius)
                rec = hit_record(t, p, normal, self.material, u, v)
                return True, rec

        return False, None
예제 #3
0
    def scatter(self, r_in: Ray, rec: hit_record):
        unit_direction = r_in.direction() / np.linalg.norm(r_in.direction())

        reflected: np.ndarray = reflect(unit_direction, rec.normal)
        scattered = Ray(rec.p, reflected + self.fuzz * random_in_unit_sphere(),
                        r_in.time())
        attenuation = self.albedo
        return (np.dot(scattered.direction(), rec.normal) >
                0), attenuation, scattered
예제 #4
0
    def scatter(self, r_in: Ray, rec: hit_record):
        target: np.ndarray = rec.p + rec.normal + random_in_unit_sphere()
        scattered = Ray(rec.p, target - rec.p, r_in.time())
        attenuation = self.albedo.value(rec.u, rec.v, rec.p)
        # attenuation = np.array((0.5, 0.5, 0.5))
        # print("rin: " + str(r_in))

        if type(self.albedo) == noise_texture:
            print("attenuation: " + str(attenuation))
            print("scatter: " + str(scattered))

        return True, attenuation, scattered