【GAMES201学习笔记】00 - Taichi三维可视化 - Taichi_THREE

1. 开始之前

1.1 学习资源链接

Taichi_THREE 原作者的教程视频:
https://www.bilibili.com/video/av628129594

github 链接:
https://github.com/taichi-dev/taichi_three#how-to-play

  • 运行程序之前记得将资源文件夹 assets 分别复制进 docsexample 文件目录下。

screenShot.png

1.2 安装

  • 运行是基于 Taichi 环境:
python3 -m pip install taichi
  • 安装 Taichi THREE
python3 -m pip install taichi-tina

具体安装流程见官方文档:

2. 你好,三角形

2.1 坐标系

Tina 使用的右手坐标系:

screenShot.png

2.2 创建窗口

import taichi as ti
import tina

# 创建场景对象 scene
scene = tina.Scene()

# 创建一个 SimpleMesh 类的网格对象 mesh ,绑定和设置到 scene
mesh = tina.SimpleMesh()
scene.add_object(mesh)

# 初始化 taichi 的一个 gui 对象
gui = ti.GUI('simple triangle')

# 渲染循环
while gui.running:
    # 渲染 scene
    scene.render()

    # 将获得的像素信息传递给 gui 渲染出来
    gui.set_image(scene.img)
    gui.show()

得到一个空白窗口:

screenShot.png

2.3 设置顶点数据

# 维护顶点数据
# 注意是三角形数组,该处只有一个三角形
verts = np.array([[
    [-1, -1,  0],  # vertex 1
    [ 1, -1,  0],  # vertex 2
    [ 0,  1,  0],  # vertex 3
    ]])

......

# 渲染循环
while gui.running:
    # 绑定和设置 VAO
    mesh.set_face_verts(verts)

    # 渲染 scene
    scene.render()

    # 将获得的像素信息传递给 gui 渲染出来
    gui.set_image(scene.img)
    gui.show()

设置相机,轮询 gui 的鼠标事件:

  • 依靠鼠标中键拖动相机视角:
  • 滚轮拉近和远离;
  • Tab 键切换“透视模式”和“正交模式”
while gui.running:
    scene.input(gui)
    ......

2.4 示例代码

import taichi as ti
import numpy as np
import tina

verts = np.array([[
    [-1, -1,  0],  # vertex 1
    [ 1, -1,  0],  # vertex 2
    [ 0,  1,  0],  # vertex 3
    ]])

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 简单网格

mesh = tina.MeshNoCulling(tina.MeshGrid(32))

生成一个 32×32 的网格:

screenShot.png

调整一下 [16, 16] 顶点的坐标:

mesh.pos[16, 16].z += 0.3

网格发生变化:

screenShot.png

可以对网格内的顶点进行遍历:

@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))

screenShot.png

4. 粒子

4.1 创建粒子模型

model = tina.SimpleParticles(maxpars=n_particles)

4.2 设置粒子参数

4.2.1 位置参数

位置参数是一个 maxpars x 3 的矩阵:

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)

# taichi 中的变量需要进行转换
pos = (ti.Vector.field(3, float, n_particles)).to_numpy()

使用示例

......
# 传递粒子数组的位置
pos = (ti.Vector.field(3, float, n_particles)).to_numpy()
......

# 渲染循环
while gui.running:
    ......
    model.set_particles(pos)
    ......

4.2.2 半径参数

位置参数是一个 maxpars x 1 的矩阵:

......
# 传递粒子半径的数组
radii = np.ones(n_particles,dtype=np.float32) * 0.02
......

# 渲染循环
while gui.running:
    ......
    model.set_particle_radii(radii)
    ......

4.2.3 颜色参数

颜色参数是一个 maxpars x 3 的矩阵:

......
# 参数是一个 n_particles x 3 的矩阵
colors = np.ones((n_particles, 3), dtype=np.float32)

# 将颜色的 G 通道置为 0 
# (255, 255, 255) => (255, 0, 255)
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 使用示例

# 开启平滑着色和 SSAO
scene = tina.Scene(smoothing=True,ssao=True)

# 设置分辨率(例中将分辨率提高到了 1.25)
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. 初始化
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)

