def mainImage(iMouse: ti.Vector, iTime: ti.f32, i: ti.i32, j: ti.i32) -> ti.Vector: fragCoord = ti.Vector([i, j]) fragColor = ti.Vector([0.0, 0.0, 0.0]) m_x: ti.i32 = (iMouse[0] / iResolution[0]) - 0.5 m_y: ti.i32 = (iMouse[1] / iResolution[1]) - 0.5 ## vec3 cameraOrigin = ti.Vector( [5.0 * ti.sin(m_x * PI * 2.), m_y * 15.0, 5.0 * ti.cos(m_x * PI * 2.)]) cameraTarget = ti.Vector([0.0, 0.0, 0.0]) upDirection = ti.Vector([0.0, 1.0, 0.0]) cameraDir = (cameraTarget - cameraOrigin).normalized() cameraRight = upDirection.cross(cameraOrigin).normalized() cameraUp = cameraDir.cross(cameraRight) # TODO: check (gl_FragCoord.xy == fragCoord) screenPos = -1.0 + 2.0 * fragCoord / iResolution screenPos[0] *= iResolution[0] / iResolution[1] rayDir = ( cameraRight * screenPos[0] \ + cameraUp * screenPos[1] \ + cameraDir ).normalized() pos: ti.Vector = cameraOrigin totalDist = 0.0 dist = EPSILON for _ in range(MAX_ITER): if (dist < EPSILON) or (totalDist > MAX_DIST): break dist = distfunc(iTime, pos) totalDist += dist pos += dist * rayDir # for i in range(MAX_ITER) END if (dist < EPSILON): eps = ti.Vector([0.0, EPSILON]) eps_yxx = ti.Vector([EPSILON, 0.0, 0.0]) eps_xyx = ti.Vector([0.0, EPSILON, 0.0]) eps_xxy = ti.Vector([0.0, 0.0, EPSILON]) normal = ti.Vector([ distfunc(iTime, pos + eps_yxx) - distfunc(iTime, pos - eps_yxx), distfunc(iTime, pos + eps_xyx) - distfunc(iTime, pos - eps_xyx), distfunc(iTime, pos + eps_xxy) - distfunc(iTime, pos - eps_xxy) ]).normalized() lightdir = ti.Vector([1.0, -1.0, 0.0]).normalized() diffuse = max(0.2, lightdir.dot(normal)) # tc = vec2(pos[0], pos.z) # texcol = texture(iChannel0, tc).rgb lightcol = ti.Vector([1.0, 1.0, 1.0]) darkcol = ti.Vector([0.4, 0.8, 0.9]) sma = 0.4 smb = 0.6 if (flag[HIT_HOLE]): lightcol = ti.Vector([1.0, 1.0, 0.8]) elif flag[HIT_BARREL]: lightcol[0] = 0.95 else: sma = 0.2 smb = 0.3 # if (HIT_HOLE) END facingRatio = smoothstep(sma, smb, abs(normal.dot(rayDir))) illumcol = mix(lightcol, darkcol, 1.0 - facingRatio) fragColor = illumcol else: # dist >= EPSILON strp: ti.f32 = smoothstep(0.8, 0.9, (screenPos[1] * 10. + iTime) % 1) fragColor = mix(ti.Vector([1.0, 1.0, 1.0]), ti.Vector([0.4, 0.8, 0.9]), strp) # if (dist <=> EPSILON) END return fragColor
def rotateX(p: ti.Vector, ang: ti.f32) -> ti.Vector: rmat: ti.Matrix = ti.Matrix([[1.0, 0.0, 0.0], [0.0, ti.cos(ang), -ti.sin(ang)], [0.0, ti.sin(ang), ti.cos(ang)]]) return rmat @ p
def test_trigonometric(): grad_test(lambda x: ti.tanh(x), lambda x: np.tanh(x)) grad_test(lambda x: ti.sin(x), lambda x: np.sin(x)) grad_test(lambda x: ti.cos(x), lambda x: np.cos(x)) grad_test(lambda x: ti.acos(x), lambda x: np.arccos(x)) grad_test(lambda x: ti.asin(x), lambda x: np.arcsin(x))
def random_vector(radius): # Create a random vector in circle theta = ti.random() * 2 * math.pi r = ti.random() * radius return r * ti.Vector([ti.cos(theta), ti.sin(theta)])
def rotation_matrix(r): return ti.Matrix([[ti.cos(r), -ti.sin(r)], [ti.sin(r), ti.cos(r)]])
def init(self): for I in ti.grouped(ti.ndrange(*[self.N] * self.dim)): r_I = 5.0 for k in ti.static(range(self.dim)): r_I *= ti.cos(5 * np.pi * I[k] / self.N) self.init_r(I, r_I)
def complex_power(z, power: ti.i32): r = ti.sqrt(z[0] ** 2 + z[1] ** 2) theta = ti.atan2(z[1], z[0]) return ti.Vector([r ** power * ti.cos(power * theta), r ** power * ti.sin(power * theta)])
def rotation2d(alpha): import taichi as ti return ti.Matrix([[ti.cos(alpha), -ti.sin(alpha)], [ti.sin(alpha), ti.cos(alpha)]])
def func(a): return ti.Vector([ti.cos(a), ti.sin(a)])
def rotation2d(alpha): return Matrix([[ti.cos(alpha), -ti.sin(alpha)], [ti.sin(alpha), ti.cos(alpha)]])
import taichi_three as t3 import numpy as np import time ti.init(ti.cpu) scene = t3.Scene() model = t3.Model(t3.Mesh.from_obj(t3.readobj('assets/torus.obj', scale=0.8))) scene.add_model(model) ball = t3.Model(t3.Mesh.from_obj(t3.readobj('assets/sphere.obj', scale=0.1))) ball.material = t3.Material( t3.BlinnPhong(emission=t3.Constant(t3.RGB(1.0, 1.0, 1.0)), )) scene.add_model(ball) camera = t3.Camera() camera.ctl = t3.CameraCtl(pos=[0, 1.8, 1.8]) scene.add_camera(camera) light = t3.PointLight(pos=[0, 1, 0]) scene.add_light(light) ambient = t3.AmbientLight(0.2) scene.add_light(ambient) gui = ti.GUI('Point light', camera.res) while gui.running: gui.get_event(None) gui.running = not gui.is_pressed(ti.GUI.ESCAPE) camera.from_mouse(gui) light.pos[None].y = ti.cos(time.time()) ball.L2W[None] = t3.translate(light.pos[None].value) scene.render() gui.set_image(camera.img) gui.show()
def sense(phase, pos, ang): p = pos + ti.Vector([ti.cos(ang), ti.sin(ang)]) * SENSE_DIST return grid[phase, p.cast(int) % GRID_SIZE]
def on_render(self): for I in ti.grouped(self.img): uv = I / self.iResolution self.img[I] = ti.cos(uv.xyx + self.iTime + ts.vec(0, 2, 4)) * 0.5 + 0.5
def trace(sample: ti.u32): for i, j in linear_pixel: o = ti.Vector([camera_pos[0], camera_pos[1], camera_pos[2]]) aperture_size = 0.2 forward = -o.normalized() u = ti.Vector([0.0, 1.0, 0.0]).cross(forward).normalized() v = forward.cross(u).normalized() u = -u # anti aliasing d = ((i + ti.random() - width / 2.0) / width * u * 1.5 + (j + ti.random() - height / 2.0) / width * v * 1.5 + width / width * forward).normalized() focal_point = d * focal_length / d.dot(forward) + o o += d * 0.01 # assuming a circle-like aperture phi = 2.0 * math.pi * ti.random() aperture_radius = ti.random() * aperture_size o += u * aperture_radius * ti.cos(phi) + \ v * aperture_radius * ti.sin(phi) d = (focal_point - o).normalized() uv = cubemap_coord(d) albedo_factor = ti.Vector([1.0, 1.0, 1.0]) radiance = ti.Vector([0.0, 0.0, 0.0]) for step in ti.ndrange(32): sp = spheres.intersect(o, d) uv = cubemap_coord(d) if sp[1] > -1: sp_index = int(sp[1]) p = sp[0] * d + o c_ = spheres.center_radius[sp_index] c = ti.Vector([c_[0], c_[1], c_[2]]) n = (p - c).normalized() wo = -d albedo = spheres.albedos[sp_index] metallic = spheres.metallics[sp_index] ior = spheres.iors[sp_index] roughness = ti.max(0.04, spheres.roughness[sp_index]) f0 = (1.0 - ior) / (1.0 + ior) f0 = f0 * f0 f0 = lerp(f0, luma(albedo), metallic) wi = reflect(-wo, n) radiance += spheres.emissions[sp_index] * albedo_factor view_fresnel = schlick2(wo, n, f0) sample_weights = ti.Vector([1.0 - view_fresnel, view_fresnel]) weight = 0.0 h = (wi + wo).normalized() shaded = ti.Vector([0.0, 0.0, 0.0]) if ti.random() < sample_weights[0]: wi = cosine_sample(n).normalized() h = (wi + wo).normalized() shaded = ti.max(0.00, wi.dot(n) * albedo / math.pi) else: wi = ggx_sample(n, wo, roughness).normalized() h = (wi + wo).normalized() F = schlick2(wi, n, f0) shaded = ti.max(0.0, wi.dot(n) * albedo * ggx_smith_uncorrelated( roughness, h.dot(n), wo.dot(n), wi.dot(n), F)) pdf_lambert = wi.dot(n) / math.pi pdf_ggx = ggx_pdf(roughness, h.dot(n), wo.dot(h)) weight = ti.max(0.0, 1.0 / (sample_weights[0] * pdf_lambert + sample_weights[1] * pdf_ggx)) # russian roule albedo_factor *= shaded * weight if step > 5: if luma(albedo) < ti.random(): break else: albedo_factor /= luma(albedo) d = wi o = p + eps * d else: radiance += albedo_factor * tex2d(skybox.field, uv) / 255 break linear_pixel[i, j] = (linear_pixel[i, j] * (sample - 1) + radiance) / sample pixel[i, j] = ti.sqrt(linear_pixel[i, j])
lambda x: x * x * x, lambda x: x * x * x * x, lambda x: 0.4 * x * x - 3, lambda x: (x - 3) * (x - 1), lambda x: (x - 3) * (x - 1) + x * x, ]) @if_has_autograd @test_utils.test() def test_poly(tifunc): grad_test(tifunc) @pytest.mark.parametrize('tifunc,npfunc', [ (lambda x: ti.tanh(x), lambda x: np.tanh(x)), (lambda x: ti.sin(x), lambda x: np.sin(x)), (lambda x: ti.cos(x), lambda x: np.cos(x)), (lambda x: ti.acos(x), lambda x: np.arccos(x)), (lambda x: ti.asin(x), lambda x: np.arcsin(x)), ]) @if_has_autograd @test_utils.test(exclude=[ti.vulkan]) def test_trigonometric(tifunc, npfunc): grad_test(tifunc, npfunc) @pytest.mark.parametrize('tifunc', [ lambda x: 1 / x, lambda x: (x + 1) / (x - 1), lambda x: (x + 1) * (x + 2) / ((x - 1) * (x + 3)), ]) @if_has_autograd