GUI 绘制点时出现错误的颜色

背景

想写一个简化的粒子法程序,用 GUI 渲染。

问题

在生成粒子位置信息后,使用 palette 渲染两种不同的粒子时出现了颜色错误的情况,如下图所示,而且改变粒子大小后依然是左下角的这四个粒子颜色错误。另外,这四个粒子的颜色还会不定地变化一下,不过待一会儿之后还是变成正确的颜色。

image

使用 1.2.2 版本和 1.4.1 版本的CPUCUDA都会这样。虽然不影响使用但感觉很奇怪,说不定是个bug?

简单代码如下:

import taichi as ti
import numpy as np
from functools import reduce

ti.init(arch=ti.cuda)

# Simulation parameters
dim = 2
dx = 0.1

# Simulation geometries
domain_size = np.array([6.0, 4.0])
cube_size, cube_translation = [2.0, 1.0], [0.5, 0.5]
dummy_layer = 3
dummy_b_size, dummy_b_translation = [domain_size[0] - 1.0 + 2*dummy_layer*dx, dummy_layer*dx], [0.5 - dummy_layer*dx, 0.5 - dummy_layer*dx]

# GUI parameters
screen_to_world_ratio = 150
res = np.array(domain_size * (screen_to_world_ratio * 1.05), dtype=np.int32)
bg_colour = 0x112f41
colour_water = 0x068587
colour_dummy = 0x8e8e8e
colour_palette = [colour_water, colour_dummy]

@ti.dataclass
class Particle:
    x: ti.types.vector(2, float)
    type: int   # 1: water, -1: dummy
    colour_indices: int

def calc_cube_particle_num(size, translation, dim=2, offset=None):
    num_dim = []
    range_offset = offset if offset is not None else 0.1
    for i in range(dim):
        off = range_offset if size[i] >= 0 else -range_offset
        num_dim.append(np.arange(translation[i] + off / 2.0, translation[i] + size[i] + 1e-5, off))
    return reduce(lambda x, y: x * y, [len(n) for n in num_dim]), num_dim

# Geometries
pt_num = ti.field(int, shape=())
pt_num_water, num_dim_water = calc_cube_particle_num(size=cube_size, translation=cube_translation, dim=dim, offset=dx)
pt_num_dummy_b, num_dim_dummy_b = calc_cube_particle_num(size=dummy_b_size, translation=dummy_b_translation, dim=dim, offset=dx)
pt_num[None] = pt_num_water + pt_num_dummy_b
new_pos_water = np.array(np.meshgrid(*num_dim_water, sparse=False, indexing='ij'), dtype=np.float32).reshape(-1, pt_num_water).transpose()
new_pos_dummy_b = np.array(np.meshgrid(*num_dim_dummy_b, sparse=False, indexing='ij'), dtype=np.float32).reshape(-1, pt_num_dummy_b).transpose()
new_pos = np.concatenate((new_pos_water, new_pos_dummy_b), axis=0)
pt = Particle.field(shape=pt_num[None])
pt.x.from_numpy(new_pos)

@ti.kernel
def init_pts():
    for i in range(pt_num[None]):
        if i < pt_num_water:
            pt[i].type = 1
            pt[i].colour_indices = 0
        else:
            pt[i].type = -1
            pt[i].colour_indices = 1

def render(gui):
    gui.clear(bg_colour)
    pos_np = pt.x.to_numpy()
    for j in range(dim):
        pos_np[:, j] *= screen_to_world_ratio / res[j]
    gui.circles(pos_np, radius=dx/2*screen_to_world_ratio, palette = colour_palette, palette_indices=pt.colour_indices)
    gui.show()

def main():
    init_pts()
    print(f"dx = {dx}, total pts {pt_num[None]}, water pts {pt_num_water}, dummy pts {pt_num[None] - pt_num_water}")
    gui = ti.GUI("test", res)
    while gui.running and not gui.get_event(gui.ESCAPE):
        render(gui)

if __name__ == '__main__':
    main()
1 个赞