예제 #1
0
    def color_reflected_refracted(self, s, O, M, N, V, inside, bounces):
        to_O = vl.vnorm(O - M)

        reflect_color = np.zeros((3, 1))
        refract_color = np.zeros((3, 1))

        if (s.material.finish.transparent == False and s.material.finish.reflection == 0.) or bounces == self.num_bounces:
            return 0.

        reflect_amount = s.material.finish.reflection
        refract_amount = 0.
        
        if s.material.finish.transparent == True:
            reflect_amount = self.reflectance(s, N, V, inside)
            refract_amount = 1. - reflect_amount

        if np.any(reflect_amount > 0.):
            R = self.reflect(to_O, N)
            reflect_color = self.trace(s.geometry.intersection_point(M, N), R, bounces + 1) * reflect_amount

        if np.any(refract_amount > 0.):
            Rf = self.refract(s, V, N, inside)
            refract_color = refract_color + self.trace(s.geometry.intersection_point(M, -N), Rf, bounces + 1) * refract_amount

        return reflect_color + refract_color
예제 #2
0
def render():
    img = misc.imread('examples/checkered.png')[:, :, :3]
    # img = misc.imread('examples/face.png')[:, :, :3]

    h, w, c = img.shape

    camera = Camera(500, 500)
    sphere = Sphere([0., 0., 0.], 1.)
    camera.translate([0, 0, -2])

    t, m, n = sphere.intersection(camera.origin, camera.D)
    d_hat = vl.vnorm(m - sphere.center)
    d_x = d_hat[0:1]
    d_y = d_hat[1:2]
    d_z = d_hat[2:3]

    u = (0.5 + (np.arctan2(d_z, d_x) / (np.pi * 2)))
    v = 0.5 - (np.arcsin(d_y) / np.pi)

    img_out = img[(v * h - 1).astype(np.uint8),
                  (u * w - 1).astype(np.uint8)].squeeze()

    mask = (t < global_config.MAX_DISTANCE).T
    plt.imshow((img_out * mask).reshape(camera.height, camera.width, 3))
    plt.show()

    import ipdb
    ipdb.set_trace()
예제 #3
0
    def refract(self, s, V, N, inside):
        n1 = np.where(inside, s.material.finish.ior, 1.)  # TODO don't hardcode air as n1
        n2 = np.where(inside, 1., s.material.finish.ior)
        n = n1 / n2
        cos_i = -vl.vdot(N, V)
        sin_t2 = n * n * (1.0 - cos_i * cos_i)

        cos_t = np.sqrt(1. - sin_t2)

        return vl.vnorm(V * n + N * (n * cos_i - cos_t))
예제 #4
0
 def color_specular(self, s, N, to_L, to_O, intensity):
     if s.material.finish.specular == 0.:
         return 0.
     else:
         R = self.reflect(to_L, N)
         specular_intensity = np.maximum(vl.vdot(to_O, R), 0.)
         specular_color = np.power(specular_intensity, 1./s.material.finish.roughness) * intensity * s.material.finish.specular
         if s.material.metallic == True:
             specular_color = specular_color * vl.vnorm(s.material.surface_color)
         return specular_color
예제 #5
0
    def color_diffuse_specular(self, s, O, M, N, V):
        diffuse_color = np.zeros((3, 1))
        specular_color = np.zeros((3, 1))

        to_O = vl.vnorm(O - M)

        for light_source in self.scene.light_sources:
            if isinstance(light_source, LightSourcePoint):
                light_dir = light_source.center - M
                to_L = vl.vnorm(light_dir)
                r2 = vl.vabs(light_dir)
                intensity = light_source.emission_color * light_source.intensity / (4 * np.pi * r2)
            elif isinstance(light_source, LightSourceDirectional):
                to_L = -light_source.direction
                intensity = light_source.emission_color * light_source.intensity
            shadow_mask = self.shadow_mask(light_source, M, N, to_L)

            diffuse_color = diffuse_color + self.color_diffuse(s, N, to_L, intensity) * shadow_mask
            specular_color = specular_color + self.color_specular(s, N, to_L, to_O, intensity) * shadow_mask
        return diffuse_color + specular_color
예제 #6
0
    def light(self, s, O, V, t, M, N, bounces):
        to_O = vl.vnorm(O - M)

        inside = (vl.vdot(V, N) > 0.)

        N_hat = np.where(inside, -N, N)

        ambient_color = self.color_ambient(s)
        diffuse_specular_color = self.color_diffuse_specular(s, O, M, N_hat, V)
        reflected_refracted_color = self.color_reflected_refracted(s, O, M, N_hat, V, inside, bounces)

        return ambient_color + diffuse_specular_color + reflected_refracted_color
