def light(lightdir, lightcol, tex, norm, camdir): cosa = ti.pow(0.5 + 0.5 * norm.dot(-lightdir), 2.0) cosr = ti.max((-camdir).dot(ts.reflect(lightdir, norm)), -0.0) diffuse = cosa phong = ti.pow(cosr, 8.0) return lightcol * (tex * diffuse + phong)
def grad_p(i): pi = Particles.p[i] p = dw_dxi(0, 0, 1) * 0 for j in range(Particles.N): p += Particles.density[i] * Particles.m[j] * ( pi / ti.pow(Particles.density[i], 2) + Particles.p[j] / ti.pow(Particles.density[j], 2)) * dw_dxi(i, j, Particles.h) return p
def tonemap(accumulated: ti.f32) -> ti.f32: sum = 0.0 sum_sq = 0.0 for i, j in color_buffer: luma = color_buffer[i, j][0] * 0.2126 + color_buffer[ i, j][1] * 0.7152 + color_buffer[i, j][2] * 0.0722 sum += luma sum_sq += ti.pow(luma / accumulated, 2.0) mean = sum / (res[0] * res[1]) var = sum_sq / (res[0] * res[1]) - ti.pow(mean / accumulated, 2.0) for i, j in tonemapped_buffer: tonemapped_buffer[i, j] = ti.sqrt(color_buffer[i, j] / mean * 0.6) return var
def w(i, j) -> ti.f32: vx_ij = x[i] - x[j] q = vx_ij.norm() / h if q < 1: q = 2 / 3 - ti.pow(q, 2) + 1 / 2 * ti.pow(q, 3) elif 1 <= q < 2: q = 1 / 6 * ti.pow(2 - q, 3) else: q = 0 q *= (3 / (2 * math.pi)) return 1 / ti.pow(h, d) * q
def ProjectDruckerPrager(S: ti.template(), Jp: ti.template()): JSe = S[0, 0] * S[1, 1] for d in ti.static(range(2)): S[d, d] = ti.max(1e-6, ti.abs(S[d, d] * Jp)) if S[0, 0] * S[1, 1] >= 1.0: # Project to tip S[0, 0] = 1.0 S[1, 1] = 1.0 Jp *= ti.pow(max(1e-6, JSe), volume_recovery_rate) else: # Check if the stress is inside the feasible region Jp = 1.0 Je = max(1e-6, S[0, 0] * S[1, 1]) sqrS_0 = S[0, 0] * S[0, 0] sqrS_1 = S[1, 1] * S[1, 1] trace_b_2 = (sqrS_0 + sqrS_1) / 2.0 Je2 = Je * Je yield_threshold = -material_friction * kappa_0 * 0.5 * (Je2 - 1.0) dev_b0 = sqrS_0 - trace_b_2 dev_b1 = sqrS_1 - trace_b_2 norm2_dev_b = dev_b0 * dev_b0 + dev_b1 * dev_b1 mu_norm_dev_b_bar = mu_0 * ti.sqrt(norm2_dev_b / Je) if mu_norm_dev_b_bar > yield_threshold: # Project to the yield surface det_b = sqrS_0 * sqrS_1 det_dev_b = dev_b0 * dev_b1 lambda_2 = yield_threshold / max(1e-6, mu_norm_dev_b_bar) lambda_1 = ti.sqrt( max(0.0, det_b - lambda_2 * lambda_2 * det_dev_b)) S[0, 0] = ti.sqrt(abs(lambda_1 + lambda_2 * dev_b0)) S[1, 1] = ti.sqrt(abs(lambda_1 + lambda_2 * dev_b1))
def regress(): for i in x: v = x[i] est = 0.0 for j in ti.static(range(number_coeffs)): est += coeffs[j] * ti.pow(v, j) loss.atomic_add(0.5 * ti.sqr(y[i] - est))
def w(i, j, h) -> ti.f32: diff_x = Particles.X[i] - Particles.X[j] norm = diff_x.norm() q = norm / h d = 3 if 0 <= q < 1: q = 2 / 3 - ti.pow(q, 2) + 1 / 2 * ti.pow(q, 3) elif 1 <= q < 2: q = 1 / 6 * ti.pow(2 - q, 3) else: q = 0 q *= (3 / 2 / math.pi) return 1 / ti.pow(h, d) * q
def get_color(z, timef32): zoo = 0.62 + 0.38 * ti.cos(0.02 * timef32) coa = ti.cos(0.1 * (1.0 - zoo) * timef32) sia = ti.sin(0.1 * (1.0 - zoo) * timef32) zoo = ti.pow(zoo, 8.0) xy = ti.Vector([z[0] * coa - z[1] * sia, z[0] * sia + z[1] * coa]) cc = ( ti.Vector([1.0, 0.0]) + smoothstep(1.0, 0.5, zoo) * ti.Vector([0.24814, 0.7369]) + xy * zoo * 2.0 ) col = ti.Vector([0.0, 0.0, 0.0]) sc = ti.Vector([ti.abs(cc[0] - 1.0) - 1.0, cc[1]]) if ti.dot(sc, sc) >= 1.0: co = 0.0 w = ti.Vector([0.5, 0.0]) for _ in range(256): if ti.dot(w, w) > 1024: break w = cmul(cc, cmul(w, cadd(1.0, -w))) co += 1.0 sco = co + 1.0 - log2(0.5 * (log2(ti.dot(cc, cc)) + log2(ti.dot(w, w)))) col = 0.5 + 0.5 * ti.cos(3.0 + sco * 0.1 + ti.Vector([0.0, 0.5, 1.0])) if co > 255.5: col = ti.Vector([0.0, 0.0, 0.0]) if ti.abs(cc.x - 1.0) < 3.0: al = smoothstep(17.0, 12.0, timef32) col = clamp(col, 0.0, 1.0) x = 0.5 for _ in range(200): x = cc[0] * (1.0 - x) * x for _ in range(200): x = cc[0] * (1.0 - x) * x col = col + mix( col, ti.Vector([1.0, 1.0, 0.0]), 0.15 + 0.85 * ti.pow(clamp(ti.abs(sc.x + 1.0) * 0.4, 0.0, 1.0), 4.0), ) * al * 0.06 * ti.exp(-15000.0 * (cc.y - x) * (cc.y - x)) return col
def main_image(t, i, j): fragcoord = ts.vec(i, j) xy = (fragcoord - iResolution / 2.0) / max(iResolution[0], iResolution[1]) campos = ts.vec(camdis[None] * ts.cos(t / 5.0), camdis * 0.5, camdis[None] * ts.sin(t / 5.0)) camtar = ts.vec(0.0, 0.0, 0.0) camdir = (cal_look_at_mat(campos, camtar, 0.0) @ ts.vec3( xy[0], xy[1], 0.9)).normalized() return ti.pow(render_ray(campos, camdir), ts.vec(1.0 / 2.2, 1.0 / 2.2, 1.0 / 2.2))
def dw(i, j, res=ti.Vector([0.0, 0.0])): vx_ij = x[i] - x[j] q = vx_ij.norm() / h alpha_x = 1 / h / vx_ij.norm() * vx_ij c = 1 / ti.pow(h, d) * 3 / 2 / math.pi if 0 <= q < 1: res = c * (-2 * q + 3 / 2 * q * q) * alpha_x elif 1 <= q < 2: res = -c * 0.5 * (2 - q) * (2 - q) * alpha_x else: res = 0 * alpha_x return res
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]
def dw_dxi(i, j, h): diff_x = Particles.X[i] - Particles.X[j] norm = diff_x.norm() q = norm / h dx = 1 / h / norm * diff_x c = 1 / ti.pow(h, 3) * 3 / 2 / math.pi res = 0 * dx if 0 <= q < 1: res = c * (-2 * q + 3 / 2 * q * q) * dx elif 1 <= q < 2: res = -c * 0.5 * (2 - q) * (2 - q) * dx else: res = 0 * dx return res
def raycast_nondiff(self, sampling_rate: float): ''' Raycasts in a non-differentiable (but faster and cleaner) way. Use `get_final_image_nondiff` with this. Args: sampling_rate (float): Sampling rate (multiplier with Nyquist frequence) ''' for i, j in self.valid_sample_step_count: # For all pixels for cnt in range(self.sample_step_nums[i, j]): look_from = self.cam_pos[None] if self.render_tape[i, j, 0].w < 0.99: 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(cnt) / 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( (diffuse + specular + self.ambient) * sample_color.xyz * opacity * self.light_color, opacity) self.render_tape[ i, j, 0] = (1.0 - self.render_tape[i, j, 0].w ) * shaded_color + self.render_tape[i, j, 0]
def render(time: ti.f32): zoo = 0.64 + 0.36 * ti.cos(0.02 * time) zoo = ti.pow(zoo, 8.0) ca = ti.cos(0.15 * (1.0 - zoo) * time) sa = ti.sin(0.15 * (1.0 - zoo) * time) for i, j in pixels: c = 2.0 * vec2(i, j) / height - vec2(1) #c *= 1.16 xy = vec2(c.x * ca - c.y * sa, c.x * sa + c.y * ca) c = vec2(-0.745, 0.186) + xy * zoo z = vec2(0.) count = 0. while count < MAXITERS and dot(z, z) < 50: z = cmul(z, z) + c count += 1. if count == MAXITERS: pixels[i, j] = [0, 0, 0] else: pixels[i, j] = setcolor(z, count)
def render(timestep: ti.f32, m: ti.ext_arr()): for x, y in pixels: p = (2.0 * x - res[0]) / res[1], (2.0 * y - res[1]) / res[1] rayo = 4.0 * ti.Vector( [ti.sin(3.0 * m[0]), 0.4 * m[1], ti.cos(3.0 * m[0])]) up = ti.Vector([0.0, -1.0, 0.0]) rotation = 0.0 camera = set_camera(rayo, up, rotation) rayd = camera @ ti.Vector([p[0], p[1], 1.5]).normalized() # sky sun = clamp(sun_dir.normalized().dot(rayd)) col = ti.Vector([ 0.6, 0.71, 0.75 ]) - rayd[1] * 0.2 * ti.Vector([1.0, 0.5, 1.0]) + 0.15 * 0.5 col += 0.2 * ti.Vector([1.0, .6, 0.1]) * ti.pow(sun, 8.0) #cloud ret = ray_march(rayo, rayd, col, timestep) col = col * (1.0 - ret[3]) + ti.Vector([ret[0], ret[1], ret[2]]) # glare col += 0.2 * ti.Vector([1.0, 0.4, 0.2]) * pow(sun, 3.0) # output to pixels pixels[x, y] = col
def __pow__(self, other, modulo=None): import taichi as ti _taichi_skip_traceback = 1 return ti.pow(self, other)
def schlick(cosine, ref_idx): r0 = (1.0 - ref_idx) / (1 + ref_idx) r0 = r0 * r0 return r0 + (1 - r0) * ti.pow((1 - cosine), 5)
def __rpow__(self, other, modulo=None): import taichi as ti return ti.pow(other, self)
def dp(i, res=ti.Vector([0.0, 0.0])): for j in range(N): if j != i: res += mass[j] * (pressure[i] / ti.pow(density[i], 2) + pressure[j] / ti.pow(density[j], 2)) * dw(i, j) return density[i] * res
def __rpow__(self, other, modulo=None): _taichi_skip_traceback = 1 return ti.pow(other, self)
def __ipow__(self, other): _taichi_skip_traceback = 1 self.assign(ti.pow(self, other)) return self
def compute_p(density): return Particles.k * (ti.pow(density / Particles.po, 7) - 1)
def compute_pressure(den): return k * (ti.pow(den / po, 7) - 1)