Пример #1
0
def render_refract(t: ti.i32):
  for i in range(n_grid):  # Parallelized over GPU threads
    for j in range(n_grid):
      grad = height_gradient[i, j]
      
      scale = 2.0
      sample_x = i - grad[0] * scale
      sample_y = j - grad[1] * scale
      sample_x = ti.min(n_grid - 1, ti.max(0, sample_x))
      sample_y = ti.min(n_grid - 1, ti.max(0, sample_y))
      sample_xi = ti.cast(ti.floor(sample_x), ti.i32)
      sample_yi = ti.cast(ti.floor(sample_y), ti.i32)
      
      frac_x = sample_x - sample_xi
      frac_y = sample_y - sample_yi
      
      for k in ti.static(range(3)):
        refracted_image[i, j, k] = (1.0 - frac_x) * (
            (1 - frac_y) * bottom_image[sample_xi, sample_yi, k] + frac_y *
            bottom_image[
              sample_xi, sample_yi + 1, k]) + frac_x * (
                                       (1 - frac_y) * bottom_image[
                                     sample_xi + 1, sample_yi, k] + frac_y *
                                       bottom_image[
                                         sample_xi + 1, sample_yi + 1, k]
                                   )
Пример #2
0
    def process_new_pcl(self):
        count = 0
        for i, j, k in self.new_pcl_count:
            c = self.new_pcl_count[i, j, k]
            pos_s2p = self.new_pcl_sum_pos[i, j, k]/c
            len_pos_s2p = pos_s2p.norm()
            d_s2p = pos_s2p /len_pos_s2p
            pos_p = pos_s2p + self.input_T[None]
            z = pos_s2p[2]

            j_f = 0.0
            ray_cast_voxels = ti.min(len_pos_s2p/self.voxel_size+ti.static(self.internal_voxels), self.max_ray_length/self.voxel_size)
            for _j in range(ray_cast_voxels):
                j_f += 1.0
                x_ = d_s2p*j_f*self.voxel_size + self.input_T[None]
                xi = self.xyz_to_ijk(x_)
                xi = self.constrain_coor(xi)

                #vector from current voxel to point, e.g. p-x
                v2p = pos_p - x_
                d_x_p = v2p.norm()
                d_x_p_s = d_x_p*sign(v2p.dot(pos_p))

                w_x_p = 1.0#self.w_x_p(d_x_p, z)

                self.TSDF[xi] =  (self.TSDF[xi]*self.W_TSDF[xi]+w_x_p*d_x_p_s)/(self.W_TSDF[xi]+w_x_p)
                self.TSDF_observed[xi] = 1
                
                self.W_TSDF[xi] = ti.min(self.W_TSDF[xi]+w_x_p, Wmax)
                self.updated_TSDF[xi] = 1
                count += 1

                if ti.static(self.TEXTURE_ENABLED):
                    self.color[xi] = self.new_pcl_sum_color[i, j, k]/ c/255.0
Пример #3
0
def sdfscene(p, t=0):
    center = ti.Vector([-3., 1, 6.])
    radius = .5
    planesdf = p.y
    spheresdf = sdfsphere(p, center, radius)
    torussdf = sdfTorus(p, ti.Vector([0, 0.5, 7]), ti.Vector([1.58, .2]))
    capsulesdf = sdfCapsule(p, ti.Vector([0.4, 0.3, 6]),
                            ti.Vector([0.7, 1.5, 6.]), .2)

    bp = p - ti.Vector([-3.4, 0.5, 6])  # translation
    tmpbp = ti.Vector([bp[0], bp[2]])
    tmpbp = Rot(t) @ tmpbp
    bp[0] = tmpbp[0]
    bp[2] = tmpbp[1]
    boxsdf = sdfBox(bp, ti.Vector([0.5, 0.5, 0.5]))

    d = smoothmin(boxsdf, spheresdf, 0.4)
    d = ti.min(planesdf, d)
    d = ti.min(torussdf, d)
    d = ti.min(capsulesdf, d)

    #blend shapes together to form the scene
    bp = p - ti.Vector([3.5, 0.5, 6])
    dbox = sdfBox(bp, ti.Vector([0.5, 0.5, 0.5]))
    dball = sdfsphere(p, ti.Vector([3.5, 0.5, 6]), radius)
    blend = mix(dbox, dball, ti.sin(t) * .5 + .5)
    d = ti.min(blend, d)
    return d
