1. 开始之前
1.1 学习资源链接
Taichi_THREE 原作者的教程视频:
https://www.bilibili.com/video/av628129594
github 链接:
https://github.com/taichi-dev/taichi_three#how-to-play
- 运行程序之前记得将资源文件夹
assets
分别复制进 docs
和 example
文件目录下。

1.2 安装
1
| python3 -m pip install taichi
|
1
| python3 -m pip install taichi-tina
|
具体安装流程见官方文档:
2. 你好,三角形
2.1 坐标系
Tina
使用的右手坐标系:

2.2 创建窗口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import taichi as ti import tina
scene = tina.Scene()
mesh = tina.SimpleMesh() scene.add_object(mesh)
gui = ti.GUI('simple triangle')
while gui.running: scene.render()
gui.set_image(scene.img) gui.show()
|
得到一个空白窗口:

2.3 设置顶点数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
verts = np.array([[ [-1, -1, 0], [ 1, -1, 0], [ 0, 1, 0], ]])
......
while gui.running: mesh.set_face_verts(verts)
scene.render()
gui.set_image(scene.img) gui.show()
|
设置相机,轮询 gui 的鼠标事件:
- 依靠鼠标中键拖动相机视角:
- 滚轮拉近和远离;
- 按
Tab
键切换“透视模式”和“正交模式”
1 2 3
| while gui.running: scene.input(gui) ......
|
2.4 示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import taichi as ti import numpy as np import tina
verts = np.array([[ [-1, -1, 0], [ 1, -1, 0], [ 0, 1, 0], ]])
scene = tina.Scene()
mesh = tina.MeshNoCulling(tina.MeshGrid(32)) scene.add_object(mesh)
gui = ti.GUI('Triangle')
while gui.running: scene.input(gui) scene.render() mesh.set_face_verts(verts) gui.set_image(scene.img) gui.show()
|
3. 网格
3.1 简单网格
1
| mesh = tina.MeshNoCulling(tina.MeshGrid(32))
|
生成一个 32×32 的网格:

调整一下 [16, 16] 顶点的坐标:
1
| mesh.pos[16, 16].z += 0.3
|
网格发生变化:

可以对网格内的顶点进行遍历:
1 2 3 4
| @ti.kernel def deform(): for i, j in mesh.pos: mesh.pos[i, j].z = 0.2 * ti.exp(-0.1 * ((i-16)**2 + (j-16)**2))
|

