如下的代码中,在kernel中建立了一个100^3的点,并投影回相机平面。
render_proj(param)
这个kernel接受一个完全没用到的ti.template()
参数。
当这个param是一个field
时,帧率在显示器上限165 FPS。
当这个param是field[0]
时,帧率降到10FPS。
请问为什么会这样…
ti.template()
如果不能接受 filed[n]
,是不是应该有一些提示…
如果能接受,为什么速度差别这么大。。
import taichi as ti
@ti.func
def vec3_x_mat4(vec: ti.template(), mat: ti.template()):
rst0 = mat[0,0] * vec[0] + mat[0,1] * vec[1] + mat[0,2] * vec[2] + mat[0,3]
rst1 = mat[1,0] * vec[0] + mat[1,1] * vec[1] + mat[1,2] * vec[2] + mat[1,3]
rst2 = mat[2,0] * vec[0] + mat[2,1] * vec[1] + mat[2,2] * vec[2] + mat[2,3]
rst3 = mat[3,0] * vec[0] + mat[3,1] * vec[1] + mat[3,2] * vec[2] + mat[3,3]
return ti.Vector([rst0, rst1, rst2, rst3])
@ti.func
def vec4_x_mat4(vec: ti.template(), mat: ti.template()):
rst0 = mat[0,0] * vec[0] + mat[0,1] * vec[1] + mat[0,2] * vec[2] + mat[0,3] * vec[3]
rst1 = mat[1,0] * vec[0] + mat[1,1] * vec[1] + mat[1,2] * vec[2] + mat[1,3] * vec[3]
rst2 = mat[2,0] * vec[0] + mat[2,1] * vec[1] + mat[2,2] * vec[2] + mat[2,3] * vec[3]
rst3 = mat[3,0] * vec[0] + mat[3,1] * vec[1] + mat[3,2] * vec[2] + mat[3,3] * vec[3]
return ti.Vector([rst0, rst1, rst2, rst3])
@ti.data_oriented
class Viewer:
def __init__(self) -> None:
self.window = ti.ui.Window("Viewer", (1080, 720))
self.gui = self.window.get_gui()
self.canvas = self.window.get_canvas()
# camera settings
self.camera = ti.ui.Camera() # by default, look at (0, 0, 1)
self.camera.position(1000, 1000, 1000)
self.camera.lookat(50, 50, 50)
self._img = ti.Vector.field(3, ti.f32, (1080, 720))
self._mat_view = ti.Matrix.field(4,4, ti.f32, shape=())
self._mat_proj = ti.Matrix.field(4,4, ti.f32, shape=())
############## dummy param for test
self.param = ti.Vector.field(3, ti.f64, 1000)
##############
def render_proj(self):
self._mat_view.from_numpy(self.camera.get_view_matrix().T)
self._mat_proj.from_numpy(self.camera.get_projection_matrix(1080/720))
# self._render_k(self.param[0]) ###### 10 FPS
self._render_k(self.param) ###### 165 FPS
def run(self):
while self.window.running:
# gui
self.render_proj()
self.canvas.set_image(self._img)
self.window.show()
@ti.kernel
def _render_k(self,
p1: ti.template(),
):
for i,j,k in ti.ndrange(100, 100, 100):
x_w = i
y_w = j
z_w = k
# projection to self._img
xyz_w = ti.Vector([x_w, y_w, z_w])
xyzw_e = vec3_x_mat4(xyz_w, self._mat_view[None])
xyzw_c = vec4_x_mat4(xyzw_e, self._mat_proj[None])
# culling
x_c = xyzw_c[0]
y_c = xyzw_c[1]
z_c = xyzw_c[2]
w_c = xyzw_c[3]
x_c /= w_c
y_c /= w_c
z_c /= w_c
if x_c < -1 or x_c > 1 or y_c < -1 or y_c > 1 or z_c < -1 or z_c > 1:
continue
# project to camera plane
row = y_c * 360 + 360
col = x_c * 540 + 540
rowi = ti.i32(row)
coli = ti.i32(col)
self._img[coli, rowi][0] = 1.0
self._img[coli, rowi][1] = 1.0
self._img[coli, rowi][2] = 1.0
ti.init(ti.cuda)
viewer = Viewer()
viewer.run()