查看原文
其他

搭建体素世界,真没想象中那么难… | Taichi 入门秘籍

Taichi 编辑部 太极图形 2023-03-21


首届 Taichi 体素创意大赛已于 4 月 29 日正式开始,开赛以来我们收到了 40+ 份充满创意的作品,从游戏动漫到人物建筑,很难想象这些作品都是在 99 行代码内完成的!(*比赛仍在进行中,投稿时间截止到 5 月 18 日下午 5 点)


部分参赛作品👏🏻👏🏻👏🏻


看到这些精美的作品,相信还有很多小伙伴也跃跃欲试,想要参与其中。今天编辑部特意呈上一份参赛贴士,帮助大家快速入门 Taichi,开启体素创意之旅。


1

安装 Taichi



首先确保你的 pip 已经是最新版本,否则可能会报 GGUI 找不到的错误:

pip3 install pip --upgrade

如果第一次安装 Taichi 请确保在 Python 3.6/3.7/3.8/3.9/3.10 (64-bit)环境下输入这个命令:

pip3 install -r requirements.txt

如有其他问题,可以加入赛事交流群提问,进群方式请见文末。



2

配置 voxel editor



💻 打开 https://github.com/taichi-dev/voxel-challenge/

1️⃣ 在 repo 页面中,点击「Use this template」按钮;


2️⃣ 在打开的页面中,选择 owner 为你自己,并填写项目名称;

3️⃣ Repo 权限需选择 Public;


4️⃣ Download ZIP 将示例代码下载到本地;

5️⃣ 在自己的本地终端/ VS code 运行示例,感受 voxel editor 的效果,例如运行 example1.py 文件;

python3 example1.py

6️⃣ 随后可以打开 py 文件,开始修改代码, DIY 自己的作品。


⚠️ 请记得将 Taichi 升级到 v1.0.1 版本,才可顺利使用 voxel renderer。升级命令为:

python3 -m pip install --upgrade taichi

⚠️ 再次强调:每个参赛者拥有 128x128x128 的网格。每个网格大小是 1/64,也就是说整个网格的 x, y, z 坐标范围是 [-1, 1]。注意网格的下标的每个维度从 -64 开始,一直到 63 结束。下标可以是负数。

3

Taichi 函数那些事儿



Taichi 和 Python 语法基本一致,你需要注意的是使用 Taichi 编写程序要注意区分 Python scope 和 Taichi scope 这两个概念,Python scope 你可以理解为普通的 Python 代码,而  Taichi scope 则是指被 @ti.kernel 和 @ti.func 修饰的函数,这些函数是被 Taichi 接管和编译执行的。在 Taichi scope 中书写代码要遵循一定的限制条件,比如在 Taichi scope 中变量是有类型的,你不可以随意地将一个变量重新赋值为一个不同类型的变量:

v = ti.Vector([0, 0, 0])
v = 1.0

像上面这样把一个 Vector 类型的变量重新赋值为一个数字 1.0 是不行的。

什么是 @ti.kernel @ti.func 

ti.kernel 修饰的函数叫做 kernel 函数,kernel 函数是 Taichi 编译和运行的入口。一个程序里面可以有多个 kernel 函数,kernel 之间互相不能调用。

ti.func 修饰的函数叫做 func 函数,func 函数只能被其它 func 函数或者 kernel 调用。

在 kernel 函数中,顶层的 for 循环会被自动并行执行,非顶层的 for 循环则会被串行执行。

@ti.kernel
def example():
    for i in range(100): # top level and executed in parallel
        for j in range(100): # not top level, serialized
  
    for k in range(100): # another top level for loop and executed in parallel
        pass

如果你不想让 Taichi 并行执行某个顶层的 for 循环,可以用 ti.loop_config 把它关掉:

@ti.kernel
def example():
    ti.loop_config(serialize=True)
    for i in range(100): # top level but serialized

多层 for 循环技巧


在多层嵌套的 for 循环中,只有顶层的 for 循环是并行执行的。如果你希望它们全部是并行执行的也是可以的。Taichi 提供了类似标准库 itertools.product 的函数 ti.ndrange,可以让你同时遍历多个 range:

ti.ndrange(arg1, arg2, arg3, ...)

这其中,每一个 arg 都是一个整数,这时它相当于一个区间 range(n), 或者一对整数 (a, b),这时它相当于区间 range(a, b)ti.ndrange 会将所有这些区间组合成一个多维乘积:

for i, j, k in ti.ndrange(3, (1, 3), 5):
    print(i, j, k) # 遍历 i 从 0 到 2,j 从 1 到 2, k 从 0 到 4 的所有组合

使用随机数


ti.random() 会返回一个 [0,1) 区间中的浮点数,如果你想返回一个区间 [a, b) 内的随机数,可以用:

x = ti.random() * (b - a) + a

如果你想返回一个 n <= x < m 的整数 x,可以用:

x = int(ti.random() * (m - n)) + n

4

引用 Taichi math 模块



Taichi 的 math 模块的引用方式为:

import taichi.math as tm

或者

from taichi.math import *

目前 math 模块提供以下功能支持:

GLSL 风格的向量操作


数学模块提供了 vec2, vec3, vec4 三种浮点类型向量, ivec2, ivec3, ivec4 三种整数类型向量,以及 mat2, mat3, mat4 三种浮点矩阵。

你可以使用多种不同的方式声明一个向量,可以是一个数字,或者是数字/列表/向量/swizzle 的组合,在后者的情形只要它们的长度加起来等于向量类型的长度即可:

v = vec3(1, 2, 3)
v = vec3([1, 2, 3])
v = vec3([1, 2], 3)
v = vec3(v.xy, 1)
v = v.xxz

在访问向量分量时,你可以使用 xyzw, rgba, stpq 这几种方式,以及它们不同顺序的组合:其中 x/y/z/w 分别表示向量的第 0、1、2、3 个分量。rgbastpq 同理。

v.yxz += w # v 的 (1, 0, 2) 分量分别加上 w 的 (0, 1, 2) 分量
v.xx += 1 # v 的 0 分量两次加上 1

但是小心像下面这样赋值的写法是不行的哦:

v.xy = 1.0

因为这相当于把向量 v.xy 重新绑定为一个数值类型的值 1.0,这是不允许的。

GLSL 风格的函数


你可以使用如 smoothstep, clamp, mix, step 等常用的 glsl 函数。这些函数在构造几何形状时非常有用。这些函数同时接受向量和标量作为参数:

x = 1.0
x = smoothstep(0.0, 1.0, x)
y = vec3(1, 2, 3)
y = smoothstep(0.2, 0.8, y)

复数运算的支持


主要提供了对 vec2 类型的复数运算的支持。

z = vec2(1, 1) # 1 + 1j
w = vec2(-1, 1) # -1 + 1j
x = cmul(z, w) # complex multiplicaiton z * w
x = cdiv(z, w) # complex division z / w
x = cpow(w, 3) # complex power w^3
x = clog(w) # logarithm of w
x = cconj(w) # conjugate of w



看到这里,相信小伙伴们都已经初步掌握了搭建体素的方法,期待大家的作品!

更多参考资料尽在:
https://github.com/taichi-dev/community/blob/main/events/voxel-challenge/reference-zh_cn.md

完成作品后,请记得投稿哦,点击阅读原文直达投稿链接。

🗣

- 许愿时间 -


你还想了解哪些「体素创作小技巧」?


快来评论区说说~

下期或许就会告诉你答案


同时欢迎扫码添加小助手

回复「创意大赛」

进入赛事交流群

⬇️



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存