Пример #4
0
def render_photon_map(t: ti.i32, offset_x: ti.f32, offset_y: ti.f32):
  for i in range(n_grid):  # Parallelized over GPU threads
    for j in range(n_grid):
      grad = height_gradient[i, j] * (1 - offset_x) * (1 - offset_y) + \
             height_gradient[i + 1, j] * offset_x * (1 - offset_y) + \
             height_gradient[i, j + 1] * (1 - offset_x) * offset_y + \
             height_gradient[i + 1, j + 1] * offset_x * offset_y
      
      scale = 5.0
      sample_x = i - grad[0] * scale + offset_x
      sample_y = j - grad[1] * scale + offset_y
      sample_x = ti.min(n_grid - 1, ti.max(0, sample_x))
      sample_y = ti.min(n_grid - 1, ti.max(0, sample_y))
      sample_xi = ti.cast(ti.floor(sample_x), ti.i32)
      sample_yi = ti.cast(ti.floor(sample_y), ti.i32)
      
      frac_x = sample_x - sample_xi
      frac_y = sample_y - sample_yi
      
      x = sample_xi
      y = sample_yi
      
      ti.atomic_add(rendered[x, y], (1 - frac_x) * (1 - frac_y))
      ti.atomic_add(rendered[x, y + 1], (1 - frac_x) * frac_y)
      ti.atomic_add(rendered[x + 1, y], frac_x * (1 - frac_y))
      ti.atomic_add(rendered[x + 1, y + 1], frac_x * frac_y)
Пример #5
0
def intersect_aabb(box_min, box_max, o, d):
    intersect = 1

    near_t = -inf
    far_t = inf
    near_face = 0
    near_is_max = 0

    for i in ti.static(range(3)):
        if d[i] == 0:
            if o[i] < box_min[i] or o[i] > box_max[i]:
                intersect = 0
        else:
            i1 = (box_min[i] - o[i]) / d[i]
            i2 = (box_max[i] - o[i]) / d[i]

            new_far_t = ti.max(i1, i2)
            new_near_t = ti.min(i1, i2)
            new_near_is_max = i2 < i1

            far_t = ti.min(new_far_t, far_t)
            if new_near_t > near_t:
                near_t = new_near_t
                near_face = int(i)
                near_is_max = new_near_is_max

    near_norm = ti.Vector([0.0, 0.0, 0.0])
    if near_t > far_t:
        intersect = 0
    if intersect:
        for i in ti.static(range(2)):
            if near_face == i:
                near_norm[i] = -1 + near_is_max * 2
    return intersect, near_t, far_t, near_norm
Пример #6
0
def test_minmax():
  grad_test(lambda x: ti.min(x, 0), lambda x: np.minimum(x, 0))
  grad_test(lambda x: ti.min(x, 1), lambda x: np.minimum(x, 1))
  grad_test(lambda x: ti.min(0, x), lambda x: np.minimum(0, x))
  grad_test(lambda x: ti.min(1, x), lambda x: np.minimum(1, x))

  grad_test(lambda x: ti.max(x, 0), lambda x: np.maximum(x, 0))
  grad_test(lambda x: ti.max(x, 1), lambda x: np.maximum(x, 1))
  grad_test(lambda x: ti.max(0, x), lambda x: np.maximum(0, x))
  grad_test(lambda x: ti.max(1, x), lambda x: np.maximum(1, x))
Пример #7
0
    def get_neigbour_min(self, i, j, mod, src):
        out_min = src[i, j]
        if i + mod < self.wid - 1:
            out_min = ti.min(out_min, src[i + mod, j])

        if j + mod < self.hgt - 1:
            out_min = ti.min(out_min, src[i, j + mod])

        if (j + mod < self.hgt - 1) & (i + mod < self.wid - mod):
            out_min = ti.min(out_min, src[i + mod, j + mod])
        return out_min
