def next_hit(pos, d): closest, normal = inf, ti.Vector.zero(ti.f32, 3) c, mat = ti.Vector.zero(ti.f32, 3), mat_lambertian # right near sphere cur_dist, hit_pos = intersect_sphere(pos, d, sp1_center, sp1_radius) if 0 < cur_dist < closest: closest = cur_dist normal = ti.normalized(hit_pos - sp1_center) c, mat = ti.Vector([1.0, 1.0, 1.0]), mat_glass # left far sphere cur_dist, hit_pos = intersect_sphere(pos, d, sp2_center, sp2_radius) if 0 < cur_dist < closest: closest = cur_dist normal = ti.normalized(hit_pos - sp2_center) c, mat = ti.Vector([0.8, 0.5, 0.4]), mat_metal # left pnorm = ti.Vector([1.0, 0.0, 0.0]) cur_dist, _ = ray_plane_intersect(pos, d, ti.Vector([-1.0, 0.0, 0.0]), pnorm) if 0 < cur_dist < closest: closest = cur_dist normal = pnorm c, mat = ti.Vector([1.0, 0.0, 0.0]), mat_lambertian # right pnorm = ti.Vector([-1.0, 0.0, 0.0]) cur_dist, _ = ray_plane_intersect(pos, d, ti.Vector([1.0, 0.0, 0.0]), pnorm) if 0 < cur_dist < closest: closest = cur_dist normal = pnorm c, mat = ti.Vector([0.0, 1.0, 0.0]), mat_lambertian # bottom pnorm = ti.Vector([0.0, 1.0, 0.0]) cur_dist, _ = ray_plane_intersect(pos, d, ti.Vector([0.0, 0.0, 0.0]), pnorm) if 0 < cur_dist < closest: closest = cur_dist normal = pnorm c, mat = ti.Vector([1.0, 1.0, 1.0]), mat_lambertian # top pnorm = ti.Vector([0.0, -1.0, 0.0]) cur_dist, _ = ray_plane_intersect(pos, d, ti.Vector([0.0, 2.0, 0.0]), pnorm) if 0 < cur_dist < closest: closest = cur_dist normal = pnorm c, mat = ti.Vector([1.0, 1.0, 1.0]), mat_lambertian # far pnorm = ti.Vector([0.0, 0.0, 1.0]) cur_dist, _ = ray_plane_intersect(pos, d, ti.Vector([0.0, 0.0, 0.0]), pnorm) if 0 < cur_dist < closest: closest = cur_dist normal = pnorm c, mat = ti.Vector([1.0, 1.0, 1.0]), mat_lambertian return closest, normal, c, mat
def dda_particle2(eye_pos, d, t, step): hit_pos = ti.Vector([0.0, 0.0, 0.0]) normal = ti.Vector([0.0, 0.0, 0.0]) closest_intersection = inf for k in range(mpm.n_particles): vel = mpm.v[k] pos = mpm.x[k] x = pos + step * vel dist, poss = intersect_sphere(eye_pos, d, x, sphere_radius) hit_pos = poss if dist < closest_intersection and dist > 0: hit_pos = eye_pos + dist * d closest_intersection = dist normal = ti.Matrix.normalized(hit_pos - x) return closest_intersection, normal
def intersect_spheres(pos, d): normal = ti.Vector([0.0, 0.0, 0.0]) c = ti.Vector([0.0, 0.0, 0.0]) min_dist = inf sid = -1 for i in range(num_spheres): dist = intersect_sphere(pos, d, sphere_pos[i], 0.05) if dist < min_dist: min_dist = dist sid = i if min_dist < inf: hit_pos = pos + d * min_dist normal = ti.Matrix.normalized(hit_pos - sphere_pos[sid]) c = [0.3, 0.5, 0.2] return min_dist, normal, c
def dda_particle(eye_pos, d_, t): grid_res = particle_grid_res bbox_min = bbox[0] bbox_max = bbox[1] hit_pos = ti.Vector([0.0, 0.0, 0.0]) normal = ti.Vector([0.0, 0.0, 0.0]) c = ti.Vector([0.0, 0.0, 0.0]) d = d_ for i in ti.static(range(3)): if ti.abs(d[i]) < 1e-6: d[i] = 1e-6 inter, near, far = ray_aabb_intersection(bbox_min, bbox_max, eye_pos, d) near = ti.max(0, near) closest_intersection = inf if inter: pos = eye_pos + d * (near + eps) rinv = 1.0 / d rsign = ti.Vector([0, 0, 0]) for i in ti.static(range(3)): if d[i] > 0: rsign[i] = 1 else: rsign[i] = -1 o = grid_res * pos ipos = ti.Matrix.floor(o).cast(ti.i32) dis = (ipos - o + 0.5 + rsign * 0.5) * rinv running = 1 while running: inside = inside_particle_grid(ipos) if inside: num_particles = voxel_has_particle[ipos] if num_particles != 0: num_particles = ti.length(pid.parent(), ipos) for k in range(num_particles): p = pid[ipos[0], ipos[1], ipos[2], k] v = particle_v[p] x = particle_x[p] + t * v color = particle_color[p] dist, poss = intersect_sphere(eye_pos, d, x, sphere_radius) hit_pos = poss if dist < closest_intersection and dist > 0: hit_pos = eye_pos + dist * d closest_intersection = dist normal = ti.Matrix.normalized(hit_pos - x) c = [ color // 256**2 / 255.0, color / 256 % 256 / 255.0, color % 256 / 255.0 ] else: running = 0 normal = [0, 0, 0] if closest_intersection < inf: running = 0 else: # hits nothing. Continue ray marching mm = ti.Vector([0, 0, 0]) if dis[0] <= dis[1] and dis[0] <= dis[2]: mm[0] = 1 elif dis[1] <= dis[0] and dis[1] <= dis[2]: mm[1] = 1 else: mm[2] = 1 dis += mm * rsign * rinv ipos += mm * rsign return closest_intersection, normal, c
def intersect_scene(pos, ray_dir): closest, normal = inf, ti.Vector.zero(ti.f32, 3) c, mat = ti.Vector.zero(ti.f32, 3), mat_none # right near sphere cur_dist, hit_pos = intersect_sphere(pos, ray_dir, sp1_center, sp1_radius) if 0 < cur_dist < closest: closest = cur_dist normal = (hit_pos - sp1_center).normalized() c, mat = ti.Vector([1.0, 1.0, 1.0]), mat_glass # left box hit, cur_dist, pnorm = ray_aabb_intersection2_transformed( box_min, box_max, pos, ray_dir) if hit and 0 < cur_dist < closest: closest = cur_dist normal = pnorm c, mat = ti.Vector([0.8, 0.5, 0.4]), mat_specular # left pnorm = ti.Vector([1.0, 0.0, 0.0]) cur_dist, _ = ray_plane_intersect(pos, ray_dir, ti.Vector([-1.1, 0.0, 0.0]), pnorm) if 0 < cur_dist < closest: closest = cur_dist normal = pnorm c, mat = ti.Vector([0.65, 0.05, 0.05]), mat_lambertian # right pnorm = ti.Vector([-1.0, 0.0, 0.0]) cur_dist, _ = ray_plane_intersect(pos, ray_dir, ti.Vector([1.1, 0.0, 0.0]), pnorm) if 0 < cur_dist < closest: closest = cur_dist normal = pnorm c, mat = ti.Vector([0.12, 0.45, 0.15]), mat_lambertian # bottom gray = ti.Vector([0.93, 0.93, 0.93]) pnorm = ti.Vector([0.0, 1.0, 0.0]) cur_dist, _ = ray_plane_intersect(pos, ray_dir, ti.Vector([0.0, 0.0, 0.0]), pnorm) if 0 < cur_dist < closest: closest = cur_dist normal = pnorm c, mat = gray, mat_lambertian # top pnorm = ti.Vector([0.0, -1.0, 0.0]) cur_dist, _ = ray_plane_intersect(pos, ray_dir, ti.Vector([0.0, 2.0, 0.0]), pnorm) if 0 < cur_dist < closest: closest = cur_dist normal = pnorm c, mat = gray, mat_lambertian # far pnorm = ti.Vector([0.0, 0.0, 1.0]) cur_dist, _ = ray_plane_intersect(pos, ray_dir, ti.Vector([0.0, 0.0, 0.0]), pnorm) if 0 < cur_dist < closest: closest = cur_dist normal = pnorm c, mat = gray, mat_lambertian # light hit_l, cur_dist = intersect_light(pos, ray_dir, closest) if hit_l and 0 < cur_dist < closest: # technically speaking, no need to check the second term closest = cur_dist normal = light_normal c, mat = light_color, mat_light return closest, normal, c, mat
def dda_particle(eye_pos, d, t): grid_res = particle_grid_res # bounding box bbox_min = bbox[0] bbox_max = bbox[1] hit_pos = ti.Vector([0.0, 0.0, 0.0]) normal = ti.Vector([0.0, 0.0, 0.0]) c = ti.Vector([0.0, 0.0, 0.0]) for i in ti.static(range(3)): if abs(d[i]) < 1e-6: d[i] = 1e-6 inter, near, far = ray_aabb_intersection(bbox_min, bbox_max, eye_pos, d) near = max(0, near) closest_intersection = inf if inter: pos = eye_pos + d * (near + eps) rinv = 1.0 / d rsign = ti.Vector([0, 0, 0]) for i in ti.static(range(3)): if d[i] > 0: rsign[i] = 1 else: rsign[i] = -1 o = grid_res * pos ipos = ti.floor(o).cast(int) dis = (ipos - o + 0.5 + rsign * 0.5) * rinv running = 1 # DDA for voxels with at least one particle while running: inside = inside_particle_grid(ipos) if inside: # once we actually intersect with a voxel that contains at least one particle, loop over the particle list num_particles = voxel_has_particle[ipos] if num_particles != 0: num_particles = ti.length(pid.parent(), ipos) for k in range(num_particles): p = pid[ipos[0], ipos[1], ipos[2], k] v = particle_v[p] x = particle_x[p] + t * v color = particle_color[p] # ray-sphere intersection dist, poss = intersect_sphere(eye_pos, d, x, sphere_radius) hit_pos = poss if dist < closest_intersection and dist > 0: hit_pos = eye_pos + dist * d closest_intersection = dist normal = (hit_pos - x).normalized() c = color else: running = 0 normal = [0, 0, 0] if closest_intersection < inf: running = 0 else: # hits nothing. Continue ray marching mm = ti.Vector([0, 0, 0]) if dis[0] <= dis[1] and dis[0] <= dis[2]: mm[0] = 1 elif dis[1] <= dis[0] and dis[1] <= dis[2]: mm[1] = 1 else: mm[2] = 1 dis += mm * rsign * rinv ipos += mm * rsign return closest_intersection, normal, c
def dda_particle(eye_pos, d, t, step): bbox_min = bbox[0] bbox_max = bbox[1] hit_pos = ti.Vector([0.0, 0.0, 0.0]) normal = ti.Vector([0.0, 0.0, 0.0]) c = ti.Vector([0.0, 0.0, 0.0]) for i in ti.static(range(3)): if abs( d[i] ) < 1e-6: #iterating over three components of direction vector from rayCast func d[i] = 1e-6 #assigning a lower bound to direction vec components... not sure why? inter, near, far = ray_aabb_intersection(bbox_min, bbox_max, eye_pos, d) #findimg near = max(0, near) closest_intersection = inf # print(closest_intersection) if inter: pos = eye_pos + d * (near + eps) rinv = 1.0 / d rsign = ti.Vector([0, 0, 0]) for i in ti.static(range(3)): if d[i] > 0: rsign[i] = 1 else: rsign[i] = -1 # o = (particle_grid_res * pos)/ 10.0 o = world_to_grid(pos) # o = grid_res * pos ipos = ti.Matrix.floor(o).cast(int) dis = (ipos - o + 0.5 + rsign * 0.5) * rinv running = 1 num = 999999999 num2 = 2000000002 # DDA for voxels with at least one particle while running: inside = inside_particle_grid(ipos) if inside: # print(ipos[0]) # print(ipos[1]) # print(ipos[2]) # once we actually intersect with a voxel that contains at least one particle, loop over the particle list num_particles = voxel_has_particle[ipos] if num_particles != 0: # print(num) # print(num_particles) # world_pos = grid_to_world(ipos) # print(world_pos[0]) # print(world_pos[1]) # print(world_pos[2]) num_particles = ti.length(pid.parent(), ipos) for k in range(num_particles): # print(num2) p = pid[ipos[0], ipos[1], ipos[2], k] # v = mpm.v[p] # x = mpm.x[p] + step * mpm.v[p] x = mpm.x[p] # print(x[0]) # print(x[1]) # print(x[2]) # print(d[0]) # print(d[1]) # print(d[2]) dist, poss = intersect_sphere(eye_pos, d, x, sphere_radius) # print(num) # print(dist) hit_pos = poss if dist < closest_intersection and dist > 0: hit_pos = eye_pos + dist * d closest_intersection = dist normal = ti.Matrix.normalized(hit_pos - x) else: running = 0 normal = [0, 0, 0] if closest_intersection < inf: # print(num) running = 0 else: # print(num2) # hits nothing. Continue ray marching mm = ti.Vector([0, 0, 0]) if dis[0] <= dis[1] and dis[0] <= dis[2]: mm[0] = 1 elif dis[1] <= dis[0] and dis[1] <= dis[2]: mm[1] = 1 else: mm[2] = 1 dis += mm * rsign * rinv ipos += mm * rsign return closest_intersection, normal