# 2. 绑定
scene.add_object(mciso)

# 3. 设置变换
transformMatrix = tina.translate([-0.5, -0.5, -0.5])
transformMatrix = tina.scale([2., 2., 2.]) @ transformMatrix
mciso.set_transform(transformMatrix)

5. 立方体

5.1 创建立方体模型

volume = tina.SimpleVolume(32)

5.2 加载 .npy 二进制数据

dens = np.load('assets/smoke.npy')
# density:密度
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 创建

scene = tina.Scene()

ball = tina.PrimitiveMesh.sphere()

scene.add_object(ball)

6.1.2 设置

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 创建

scene = tina.Scene()

bucket = tina.PrimitiveMesh.cylinder()

scene.add_object(bucket)

6.2.2 设置

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 加载模型

model = tina.MeshModel('assets/monkey.obj')
scene.add_object(model)

可以增加模型载入的数量:

scene = tina.Scene(maxfaces=2**18)

7.2 材质

7.2.1 初始化材质对象

roughness = tina.Param(float, initial=0)#.15)
metallic = tina.Param(float, initial=0)#.25)
material = tina.PBR(metallic=metallic, roughness=roughness)

或者使用

material = tina.CookTorrance(roughness=0.1, fresnel=0.9)
参 数含 义
roughness粗糙度
fresnel菲尼尔反射效应:在掠射角的角度,光照结果会更亮一些

7.2.2 示例代码

model = tina.MeshModel('assets/monkey.obj')
material = tina.CookTorrance(roughness=0.1, fresnel=0.9)

scene.add_object(model, material)

7.3 光源

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 激活变换

网格模型

model = tina.MeshTransform(model)

粒子模型

model = tina.ParsTransform(model)

8.2 构造变换矩阵

《欧拉角,四元数,旋转矩阵相互转化》

# 设置一个位移变换
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 设置变换

网格模型

# 设置网格变换
model.set_transform(transformMatrix)

粒子模型

# 设置粒子变换(第二个参数是 scale :调整的是单个粒子的大小)
model.set_transform(transformMatrix, 1)

9. 其他基础功能

9.1 面剔除

Tina 是默认是开启面剔除功能的,所以需要三角形两面都显示的情况时,可以在“创建场景对象”的时候声明:

scene = tina.Scene(culling=False)

但是这种方式获得的三角形反面法线是相反的,这时推荐渲染正反两个三角形面:

verts = np.array([[
    [-1, -1,  0],  # vertex 1
    [ 1, -1,  0],  # vertex 2
    [ 0,  1,  0],  # vertex 3
    ],[
    [ 1, -1,  0],  # vertex 1
    [-1, -1,  0],  # vertex 2
    [ 0,  1,  0],  # vertex 3
    ]])

同时,可以在“创建网格对象”的阶段声明以下语句,来取消剔除功能:

mesh = tina.MeshNoCulling(tina.SimpleMesh())

9.2 抗锯齿

可以在“创建场景对象”阶段开启 TAA 选项(静止时按帧周期性变动采样点):

scene = tina.Scene(taa=True)

9.3 平滑着色

可以在“创建场景对象”阶段开启光滑着色,尤其适合在网格中使用:

scene = tina.Scene(smoothing=True)

同时也可以在“创建网格对象”的阶段取消平滑着色,锐化法线信息:

mesh = tina.MeshFlatNormal(tina.MeshNoCulling(tina.MeshGrid(32)))

9.4 屏幕空间环境光遮罩

环境遮罩之SSAO原理

scene = tina.Scene(ssao=True)

9.5 天空盒

9.5.1 激活天空盒

scene = tina.Scene(smoothing=True, taa=True, ibl=True)

9.5.2 设置天空盒

目前暂时需要在源码 raster.py(Line:30,31) 中更改:

skybox = tina.Skybox(skybox.resolution).cook_from(skybox)
# skybox = tina.Skybox('assets/skybox.jpg', cubic=True)

通过注释进行切换,选择使用缺省值或者使用路径中的天空盒素材

10. 资源导出

10.1 导出图片

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) 无法正常导出。
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值