Hello, everyone! I made a 3D renderer based on Taichi.
You could make use of it in your own projects for visualizing 3D scenes in real-time.
It uses rasterizaion for triangle meshes, runs extremely fast even on CPU.
It also supports loading OBJ models, binding textures, and PBR materials.
The project is still at its early stage and your contribution are more than appreaciated!
So please feel free to contribute if you got a good idea by opening an issue or PR on GitHub: GitHub - taichi-dev/taichi_three: A soft renderer based on Taichi (work in progress)
You could easily install it by:
python3 -m pip install taichi_three==0.0.8 # examples shown below are API v0.0.8
It has a node-based API (for meshes and materials).
For example, to display a cube:
import taichi as ti
import taichi_three as t3
scene = t3.Scene()
camera = t3.Camera()
scene.add_camera(camera)
light = t3.Light(dir=[-0.2, -0.6, -1.0])
scene.add_light(light)
model = t3.Model(t3.Mesh.from_obj(t3.Geometry.cube()))
scene.add_model(model)
gui = ti.GUI('Hello Cube')
while gui.running:
gui.get_event(None)
camera.from_mouse(gui)
scene.render()
gui.set_image(camera.img)
gui.show()
to visualize a sinc wave as animation:
import taichi as ti
import taichi_three as t3
ti.init(ti.cpu)
scene = t3.Scene()
mesh = t3.MeshGrid((128, 128)) # create a mesh grid
model = t3.Model(t3.QuadToTri(mesh)) # only triangle meshes are directly renderable
scene.add_model(model) # add the renderable model
camera = t3.Camera()
camera.ctl = t3.CameraCtl(pos=[1.1, 1.6, 1.6]) # set camera position
scene.add_camera(camera)
light = t3.Light(dir=[0.4, -1.5, -0.8])
scene.add_light(light)
@ti.func
def Z(xy, t):
return 0.1 * ti.sin(10 * xy.norm() - t3.tau * t) # sinc wave
@ti.kernel
def deform_mesh(t: float):
for i, j in mesh.pos:
mesh.pos[i, j].y = Z(mesh.pos[i, j].xZ, t) # deform mesh by updating position
gui = ti.GUI('Meshgrid')
while gui.running:
gui.get_event(None)
camera.from_mouse(gui) # this allows you to turn around by LMB drag
deform_mesh(gui.frame * 0.03)
scene.render()
gui.set_image(camera.img)
gui.show()
We also support physically-based rendering (PBR):
import taichi as ti
import taichi_three as t3
import numpy as np
ti.init(ti.cpu)
scene = t3.Scene()
model = t3.Model(t3.Mesh.from_obj(t3.readobj('assets/torus.obj', scale=0.8)))
model.material = t3.Material(t3.CookTorrance(
color=t3.Texture(ti.imread('assets/cloth.jpg')),
roughness=t3.Texture(ti.imread('assets/pattern.jpg')),
metallic=t3.Constant(0.5),
))
scene.add_model(model)
camera = t3.Camera()
camera.ctl = t3.CameraCtl(pos=[0.8, 0, 2.5])
scene.add_camera(camera)
light = t3.Light([0, -0.5, -1])
scene.add_light(light)
ambient = t3.AmbientLight(0.3)
scene.add_light(ambient)
gui = ti.GUI('Model', camera.res)
while gui.running:
gui.get_event(None)
gui.running = not gui.is_pressed(ti.GUI.ESCAPE)
camera.from_mouse(gui)
model.L2W[None] = t3.rotateX(angle=t3.get_time())
scene.render()
gui.set_image(camera.img)
gui.show()
You may use LMB to orbit around the object, MMB to move, RMB to scale.
More details are provided in the documentation (work in progress): https://t3.142857.red
Please let me know if you’re interested or have cool suggestions!