Esempio n. 1
0
    def schlick(self, incident: 'Vector3', normal: 'Vector3', n1: 'float',
                n2: 'float'):
        r0 = (n1 - n2) / (n1 + n2)
        r0 *= r0
        cosX = Vector3.dot(normal, incident)
        if n1 > n2:
            n = n1 / n2
            sinT2 = n * n * (1.0 - cosX * cosX)
            if sinT2 > 1.0:
                return 1.0
            cosX = math.sqrt(1.0 - sinT2)

        x = 1.0 - cosX
        return r0 + (1.0 - r0) * math.pow(x, 5)
Esempio n. 2
0
    def trilineart_interp(self, c, u, v, w):
        uu = u * u * (3 - 2 * u)
        vv = v * v * (3 - 2 * v)
        ww = w * w * (3 - 2 * w)

        accum = 0
        for i in range(2):
            for j in range(2):
                for k in range(2):
                    weight_v = Vector3(u - i, v - j, w - k)
                    accum += (i * uu + (1 - i) * (1 - uu)) * \
                             (j * vv + (1 - j) * (1 - vv)) * \
                             (k * ww + (1 - k) * (1 - ww)) * Vector3.dot(c[i * 2 + j * 2 + k], weight_v)
        return accum
Esempio n. 3
0
    def hit(self, ray: Ray, t_min: float, t_max: float) -> (bool, HitRecord):
        """Checks if the ray 'ray' hits with the sphere between t_min and t_max.
        Returns true if there is a collision, false otherwise.
        Return the hitRecord information if the collision is true.
        """
        current_center = self.get_center(t=ray.time)

        oc = ray.origin - current_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(b * b - a * c)) / a
            if t_max > temp > t_min:
                record = HitRecord()
                record.t = temp
                record.hit_point = ray.point_at_parameter(record.t)
                record.hit_point_normal = (record.hit_point -
                                           current_center) / self._radius
                record.u, record.v = self.get_sphere_uv(p=record.hit_point)
                record.material = self._material
                return True, record
            temp = (-b + math.sqrt(b * b - a * c)) / a
            if t_max > temp > t_min:
                record = HitRecord()
                record.t = temp
                record.hit_point = ray.point_at_parameter(record.t)
                record.hit_point_normal = (record.hit_point -
                                           current_center) / self._radius
                record.u, record.v = self.get_sphere_uv(p=record.hit_point)
                record.material = self._material
                return True, record

        return False, None
Esempio n. 4
0
 def value(self, direction: Vector3) -> float:
     cosine = Vector3.dot(Vector3.normalize(direction), self._uvw.w())
     if cosine > 0:
         return cosine / math.pi
     else:
         return 0