예제 #7
0
파일: sphere.py 프로젝트: nlintz/Raytracer
    def intersection(self, O, D):
        O_hat = vl.inverse_transform(
            self.S,
            vl.inverse_transform(self.R, vl.inverse_transform(self.T, O)))
        D_hat = vl.inverse_transform(self.S, vl.inverse_transform(self.R, D))
        a = vl.vdot(D_hat, D_hat)
        b = 2 * vl.vdot(O_hat, D_hat)
        c = vl.vdot(O_hat, O_hat) - 1
        disc = (b**2) - (4 * a * c)

        t0 = (-b - np.sqrt(np.maximum(disc, 0.))) / (2 * a)
        t1 = (-b + np.sqrt(np.maximum(disc, 0.))) / (2 * a)
        t = np.where((t0 > 0) & (t0 < t1), t0, t1)

        pred = (disc > 0.) & (t > 0.)
        t_out = np.where(pred, t, global_config.MAX_DISTANCE)
        M = (O_hat + D_hat * t_out)
        M_out = vl.transform(self.T,
                             vl.transform(self.R, vl.transform(self.S, M)))
        N_out = vl.vnorm(vl.transform(self.R, vl.inverse_transform(self.S, M)))

        return t_out, M_out, N_out
예제 #8
0
    def intersection(self, O, D):
        O_hat = vl.inverse_transform(
            self.S,
            vl.inverse_transform(self.R, vl.inverse_transform(self.T, O)))
        D_hat = vl.inverse_transform(self.S, vl.inverse_transform(self.R, D))

        xy_mask = np.array([1., 1., 0.]).reshape(-1, 1)
        O_xy = O_hat * xy_mask
        D_xy = D_hat * xy_mask

        a = vl.vdot(D_xy, D_xy)
        b = 2 * vl.vdot(D_xy, O_xy)
        c = vl.vdot(O_xy, O_xy) - 1

        disc = (b**2) - (4 * a * c)
        t0 = (-b - np.sqrt(np.maximum(disc, 0.))) / (2 * a)
        t1 = (-b + np.sqrt(np.maximum(disc, 0.))) / (2 * a)

        zo = O_hat[2:3]
        zd = D_hat[2:3]
        z0 = (zo + zd * t0)
        z1 = (zo + zd * t1)

        z0_mask = (t0 > 0) & (z0 <= self.z_max) & (z0 >= self.z_min) & (disc >
                                                                        0.)
        z1_mask = (t1 > 0) & (z1 <= self.z_max) & (z1 >= self.z_min) & (disc >
                                                                        0.)

        # # Compute Cylinder Intersections
        t_cand0 = np.where(z0_mask, t0, global_config.MAX_DISTANCE)
        t_cand1 = np.where(z1_mask, t1, global_config.MAX_DISTANCE)
        t_cand_cyl = np.min(np.array([t_cand0, t_cand1]), axis=0)

        # # Compute Endcap Cylinder Intersections
        if self.closed is True:
            t3 = (self.z_min - zo) / zd
            t4 = (self.z_max - zo) / zd

            P_front = (O_xy + D_xy * t3)
            P_back = (O_xy + D_xy * t4)

            front_cap_hit_mask = (vl.vdot(P_front, P_front) <= 1.)
            back_cap_hit_mask = (vl.vdot(P_back, P_back) <= 1.)

            hit_mask = (z0_mask | z1_mask)

            t_front_cap = front_cap_hit_mask * t3
            t_back_cap = back_cap_hit_mask * t4
            t_side = t_cand_cyl

            t_front_cap[t_front_cap <= 0.] = global_config.MAX_DISTANCE
            t_back_cap[t_back_cap <= 0.] = global_config.MAX_DISTANCE
            t_side[t_side <= 0.] = global_config.MAX_DISTANCE

            t_out = np.min([t_side, t_front_cap, t_back_cap], axis=0)
            t_arg_out = np.argmin([t_side, t_front_cap, t_back_cap], axis=0)

            M_out = O_hat + D_hat * t_out

            normal_cyl = hit_mask * (M_out * xy_mask)
            normal_front_cap = front_cap_hit_mask * np.array(
                [0, 0, -1]).reshape(-1, 1)
            normal_back_cap = back_cap_hit_mask * np.array([0, 0, 1]).reshape(
                -1, 1)
            normals = np.sum([
                normal_cyl * (t_arg_out == 0), normal_front_cap *
                (t_arg_out == 1), normal_back_cap * (t_arg_out == 2)
            ],
                             axis=0)

            M_out = vl.transform(
                self.T, vl.transform(self.R, vl.transform(self.S, M_out)))
            N_out = vl.vnorm(
                vl.transform(self.R, vl.inverse_transform(self.S, normals)))
            return t_out, M_out, N_out

        else:
            t_out = t_cand_cyl
            M = (O_hat + D_hat * t_out)
            M_out = vl.transform(self.T,
                                 vl.transform(self.R, vl.transform(self.S, M)))
            N_out = vl.vnorm(
                vl.transform(self.R, vl.inverse_transform(self.S,
                                                          M * xy_mask)))

            return t_out, M_out, N_out