4. 粒子
4.1 创建粒子模型
1
| model = tina.SimpleParticles(maxpars=n_particles)
|
4.2 设置粒子参数
4.2.1 位置参数
位置参数是一个 maxpars x 3
的矩阵:
1 2 3 4 5 6
| pos = np.empty((n_particles, 3), dtype=np.float32) pos = np.zeros((n_particles, 3), dtype=np.float32) pos = np.ones((n_particles, 3), dtype=np.float32)
pos = (ti.Vector.field(3, float, n_particles)).to_numpy()
|
使用示例
1 2 3 4 5 6 7 8 9 10
| ......
pos = (ti.Vector.field(3, float, n_particles)).to_numpy() ......
while gui.running: ...... model.set_particles(pos) ......
|
4.2.2 半径参数
位置参数是一个 maxpars x 1
的矩阵:
1 2 3 4 5 6 7 8 9 10
| ......
radii = np.ones(n_particles,dtype=np.float32) * 0.02 ......
while gui.running: ...... model.set_particle_radii(radii) ......
|
4.2.3 颜色参数
颜色参数是一个 maxpars x 3
的矩阵:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ......
colors = np.ones((n_particles, 3), dtype=np.float32)
for icolor in colors: icolor[1] = 0 ......
while gui.running: ...... model.set_particle_colors(colors) ......
|
4.3 给粒子添加 Mesh
4.3.1 参考文档
源码使用的 Marching Cube 算法实现:
《水泡动画模拟(Marching Cubes)》
4.3.2 使用示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| scene = tina.Scene(smoothing=True,ssao=True)
mciso = tina.MCISO((n_grid * 1.25, n_grid * 1.25, n_grid * 1.25)) scene.add_object(mciso)
......
while gui.running: ......
mciso.march(x, w0=2, rad=0, sig=0)
scene.render() gui.set_image(scene.img) gui.show()
|
4.3.3 应用变换
使用网格模型的变换
1 2 3 4 5 6 7 8 9 10 11 12
| scene = tina.Scene(smoothing=True,ssao=True) mciso = tina.MCISO((n_grid * 1.25, n_grid * 1.25, n_grid * 1.25)) mciso = tina.MeshTransform(mciso)
scene.add_object(mciso)
transformMatrix = tina.translate([-0.5, -0.5, -0.5]) transformMatrix = tina.scale([2., 2., 2.]) @ transformMatrix mciso.set_transform(transformMatrix)
|
5. 立方体
5.1 创建立方体模型
1
| volume = tina.SimpleVolume(32)
|
5.2 加载 .npy 二进制数据
1 2 3 4 5
| dens = np.load('assets/smoke.npy')
scene = tina.Scene(N=dens.shape[0], taa=True, density=16) volume = tina.SimpleVolume(N=dens.shape[0]) scene.add_object(volume)
|
6. 其他基础元件
6.1 球体
6.1.1 创建
1 2 3 4 5
| scene = tina.Scene()
ball = tina.PrimitiveMesh.sphere()
scene.add_object(ball)
|
6.1.2 设置
1 2 3 4 5 6 7 8
| while gui.running: .......
ball_tran_matrix = tina.scale(ball_radius) ball_tran_matrix = tina.translate(ball_vel[None].value) @ ball_tran_matrix ball.set_transform(ball_tran_matrix)
......
|
6.2 圆柱体
6.2.1 创建
1 2 3 4 5
| scene = tina.Scene()
bucket = tina.PrimitiveMesh.cylinder()
scene.add_object(bucket)
|
6.2.2 设置
1 2 3 4 5 6 7 8
| while gui.running: .......
bucket_tran_matrix = tina.scale(bucket_radius) bucket_tran_matrix = tina.translate(bucket_vel[None].value) @ bucket_tran_matrix bucket.set_transform(bucket_tran_matrix)
......
|
7. 模型
7.1 加载模型
1 2
| model = tina.MeshModel('assets/monkey.obj') scene.add_object(model)
|
可以增加模型载入的数量:
1
| scene = tina.Scene(maxfaces=2**18)
|
7.2 材质
7.2.1 初始化材质对象
1 2 3
| roughness = tina.Param(float, initial=0) metallic = tina.Param(float, initial=0) material = tina.PBR(metallic=metallic, roughness=roughness)
|
或者使用
1
| material = tina.CookTorrance(roughness=0.1, fresnel=0.9)
|
参 数 |
含 义 |
roughness |
粗糙度 |
fresnel |
菲尼尔反射效应:在掠射角的角度,光照结果会更亮一些 |
7.2.2 示例代码
1 2 3 4
| model = tina.MeshModel('assets/monkey.obj') material = tina.CookTorrance(roughness=0.1, fresnel=0.9)
scene.add_object(model, material)
|
7.3 光源
1 2 3 4 5 6 7 8 9 10
| scene.lighting.clear_lights()
scene.lighting.add_light(pos=[0, 1, 0], color=[1, 0, 0])
scene.lighting.add_light(dir=[1, 1, 0])
scene.lighting.set_ambient_light(color=[0.2, 0.1, 0.1])
|
8. 变换
8.1 激活变换
网格模型 :
1
| model = tina.MeshTransform(model)
|
粒子模型 :
1
| model = tina.ParsTransform(model)
|
8.2 构造变换矩阵
《欧拉角,四元数,旋转矩阵相互转化》
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| transformMatrix = tina.translate([-0.5, -0.5, -0.5])
transformMatrix = tina.scale([2., 2., 2.]) @ transformMatrix
transformMatrix = tina.eularXYZ([0., 2., 0.]) @ transformMatrix
transformMatrix = tina.quaternion([1., 0., 0., 0.]) @ transformMatrix
......
|
8.3 设置变换
网格模型 :
1 2
| model.set_transform(transformMatrix)
|
粒子模型 :
1 2
| model.set_transform(transformMatrix, 1)
|
9. 其他基础功能
9.1 面剔除
Tina
是默认是开启面剔除功能的,所以需要三角形两面都显示的情况时,可以在“创建场景对象”的时候声明:
1
| scene = tina.Scene(culling=False)
|
但是这种方式获得的三角形反面法线是相反的,这时推荐渲染正反两个三角形面:
1 2 3 4 5 6 7 8 9
| verts = np.array([[ [-1, -1, 0], [ 1, -1, 0], [ 0, 1, 0], ],[ [ 1, -1, 0], [-1, -1, 0], [ 0, 1, 0], ]])
|
同时,可以在“创建网格对象”的阶段声明以下语句,来取消剔除功能:
1
| mesh = tina.MeshNoCulling(tina.SimpleMesh())
|
9.2 抗锯齿
可以在“创建场景对象”阶段开启 TAA 选项(静止时按帧周期性变动采样点):
1
| scene = tina.Scene(taa=True)
|
9.3 平滑着色
可以在“创建场景对象”阶段开启光滑着色,尤其适合在网格中使用:
1
| scene = tina.Scene(smoothing=True)
|
同时也可以在“创建网格对象”的阶段取消平滑着色,锐化法线信息:
1
| mesh = tina.MeshFlatNormal(tina.MeshNoCulling(tina.MeshGrid(32)))
|
9.4 屏幕空间环境光遮罩
环境遮罩之SSAO原理
1
| scene = tina.Scene(ssao=True)
|
9.5 天空盒
9.5.1 激活天空盒
1
| scene = tina.Scene(smoothing=True, taa=True, ibl=True)
|
9.5.2 设置天空盒
目前暂时需要在源码 raster.py
(Line:30,31) 中更改:
1 2
| skybox = tina.Skybox(skybox.resolution).cook_from(skybox)
|
通过注释进行切换,选择使用缺省值或者使用路径中的天空盒素材
10. 资源导出
10.1 导出图片
1 2 3 4 5 6 7 8 9 10 11 12 13
| flame = 0
while gui.running: scene.input(gui) ...... scene.render() gui.set_image(scene.img) ...... filename = 'OutPng\\output_png_{:04d}.png'.format(flame) ti.imwrite(scene.img, filename) flame += 1 ...... gui.show()
|
Note :
- 使用
gui.show(filename)
无法正常导出。