taichi-dev / taichi_three

A soft renderer based on Taichi (work in progress)
https://t3.142857.red/
MIT License
223 stars 24 forks source link

Simple triangle example doesn't work (Mesh culling func misses) #33

Open JerryYan97 opened 3 years ago

JerryYan97 commented 3 years ago

Hello! What should I do if I also want to keep the back face of a dynamic triangle?

https://github.com/taichi-dev/taichi_three/blob/master/examples/simple_triangle.py

archibate commented 3 years ago

Thank for asking, you may use the newly added t3.MeshNoCulling node. It was not available in v0.0.9 yet. To use it:

  1. you may clone this repo and install it manually to get this latest update (recommended):
    python3 -m pip uninstall -y taichi_three  # remove the old version
    python3 -m pip uninstall -y taichi_three  # double uninstall for sure
    git clone https://github.com/taichi-dev/taichi_three.git --depth=1
    cd taichi_three
    python3 -m pip install wheel  # required for building wheel
    python3 setup.py bdist_wheel  # create the wheel file
    python3 -m pip install dist/*.whl  # install the latest version
  2. copy and paste the source of t3.MeshNoCulling locally in your file:
    
    import taichi_three as t3
    import taichi as ti

@ti.data_oriented class MeshNoCulling: # the same one as taichi_three/model.py have in latest master branch def init(self, mesh): self.mesh = mesh

@property
def shape(self):
    return self.mesh.shape

@property
def static_shape(self):
    return [2, *self.mesh.static_shape]

def before_rendering(self):
    self.mesh.before_rendering()

@ti.func
def get_face(self, i, j: ti.template()):
    face = self.mesh.get_face(i, t3.ts.vec(*[j[_] for _ in range(1, j.n)]))
    ret = t3.DataOriented()
    if ti.static(j.x == 0):
        ret.__dict__.update(
            pos = [face.pos[i] for i in [0, 1, 2]],
            tex = [face.tex[i] for i in [0, 1, 2]],
            nrm = [face.nrm[i] for i in [0, 1, 2]],
        )
    else:
        ret.__dict__.update(
            pos = [face.pos[i] for i in [0, 2, 1]],
            tex = [face.tex[i] for i in [0, 2, 1]],
            nrm = [face.nrm[i] for i in [0, 2, 1]],
        )
    return ret

N = 64

scene = t3.Scene() mesh = t3.DynamicMesh(n_faces=N, n_pos=N + 1) model = t3.Model(MeshNoCulling(mesh)) # here scene.add_model(model) camera = t3.Camera() scene.add_camera(camera) light = t3.AmbientLight(1.0) scene.add_light(light)

@ti.materialize_callback @ti.kernel def init_mesh(): mesh.nrm[0] = [0, 0, 1] mesh.pos[N] = [0, 0, 0] for i in range(N): a = i / N * t3.tau mesh.pos[i] = [ti.sin(a), ti.cos(a), 0] mesh.faces[i] = [[i, 0, 0], [(i + 1) % N, 0, 0], [N, 0, 0]]

gui = ti.GUI('Dynamic', camera.res) while gui.running: gui.get_event(None) camera.from_mouse(gui) mesh.n_faces[None] = gui.frame % N scene.render() gui.set_image(camera.img) gui.show()


3. Or, if you don't mind - create two faces with different 'orientation' and normal will make it visible from both side.