python中math库最大值_哪些 Python 库让你相见恨晚?

众所周知,计算机图形学由于其需要的计算量大,常见的编程语言都是C或C++等编译型语言,或者是CUDA和GLSL等GPU编程语言,而Python由于性能问题而无法直接参与其中。

因此 @胡渊鸣 同学发起了 Taichi 这个项目,它可以将 Python 函数转译成高效的 CPU / GPU 汇编,从而保证效率同时,又能直接以 Python 编写和调用。 有了 Taichi,我们就可以用 Python 语言玩转计算机图形学啦!

案例0:

import taichi as ti

# 声明一个数据类型为浮点数,大小为 512x512x3 的场,3 个分量分别储存 (R, G, B)

pixels = ti.field(dtype=float, shape=(512, 512, 3))

@ti.kernel # 指定要编译的核函数

def paint():

for i, j in ti.ndrange(512, 512): # 自动并行化遍历

r = i / 512

g = j / 512

b = 0.5

pixels[i, j, 0] = r

pixels[i, j, 1] = g

pixels[i, j, 2] = b

gui = ti.GUI("Hello, Taichi", (512, 512))

while gui.running:

paint()

gui.set_image(pixels) # 按 RGB 格式显示图片

gui.show()

成功运行以上代码将得到:

知识点0.0:pixels = ti.field(dtype=float, shape=(512, 512, 3))

ti.field 用于声明一个场,Taichi 中一切数据都以场的形式存储。

其中 dtype 参数指定场中元素的数据类型,可以是浮点或整型,我们这里选择浮点型。

其中 shape 参数指定场指定场的形状,相当于数组的大小。

知识点0.1:@ti.kernel装饰的函数,将会被 Taichi 的 JIT 引擎编译。

知识点0.2:for i, j in ti.ndrange(512, 512): Taichi 中的最外层循环将会被并行执行以求更高的效率。

知识点0.3:pixels[i, j, 0] = r,我们可以通过下标索引的方式读写场中元素,索引要和场的 shape 一一对应。

知识点0.4:gui = ti.GUI("Hello, Taichi", (512, 512)),Taichi 有一个内置的 GUI 系统方便可视化。你也可以使用其他库比如 matplotlib 来可视化,下面会说到。

案例1:添加参数

import taichi as ti

import time

pixels = ti.field(dtype=float, shape=(512, 512, 3))

@ti.kernel

def paint(t: float): # 指定参数类型

for i, j in ti.ndrange(512, 512):

r = i / 512

g = j / 512

b = ti.sin(t) * 0.5 + 0.5 # 使用 sin 让蓝色分量反复跳动

pixels[i, j, 0] = r

pixels[i, j, 1] = g

pixels[i, j, 2] = b

gui = ti.GUI("Hello, Taichi", (512, 512))

while gui.running:

paint(gui.frame * 0.04) # 当前第几帧 * 0.04

gui.set_image(pixels)

gui.show()

运行以上代码将得到蓝色通道不断忽明忽暗的图像。

知识点1.1:def paint(t: float): Taichi kernel 的参数和普通 Python 函数不一样,必须用参数名 : 类型名的格式指定,以便进行静态编译。

知识点1.2:ti.sin 是 Taichi 提供的基础数学函数之一,由于 Taichi 程序实际执行在 Python 以外的地方,math.sin 或 np.sin 不会有效。

怎么样,是不是感觉已经可以用 Taichi 写一个 raytracer 了?别着急,你可能还需要一个东西……

案例2:玩转矢量

在计算机图形学中最经常用到的一个东西应该就是矢量了吧,因此 Taichi 也有内置对矢量和矩阵的支持。

比如我们把刚才那个案例的 RGB 通道换成用矢量的 XYZ 分量来存储:

import taichi as ti

import time

# 声明一个 512x512 的场,每个元素都是一个 3 维矢量(RGB 颜色)

pixels = ti.Vector.field(n=3, dtype=float, shape=(512, 512))

@ti.kernel

def paint(t: float):

for i, j in ti.ndrange(512, 512):

r = i / 512

g = j / 512

b = ti.sin(t) * 0.5 + 0.5

pixels[i, j].x = r # 访问矢量的分量

pixels[i, j].y = g

pixels[i, j].z = b

# pixels[i, j] = ti.Vector([r, g, b]) # 或者直接构造矢量

gui = ti.GUI("Hello, Taichi", (512, 512))

while gui.running:

paint(gui.frame * 0.04)

gui.set_image(pixels)

gui.show()

知识点2.0:ti.Vector.field用法基本和ti.field一样,不过多了一个参数 n 指定矢量的维数,这里我们要存储 RGB 格式的颜色,因此选择 3。

知识点2.1:你可以使用v.x,v.y,v.z读写矢量的各个分量。

知识点2.2:也可以直接从 n 个分量构造一个新的矢量:ti.Vector([x, y, z])

矢量的更多方法,比如 magnitude,normalize 等,可以在 Taichi 官方文档中查到:

Vectors - taichi 0.6.29 documentation

案例3:导出数据到 NumPy 数组

在 Taichi 的场中处理完数据后,我们还可以将其数据导出到一个 NumPy 数组以便和其他包交互。

import matplotlib.image as mp

import taichi as ti

pixels = ti.Vector.field(n=3, dtype=float, shape=(512, 512))

@ti.kernel

def paint(t: float):

for i, j in ti.ndrange(512, 512):

r = i / 512

g = j / 512

b = ti.sin(t) * 0.5 + 0.5

pixels[i, j].x = r

pixels[i, j].y = g

pixels[i, j].z = b

# pixels[i, j] = ti.Vector([r, g, b])

paint(0)

pixels_np = pixels.to_numpy() # 转换成 matplotlib 能够识别的 NumPy 数组

mp.imsave('hello.png', pixels_np)

知识点3.0:pixels.to_numpy(),使用to_numpy() 获取 Taichi 场中当前的数据,以 NumPy 数组的形式返回。

知识点3.1:pixels.from_numpy(xxx),使用from_numpy(xxx) 将 Taichi 场中的数据设置为 NumPy 数组 xxx的数据,通常用于初始化。

知识点3.2:mp.imsave('hello.png', pixels_np),这是把 pixels_np 这个 NumPy 数组交给了 Matplotlib 处理,Taichi 与其他包的交互大多都是通过 NumPy 实现的。

好啦,相信大家对 Taichi 的目标和已经有所了解了,那就是用 Python 编写着色器!而且还是 compute shader!

没错,实际上 Taichi 具有很多个后端,可以在初始化的时候指定,比如 ti.init(ti.opengl)就会选用 OpenGL compute shader 在 GPU 上运行程序。默认的话就是 CPU 上并行运行的。

其实 Taichi 的能力还远不止是图像渲染,包括粒子、流体等的物理模拟也都能完全胜任。

Taichi 可以使用 pip 安装(需要 Python 3.6 及以上,64位):

python3 -m pip install taichi

今天就写到这里,有空再加点关于物理模拟的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值