Пример #8
0
 def tile_culling(self):
     for i, j in self.block_num_triangles:
         idx = 0
         tile_min = ti.Vector([i * tile_size, j * tile_size])
         tile_max = ti.Vector([(i + 1) * tile_size, (j + 1) * tile_size])
         for t in range(self.n):
             A, B, C = self.A[t], self.B[t], self.C[t]
             tri_min = ti.min(A, ti.min(B, C))
             tri_max = ti.max(A, ti.max(B, C))
             if self.bbox_intersect(tile_min, tile_max, tri_min, tri_max):
                 self.block_indicies[i, j, idx] = t
                 idx = idx + 1
         self.block_num_triangles[i, j] = idx
Пример #9
0
def time_integrate(t: ti.i32):
    for i in range(n_objects):
        s = math.exp(-dt * damping)
        new_v = s * v[t - 1, i] + dt * force[t, i] / mass
        new_x = x[t - 1, i] + dt * new_v
        if new_x[0] > 0.4 and new_v[0] > 0:
            # friction projection
            if new_v[1] > 0:
                new_v[1] -= ti.min(new_v[1], friction * new_v[0])
            if new_v[1] < 0:
                new_v[1] += ti.min(-new_v[1], friction * new_v[0])
            new_v[0] = 0
        v[t, i] = new_v
        x[t, i] = new_x