예제 #9
0
 def __init__(self,
              direction,
              emission_color=np.ones((3, 1)),
              intensity=1.):
     super(LightSourceDirectional, self).__init__(emission_color, intensity)
     self.direction = vl.vnorm(np.reshape(direction, (3, 1)))
예제 #10
0
 def get_normal(self):
     return -vl.vnorm(vl.triangle_normal(self.vertices))
예제 #11
0
 def reflect(self, V, N):
     return vl.vnorm(N * 2 * vl.vdot(V, N) - V)
예제 #12
0
파일: camera.py 프로젝트: nlintz/Raytracer
 def D(self):
     return vl.vnorm(self.screen - self.origin)
예제 #13
0
파일: cone.py 프로젝트: nlintz/Raytracer
    def intersection(self, O, D):
        O_hat = vl.inverse_transform(
            self.S,
            vl.inverse_transform(self.R, vl.inverse_transform(self.T, O)))
        D_hat = vl.inverse_transform(self.S, vl.inverse_transform(self.R, D))

        xy_mask = np.array([1., 1., 0.]).reshape(-1, 1)
        z_mask = np.array([0., 0., 1.]).reshape(-1, 1)
        O_xy = O_hat * xy_mask
        O_z = O_hat * z_mask
        D_xy = D_hat * xy_mask
        D_z = D_hat * z_mask

        a = vl.vdot(D_xy, D_xy) - vl.vdot(D_z, D_z)
        b = (2 * vl.vdot(D_xy, O_xy)) - (2 * vl.vdot(D_z, O_z))
        c = vl.vdot(O_xy, O_xy) - vl.vdot(O_z, O_z)

        disc = (b**2) - (4 * a * c)
        t0 = (-b - np.sqrt(np.maximum(disc, 0.))) / (2 * a)
        t1 = (-b + np.sqrt(np.maximum(disc, 0.))) / (2 * a)

        zo = O_hat[2:3]
        zd = D_hat[2:3]
        z0 = (zo + zd * t0)
        z1 = (zo + zd * t1)
        z0_mask = (t0 > 0) & (z0 <= self.z_max) & (z0 >= self.z_min) & (disc >
                                                                        0.)
        z1_mask = (t1 > 0) & (z1 <= self.z_max) & (z1 >= self.z_min) & (disc >
                                                                        0.)

        # Compute Cone Intersections
        t_cand0 = np.where(z0_mask, t0, global_config.MAX_DISTANCE)
        t_cand1 = np.where(z1_mask, t1, global_config.MAX_DISTANCE)

        t_cand_cone = np.min(np.array([t_cand0, t_cand1]), axis=0)

        # Compute Endcap Cone Intersections
        if self.closed is True:
            t4 = (self.z_max - zo) / zd
            P_back = (O_xy + D_xy * t4)

            back_cap_hit_mask = (vl.vdot(P_back, P_back) <= 1.)
            hit_mask = (z0_mask | z1_mask)

            t_side = t_cand_cone
            t_back_cap = back_cap_hit_mask * t4

            t_back_cap[t_back_cap <= 0.] = global_config.MAX_DISTANCE
            t_side[t_side <= 0.] = global_config.MAX_DISTANCE

            t_out = np.min([t_side, t_back_cap], axis=0)
            t_arg_out = np.argmin([t_side, t_back_cap], axis=0)
            M_out = O_hat + D_hat * t_out

            M_norm = (M_out * xy_mask)
            M_norm[2, :] = -1.
            normal_cone = M_norm
            normal_back_cap = back_cap_hit_mask * np.array([0, 0, 1]).reshape(
                -1, 1)
            normals = np.sum([
                normal_cone * (t_arg_out == 0), normal_back_cap *
                (t_arg_out == 1)
            ],
                             axis=0)

            M_out = vl.transform(
                self.T, vl.transform(self.R, vl.transform(self.S, M_out)))
            N_out = vl.vnorm(
                vl.transform(self.R, vl.inverse_transform(self.S, normals)))
            return t_out, M_out, N_out

        else:
            t_out = t_cand_cone
            M = (O_hat + D_hat * t_out)
            M_norm = M * xy_mask
            M_norm[2, :] = -1.

            M_out = vl.transform(self.T,
                                 vl.transform(self.R, vl.transform(self.S, M)))
            N_out = vl.vnorm(
                vl.transform(self.R, vl.inverse_transform(self.S, M_norm)))
            return t_out, M_out, N_out
예제 #14
0
파일: sphere.py 프로젝트: nlintz/Raytracer
 def normal_to(self, M):
     return vl.vnorm(
         vl.inverse_transform(self.S, vl.inverse_transform(self.T, M)))