def __init__(self, intersection, ray: rays.Ray, all_intersections=None): self.t = intersection.t self.object = intersection.shape self.point = ray.position(self.t) self.eyev = -ray.direction self.normalv = intersection.shape.normal_at(self.point) self.inside = False if self.normalv.dot(self.eyev) < 0: # If the dot product of the eye vector and normal is negative, they # are pointing away from each other, which means you're inside of # the object. self.inside = True self.normalv = -self.normalv # This is the point just a tiny bit above the surface, used to avoid # rounding errors self.over_point = self.point + self.normalv * EPSILON # And this one is a tiny bit under the surface to avoid rounding errors self.under_point = self.point - self.normalv * EPSILON self.reflectv = ray.direction.reflect(self.normalv) self.n1 = 1.0 self.n2 = 1.0 if all_intersections is not None: containers: List[Any] = [] for isection in all_intersections.intersections: if isection == intersection: if len(containers) == 0: self.n1 = 1.0 else: self.n1 = containers[-1].material.refractive_index if isection.shape in containers: containers.remove(isection.shape) else: containers.append(isection.shape) if isection == intersection: if len(containers) == 0: self.n2 = 1.0 else: self.n2 = containers[-1].material.refractive_index break self.schlick = self.compute_schlick()