Пример #10
0
def collide(t: ti.i32):
    for i in range(n_objects):
        hs = halfsize[i]
        for k in ti.static(range(4)):
            # the corner for collision detection
            offset_scale = ti.Vector([k % 2 * 2 - 1, k // 2 % 2 * 2 - 1])

            corner_x, corner_v, rela_pos = to_world(t, i, offset_scale * hs)
            corner_v = corner_v + dt * gravity * ti.Vector([0.0, 1.0])

            # Apply impulse so that there's no sinking
            normal = ti.Vector([0.0, 1.0])
            tao = ti.Vector([1.0, 0.0])

            rn = cross(rela_pos, normal)
            rt = cross(rela_pos, tao)
            impulse_contribution = inverse_mass[i] + ti.sqr(rn) * \
                                   inverse_inertia[i]
            timpulse_contribution = inverse_mass[i] + ti.sqr(rt) * \
                                    inverse_inertia[i]

            rela_v_ground = normal.dot(corner_v)

            impulse = 0.0
            timpulse = 0.0
            new_corner_x = corner_x + dt * corner_v
            toi = 0.0
            if rela_v_ground < 0 and new_corner_x[1] < ground_height:
                impulse = -(1 +
                            elasticity) * rela_v_ground / impulse_contribution
                if impulse > 0:
                    # friction
                    timpulse = -corner_v.dot(tao) / timpulse_contribution
                    timpulse = ti.min(friction * impulse,
                                      ti.max(-friction * impulse, timpulse))
                    if corner_x[1] > ground_height:
                        toi = -(corner_x[1] - ground_height) / ti.min(
                            corner_v[1], 1e-3)

            apply_impulse(t, i, impulse * normal + timpulse * tao,
                          new_corner_x, toi)

            penalty = 0.0
            if new_corner_x[1] < ground_height:
                # apply penalty
                penalty = -dt * penalty * (
                    new_corner_x[1] - ground_height) / impulse_contribution

            apply_impulse(t, i, penalty * normal, new_corner_x, 0)
Пример #11
0
    def initialize_particle_x(x: np.ndarray, v: np.ndarray, color: np.ndarray):
        for i in range(max_num_particles):
            if i < num_particles:
                for c in ti.static(range(3)):
                    particle_x[i][c] = x[i * 3 + c]
                for c in ti.static(range(3)):
                    particle_v[i][c] = v[i * 3 + c]
                # v_c = ti.min(1, particle_v[i].norm()) * 1.5
                # ti.print(v_c)
                if ti.static(scene == 'fluid'):
                    v_c = ti.min(particle_v[i].norm() * 0.1, 1)
                    particle_color[i] = rgb_to_i32(v_c * 0.3 + 0.3,
                                                   v_c * 0.4 + 0.4,
                                                   0.5 + v_c * 0.5)
                elif ti.static(scene == 'sand'):
                    particle_color[i] = ti.cast(color[i], ti.i32)
                else:
                    particle_color[i] = rgb_to_i32(0.85, 0.90, 1.0)

                # reconstruct grid using particle position and MPM p2g.
                for k in ti.static(range(27)):
                    base_coord = (inv_dx * particle_x[i] - 0.5).cast(
                        ti.i32) + ti.Vector([k // 9, k // 3 % 3, k % 3])
                    grid_density[base_coord /
                                 grid_visualization_block_size] = 1
Пример #12
0
 def _sdf(self, f, grid_pos):
     delta = ti.Vector([self.gap[f] / 2, 0., 0.])
     p = grid_pos - ti.Vector([0., -self.h / 2, 0.])
     a = super(Chopsticks, self)._sdf(f,
                                      p - delta)  # grid_pos - (mid + delta)
     b = super(Chopsticks, self)._sdf(f,
                                      p + delta)  # grid_pos - (mid - delta)
     return ti.min(a, b)
Пример #13
0
 def set_action(t: ti.i32):
     cur = 0
     for i in ti.static(range(len(self.primitives))):
         p = self.primitives[i]
         if ti.static(p.action_dim>0):
             for j in ti.static(range(p.action_dim)):
                 p.action_buffer[t][j] = ti.max(ti.min(h[t, cur+j], 1.), -1.)
             cur += p.action_dim
Пример #14
0
 def get_final_image_nondiff(self):
     ''' Retrieves the final image from the tape if the `raycast_nondiff` method was used. '''
     for i, j in self.valid_sample_step_count:
         valid_sample_step_count = self.valid_sample_step_count[i, j] - 1
         self.output_rgba[i, j] = ti.min(1.0, self.render_tape[i, j, 0])
         if valid_sample_step_count > self.max_valid_sample_step_count[None]:
             self.max_valid_sample_step_count[
                 None] = valid_sample_step_count
Пример #15
0
    def kernel(angle: ti.f32, view_id: ti.i32):
        for pixel in range(res * res):
            for k in range(marching_steps):
                x = pixel // res
                y = pixel - x * res

                camera_origin = ti.Vector([
                    camera_origin_radius * ti.sin(angle), 0,
                    camera_origin_radius * ti.cos(angle)
                ])
                dir = ti.Vector([
                    fov * (ti.cast(x, ti.f32) /
                           (res_f32 / 2.0) - res_f32 / res_f32),
                    fov * (ti.cast(y, ti.f32) / (res_f32 / 2.0) - 1.0), -1.0
                ])

                length = ti.sqrt(dir[0] * dir[0] + dir[1] * dir[1] +
                                 dir[2] * dir[2])
                dir /= length

                rotated_x = dir[0] * ti.cos(angle) + dir[2] * ti.sin(angle)
                rotated_z = -dir[0] * ti.sin(angle) + dir[2] * ti.cos(angle)
                dir[0] = rotated_x
                dir[2] = rotated_z
                point = camera_origin + (k + 1) * dx * dir

                # Convert to coordinates of the density grid box
                box_x = point[0] + 0.5
                box_y = point[1] + 0.5
                box_z = point[2] + 0.5

                # Density grid location
                index_x = ti.cast(ti.floor(box_x * density_res), ti.i32)
                index_y = ti.cast(ti.floor(box_y * density_res), ti.i32)
                index_z = ti.cast(ti.floor(box_z * density_res), ti.i32)
                index_x = ti.max(0, ti.min(index_x, density_res - 1))
                index_y = ti.max(0, ti.min(index_y, density_res - 1))
                index_z = ti.max(0, ti.min(index_z, density_res - 1))

                flag = 0
                if in_box(point[0], point[1], point[2]):
                    flag = 1

                contribution = density[index_z, index_y, index_x] * flag

                ti.atomic_add(field[view_id, y, x], contribution)
Пример #16
0
def clamp(x, low, high):
    """
    Получение наиболее близкого значения в заданном диапазоне
    :param x: исходное значение
    :param low: нижняя граница
    :param high: верзняя граница
    :return: новое значение в границах low и high
    """
    return ti.max(ti.min(x, high), low)
Пример #17
0
def softray(ro, rd, hn):
    res = 1.0
    t = 0.0005
    h = 1.0
    for _ in range(0, 40):
        h = scene(ro + rd * t)
        res = ti.min(res, hn * h / t)
        t += ts.clamp(h, 0.02, 2.0)
    return ts.clamp(res, 0.0, 1.0)
Пример #18
0
    def foo():
        # Parallel min
        for i in range(1000):
            ti.atomic_min(f[0], -3.13 * i)

        # Serial min
        for _ in range(1):
            for i in range(1000):
                f[1] = ti.min(-3.13 * i, f[1])
Пример #19
0
def SdfNormalCapsule(X, radius, half_length):
    unclamped_alpha = (X[0] / half_length + 1.0) * 0.5
    alpha = ti.min(ti.max(unclamped_alpha, 0.0), 1.0)
    normal = ti.Vector([X[0], X[1]])
    normal[0] += (1.0 - 2.0 * alpha) * half_length
    ltmp = ti.max(1e-12, normal.norm())
    normal[0] /= ltmp
    normal[1] /= ltmp
    if unclamped_alpha >= 0.0 and unclamped_alpha <= 1.0:
        normal[0] = 0.0
    return normal
Пример #20
0
def apply_impulse(t, i, impulse, location, toi_input):
    # ti.print(toi)
    delta_v = impulse * inverse_mass[i]
    delta_omega = cross(location - x[t, i], impulse) * inverse_inertia[i]

    toi = ti.min(ti.max(0.0, toi_input), dt)

    ti.atomic_add(x_inc[t + 1, i], toi * (-delta_v))
    ti.atomic_add(rotation_inc[t + 1, i], toi * (-delta_omega))

    ti.atomic_add(v_inc[t + 1, i], delta_v)
    ti.atomic_add(omega_inc[t + 1, i], delta_omega)
Пример #21
0
def add_block(x: ti.f32):
    if n_s_particles < 40000 - 1000:
        for i in range(n_s_particles, n_s_particles + 1000):
            x_s[i] = [
                ti.min(0.87, x) + ti.random() * 0.1,
                ti.random() * 0.1 + 0.87
            ]
            v_s[i] = ti.Matrix([0, -0.25])
            F_s[i] = ti.Matrix([[1, 0], [0, 1]])
            c_C0[i] = -0.01
            alpha_s[i] = 0.267765

    n_s_particles += 1000
Пример #22
0
    def linearSolve(self, x, b, relative_tolerance):
        self.linear_solver_data.deactivate_all()
        self.linearSolverReinitialize()

        # NOTE: requires that the input x has been projected
        # self.multiply(x, self.temp)
        self.scaledCopy(self.r, b, -1, self.temp)
        self.kernelProject(self.r)
        self.precondition(
            self.r,
            self.q)  # NOTE: requires that preconditioning matrix is projected
        self.copy(self.p, self.q)

        zTrk = self.dotProduct(self.r, self.q)

        # print('\033[1;36mzTrk = ', zTrk, '\033[0m')
        residual_preconditioned_norm = ti.sqrt(zTrk)
        local_tolerance = self.real(
            ti.min(relative_tolerance * residual_preconditioned_norm,
                   self.linear_solve_tolerance))
        for cnt in range(self.linear_solve_max_iterations):
            if ti.static(self.debug_mode):
                print('\033[1;33mlinear_iter = ', cnt,
                      ', residual_preconditioned_norm = ',
                      residual_preconditioned_norm, '\033[0m')
            if residual_preconditioned_norm <= local_tolerance:
                return cnt

            self.multiply(self.p, self.temp)
            self.kernelProject(self.temp)
            alpha = zTrk / self.dotProduct(self.temp, self.p)
            print('\033[1;36malpha = ', alpha, '\033[0m')
            self.scaledCopy(x, x, alpha, self.p)  # i.e. x += p * alpha
            self.scaledCopy(self.r, self.r, -alpha,
                            self.temp)  # i.e. r -= temp * alpha
            self.precondition(
                self.r, self.q
            )  # NOTE: requires that preconditioning matrix is projected

            zTrk_last = zTrk
            zTrk = self.dotProduct(self.q, self.r)
            print('\033[1;36mzTrk = ', zTrk, '\033[0m')
            beta = zTrk / zTrk_last
            print('\033[1;36mbeta = ', beta, '\033[0m')

            self.scaledCopy(self.p, self.q, beta,
                            self.p)  # i.e. p = q + beta * p

            residual_preconditioned_norm = ti.sqrt(zTrk)

        return self.linear_solve_max_iterations
Пример #23
0
def ray_aabb_intersection(box_min, box_max, o, d):
    intersect = 1

    near_int = -inf
    far_int = inf

    for i in ti.static(range(3)):
        if d[i] == 0:
            if o[i] < box_min[i] or o[i] > box_max[i]:
                intersect = 0
        else:
            i1 = (box_min[i] - o[i]) / d[i]
            i2 = (box_max[i] - o[i]) / d[i]

            new_far_int = ti.max(i1, i2)
            new_near_int = ti.min(i1, i2)

            far_int = ti.min(new_far_int, far_int)
            near_int = ti.max(new_near_int, near_int)

    if near_int > far_int:
        intersect = 0
    return intersect, near_int, far_int
Пример #24
0
def ray_aabb_intersection(box_min, box_max, o, d):
    intersect = 1

    near_int = -inf
    far_int = inf

    for i in ti.static(range(3)):
        if d[i] == 0:
            if o[i] < box_min[i] or o[i] > box_max[
                    i]:  # if any component of ray origin is outside bbox
                intersect = 0  #intersection is false
        else:
            i1 = (box_min[i] - o[i]) / d[i]
            i2 = (box_max[i] - o[i]) / d[i]

            new_far_int = ti.max(i1, i2)
            new_near_int = ti.min(i1, i2)

            far_int = ti.min(new_far_int, far_int)
            near_int = ti.max(new_near_int, near_int)

    if near_int > far_int:
        intersect = 0
    return intersect, near_int, far_int
Пример #25
0
def intersect_hull(gx: ti.f32, gy: ti.f32, gz: ti.f32, k_len: ti.i32,
                   hull_len: ti.i32):
    g = ti.Vector([gx, gy, gz])
    for i in range(k_len):
        c = hull_p[i]
        d = c - g
        h = c
        for j in range(hull_len):
            ok, p = intersect_triangle(g, d, hull_p[hull_f[j][0]],
                                       hull_p[hull_f[j][1]],
                                       hull_p[hull_f[j][2]])
            if ok:
                h = p
                break
        k[i] = ti.min(
            ti.max(ti.sqrt((c - g).dot(c - g) / (h - g).dot(h - g)), 0.0), 1.0)
Пример #26
0
    def util_ti_scale_value_to_color(self, c) -> ti.i32:
        max_value = self.display_value_max
        min_value = self.display_value_min
        v = (c - min_value) / (max_value - min_value)

        value = 0
        if ti.static(self.display_color_map == 0):
            # map [0,1] ~ gray color 0~255
            color_gray = ti.min(255, ti.max(0, v * 256.0))
            value = ti.cast(color_gray, ti.i32) * 0x010101
        else:
            r = self.util_color_map_value(0x01, 0xff, v)
            g = self.util_color_map_value(0x20, 0xbb, v)
            b = self.util_color_map_value(0xff, 0x00, v)
            value = r * 0x010000 + g * 0x0100 + b
        return value
Пример #27
0
 def _cook(self, color):
     if isinstance(color, ti.Expr):
         color = ti.Vector([color, color, color])
     elif isinstance(color, ti.Matrix):
         assert color.m == 1, color.m
         if color.n == 1:
             color = ti.Vector([color(0), color(0), color(0)])
         elif color.n == 2:
             color = ti.Vector([color(0), color(1), 0])
         elif color.n in [3, 4]:
             color = ti.Vector([color(0), color(1), color(2)])
         else:
             assert False, color.n
     if self.img.meta.dtype not in [ti.u8, ti.i8]:
         color = ti.max(0, ti.min(255, ti.cast(color * 255 + 0.5, int)))
     return color
Пример #28
0
 def func():
     x[0] = y[None] + z[None]
     x[1] = y[None] - z[None]
     x[2] = y[None] * z[None]
     x[3] = y[None] / z[None]
     x[4] = y[None] // z[None]
     x[5] = y[None] % z[None]
     x[6] = y[None]**z[None]
     x[7] = y[None] == z[None]
     x[8] = y[None] != z[None]
     x[9] = y[None] > z[None]
     x[10] = y[None] >= z[None]
     x[11] = y[None] < z[None]
     x[12] = y[None] <= z[None]
     x[13] = ti.atan2(y[None], z[None])
     x[14] = ti.min(y[None], z[None])
     x[15] = ti.max(y[None], z[None])
Пример #29
0
 def raycast(self, sampling_rate: float):
     ''' Produce a rendering. Run compute_entry_exit first! '''
     for i, j in self.valid_sample_step_count:  # For all pixels
         for sample_idx in range(self.sample_step_nums[i, j]):
             look_from = self.cam_pos[None]
             if self.render_tape[i, j, sample_idx -
                                 1].w < 0.99 and sample_idx < ti.static(
                                     self.max_samples):
                 tmax = self.exit[i, j]
                 n_samples = self.sample_step_nums[i, j]
                 ray_len = (tmax - self.entry[i, j])
                 tmin = self.entry[
                     i,
                     j] + 0.5 * ray_len / n_samples  # Offset tmin as t_start
                 vd = self.rays[i, j]
                 pos = look_from + tl.mix(
                     tmin, tmax,
                     float(sample_idx) /
                     float(n_samples - 1)) * vd  # Current Pos
                 light_pos = look_from + tl.vec3(0.0, 1.0, 0.0)
                 intensity = self.sample_volume_trilinear(pos)
                 sample_color = self.apply_transfer_function(intensity)
                 opacity = 1.0 - ti.pow(1.0 - sample_color.w,
                                        1.0 / sampling_rate)
                 # if sample_color.w > 1e-3:
                 normal = self.get_volume_normal(pos)
                 light_dir = (
                     pos -
                     light_pos).normalized()  # Direction to light source
                 n_dot_l = max(normal.dot(light_dir), 0.0)
                 diffuse = self.diffuse * n_dot_l
                 r = tl.reflect(light_dir,
                                normal)  # Direction of reflected light
                 r_dot_v = max(r.dot(-vd), 0.0)
                 specular = self.specular * pow(r_dot_v, self.shininess)
                 shaded_color = tl.vec4(
                     ti.min(1.0, diffuse + specular + self.ambient) *
                     sample_color.xyz * opacity * self.light_color, opacity)
                 self.render_tape[i, j, sample_idx] = (
                     1.0 - self.render_tape[i, j, sample_idx - 1].w
                 ) * shaded_color + self.render_tape[i, j, sample_idx - 1]
                 self.valid_sample_step_count[i, j] += 1
             else:
                 self.render_tape[i, j, sample_idx] = self.render_tape[
                     i, j, sample_idx - 1]
Пример #30
0
def sdf(o_):
    if ti.static(supporter == 0):
        o = o_ - ti.Vector([0.5, 0.002, 0.5])
        p = o
        h = 0.02
        ra = 0.29
        rb = 0.005
        d = (ti.Vector([p[0], p[2]]).norm() - 2.0 * ra + rb, ti.abs(p[1]) - h)
        dist = ti.min(ti.max(d[0], d[1]), 0.0) + ti.Vector(
            [ti.max(d[0], 0.0), ti.max(d[1], 0)]).norm() - rb
        return dist
    elif ti.static(supporter == 1):
        o = o_ - ti.Vector([0.5, 0.002, 0.5])
        dist = (o.abs() - ti.Vector([0.5, 0.02, 0.5])).max()
    else:
        dist = o_[1] - 0.04

    return dist