Taichiは、物理シミュレーションやグラフィックレンダリングに特化したPythonライブラリで、GPUを活用して高度な並列処理を提供します。以下ではその基本的な使い方と応用例を紹介します。
インストール方法
<code>pip install taichi</code>
基礎的なグラフィックレンダリング
簡単な形状の描画が可能です。例えば、以下のようなコードで複雑なパターンを生成できます。
<code>
import taichi as ti
ti.init(arch=ti.gpu)
n = 400
img = ti.field(dtype=float, shape=(n, n))
@ti.func
def calc_color(x, y):
c = ti.Vector([x - 0.5, y - 0.5])
z = ti.Vector([0.0, 0.0])
for i in range(100):
if z.norm() > 2: break
z = ti.Vector([z[0]**2 - z[1]**2 + c[0], 2*z[0]*z[1] + c[1]])
return min(i * 0.02, 1.0)
@ti.kernel
def render():
for i, j in img:
x = i / n
y = j / n
img[i, j] = calc_color(x, y)
render()
gui = ti.GUI("Basic Rendering", res=(n, n))
while gui.running:
gui.set_image(img)
gui.show()
</code>
物理シミュレーション
物理シミュレーションも直感的に実装できます。ここでは、重力下でのボールの動きを模倣します。
<code>
import taichi as ti
ti.init(arch=ti.cuda)
num_balls = 50
g = ti.Vector([0.0, -9.8])
pos = ti.Vector.field(2, dtype=ti.f32, shape=num_balls)
vel = ti.Vector.field(2, dtype=ti.f32, shape=num_balls)
@ti.kernel
def init():
for i in range(num_balls):
pos[i] = [ti.random(), ti.random()]
vel[i] = [0.0, 0.0]
@ti.kernel
def step():
for i in range(num_balls):
vel[i] += g * 0.01
pos[i] += vel[i] * 0.01
if pos[i].y < 0:
vel[i].y *= -0.7
init()
gui = ti.GUI('Ball Simulation', (600, 600))
while gui.running:
step()
gui.circles(pos.to_numpy(), radius=5)
gui.show()
</code>
ボリュームレンダリング
光線が透明または半透明の物質を通過する効果をシミュレートする技術です。Taichiはこの高度なレンダリングをサポートしています。
<code>
import taichi as ti
ti.init(arch=ti.gpu)
res = (800, 600)
density = ti.field(dtype=ti.f32, shape=res)
@ti.func
def interpolate(a, b, t):
return a + (b - a) * t
@ti.kernel
def initialize_density():
for i, j in density:
x = i / res[0]
y = j / res[1]
density[i, j] = interpolate(0.0, 1.0, y)
@ti.kernel
def perform_render(out_img: ti.template()):
for i, j in out_img:
d = density[i, j]
out_img[i, j] = ti.Vector([d, d, d])
def main():
initialize_density()
output = ti.Vector.field(3, dtype=ti.f32, shape=res)
gui = ti.GUI("Volume Render Demo", res)
while gui.running:
perform_render(output)
gui.set_image(output)
gui.show()
if __name__ == "__main__":
main()
</code>