Пример #1
0
 def tex(self):
     return [
         i / ts.vec2(*self.parent.res) for i in [
             self.i + ts.D.__, self.i + ts.D.x_, self.i +
             ts.D.xx, self.i + ts.D._x
         ]
     ]
Пример #2
0
 def render(self):
     self.src.render()
     for i in self.kern:
         self.kern[i] = ts.randUnit3D() * ti.random()**2 * self.radius
     for i in ti.grouped(self.repa):
         u = ts.randUnit3D()
         v = ts.randUnit3D()
         w = u.cross(v).normalized()
         v = w.cross(u)
         self.repa[i] = ti.Matrix.rows([u, v, w])
     for i in ti.grouped(self.img):
         count = 0
         normal = self.src['normal'][i]
         d0 = self.invdep(self.src.idepth[i])
         for j in range(self.samples):
             r = self.repa[i % ts.vec2(*self.repa.shape)] @ self.kern[j]
             r = v4trans(self.src.camera.L2W.inverse(), r, 0)
             if r.dot(normal) < 0:
                 r = -r
             rxy = self.src.camera.uncook(ts.vec3(r.xy, d0), False).xy
             d1 = self.invdep(ts.bilerp(self.src.idepth, i + rxy))
             d1 = d1 - r.z
             if d1 < d0 - 1e-6:
                 count += 1
         ao = 1 - count / self.samples
         self.img[i] = ao
Пример #3
0
 def velocity(self, P):
     p = P * self.dx
     vel = ts.vec2(0.0)
     for v in range(self.vorts.shape[0]):
         dis = (p - self.vorts[v])
         dis = ts.normalizePow(dis, -1, 0.001)
         dis = dis.yx * ts.vec(-1, 1) * self.vorty[v]
         vel += dis
     return vel * 0.01
Пример #4
0
    def shadow_occlusion(self, wpos, normal):
        if ti.static(self.shadow is None):
            return 1

        lspos = v4trans(self.shadow.L2W[None].inverse(), wpos, 1)
        lscoor = self.shadow.uncook(lspos)

        cur_z = lspos.z  # TODO: bend with normal

        return self._sub_SDlerp(cur_z, lscoor, ts.vec2(0))
        '''
Пример #5
0
    def _render(self):
        for I in ti.grouped(self.img):
            scale = ti.static(2 / min(*self.img.shape()))
            coor = (I - ts.vec2(*self.img.shape()) / 2) * scale

            orig, dir = self.camera.generate(coor)

            pos, normal = self.trace(orig, dir)
            light_dir = self.light_dir[None]

            color = self.opt.render_func(pos, normal, dir, light_dir)
            color = self.opt.pre_process(color)
            self.img[I] = color
Пример #6
0
 def uncook(self, pos):
     if ti.static(self.type == self.ORTHO):
         pos[0] *= self.intrinsic[None][0, 0] 
         pos[1] *= self.intrinsic[None][1, 1]
         pos[0] += self.intrinsic[None][0, 2]
         pos[1] += self.intrinsic[None][1, 2]
     elif ti.static(self.type == self.TAN_FOV):
         pos = self.intrinsic[None] @ pos
         pos[0] /= abs(pos[2])
         pos[1] /= abs(pos[2])
     else:
         raise NotImplementedError("Curvilinear projection matrix not implemented!")
     return ts.vec2(pos[0], pos[1])
Пример #7
0
 def sample(self, dir):
     I = ts.vec2(0.0)
     eps = 1e-5
     dps = 1 - 12 / self.texture.shape[0]
     if dir.z >= 0 and dir.z >= abs(dir.y) - eps and dir.z >= abs(
             dir.x) - eps:
         I = ts.vec(3 / 8, 3 / 8) + dir.xy / dir.z / 8 * dps
     if dir.z <= 0 and -dir.z >= abs(dir.y) - eps and -dir.z >= abs(
             dir.x) - eps:
         I = ts.vec(7 / 8, 3 / 8) + dir.Xy / -dir.z / 8 * dps
     if dir.x <= 0 and -dir.x >= abs(dir.y) - eps and -dir.x >= abs(
             dir.z) - eps:
         I = ts.vec(1 / 8, 3 / 8) + dir.zy / -dir.x / 8 * dps
     if dir.x >= 0 and dir.x >= abs(dir.y) - eps and dir.x >= abs(
             dir.z) - eps:
         I = ts.vec(5 / 8, 3 / 8) + dir.Zy / dir.x / 8 * dps
     if dir.y >= 0 and dir.y >= abs(dir.x) - eps and dir.y >= abs(
             dir.z) - eps:
         I = ts.vec(3 / 8, 5 / 8) + dir.xZ / dir.y / 8 * dps
     if dir.y <= 0 and -dir.y >= abs(dir.x) - eps and -dir.y >= abs(
             dir.z) - eps:
         I = ts.vec(3 / 8, 1 / 8) + dir.xz / -dir.y / 8 * dps
     I = ts.vec2(self.texture.shape[0]) * I
     return ts.bilerp(self.texture, I)
Пример #8
0
 def _loadrays(self, topleft: ti.template(), region: ti.template(), skipstep: ti.template()):
     ti.static_print('loadrays:', topleft, region, skipstep)
     for II in ti.grouped(ti.ndrange(*region)):
         I = II * skipstep + topleft
         for J in ti.static(ti.grouped(ti.ndrange(skipstep, skipstep))):
             self.img[I + J] *= 0
     for II in ti.grouped(ti.ndrange(*region)):
         i = II.dot(ts.vec(1, region[0]))
         I = II * skipstep + topleft + skipstep * ti.random()
         coor = ts.vec2((I.x - self.cx) / self.fx, (I.y - self.cy) / self.fy)
         orig, dir = self.generate(coor)
         self.ro[i] = orig
         self.rd[i] = dir
         self.rc[i] = ts.vec3(1.0)
         self.rI[i] = II
Пример #9
0
def render_triangle(model, camera, face):
    scene = model.scene
    L2C = model.L2C[None]  # Local to Camera, i.e. ModelView in OpenGL
    posa, posb, posc = face.pos
    texa, texb, texc = face.tex
    nrma, nrmb, nrmc = face.nrm
    posa = (L2C @ ts.vec4(posa, 1)).xyz
    posb = (L2C @ ts.vec4(posb, 1)).xyz
    posc = (L2C @ ts.vec4(posc, 1)).xyz
    nrma = (L2C @ ts.vec4(nrma, 0)).xyz
    nrmb = (L2C @ ts.vec4(nrmb, 0)).xyz
    nrmc = (L2C @ ts.vec4(nrmc, 0)).xyz

    pos_center = (posa + posb + posc) / 3
    if ti.static(camera.type == camera.ORTHO):
        pos_center = ts.vec3(0.0, 0.0, 1.0)

    dpab = posa - posb
    dpac = posa - posc
    dtab = texa - texb
    dtac = texa - texc

    normal = ts.cross(dpab, dpac)

    # NOTE: the normal computation indicates that a front-facing face should
    # be COUNTER-CLOCKWISE, i.e., glFrontFace(GL_CCW);
    # this is to be compatible with obj model loading.
    if ts.dot(pos_center, normal) <= 0:
        tan, bitan = compute_tangent(-dpab, -dpac, -dtab,
                                     -dtac)  # TODO: node-ize this

        clra = model.vertex_shader(
            posa, texa, nrma, tan,
            bitan)  # TODO: interpolate tan and bitan? merge with nrm?
        clrb = model.vertex_shader(posb, texb, nrmb, tan, bitan)
        clrc = model.vertex_shader(posc, texc, nrmc, tan, bitan)

        A = camera.uncook(posa)
        B = camera.uncook(posb)
        C = camera.uncook(posc)
        scr_norm = ts.cross(A - C, B - A)
        if scr_norm != 0:  # degenerate to 'line' if zero
            B_A = (B - A) / scr_norm
            A_C = (A - C) / scr_norm

            shake = ts.vec2(0.0)
            if ti.static(camera.fb.n_taa):
                for i, s in ti.static(
                        enumerate(map(ti.Vector,
                                      TAA_SHAKES[:camera.fb.n_taa]))):
                    if camera.fb.itaa[None] == i:
                        shake = s * 0.5

            # screen space bounding box
            M = int(ti.floor(min(A, B, C) - 1))
            N = int(ti.ceil(max(A, B, C) + 1))
            M = ts.clamp(M, 0, ti.Vector(camera.fb.res))
            N = ts.clamp(N, 0, ti.Vector(camera.fb.res))
            for X in ti.grouped(ti.ndrange((M.x, N.x), (M.y, N.y))):
                # barycentric coordinates using the area method
                X_A = X - A + shake
                w_C = ts.cross(B_A, X_A)
                w_B = ts.cross(A_C, X_A)
                w_A = 1 - w_C - w_B

                # draw
                eps = ti.get_rel_eps() * 0.2
                is_inside = w_A >= -eps and w_B >= -eps and w_C >= -eps
                if not is_inside:
                    continue

                # https://gitee.com/zxtree2006/tinyrenderer/blob/master/our_gl.cpp
                if ti.static(camera.type != camera.ORTHO):
                    bclip = ts.vec3(w_A / posa.z, w_B / posb.z, w_C / posc.z)
                    bclip /= bclip.x + bclip.y + bclip.z
                    w_A, w_B, w_C = bclip

                depth = (posa.z * w_A + posb.z * w_B + posc.z * w_C)
                if camera.fb.atomic_depth(X, depth):
                    continue

                clr = [
                    a * w_A + b * w_B + c * w_C
                    for a, b, c in zip(clra, clrb, clrc)
                ]
                camera.fb.update(X, model.pixel_shader(*clr))
Пример #10
0
 def get_normal_at(self, i):
     xa = self.pos[ts.clamp(i + ts.D.x_, 0, ts.vec2(*self.shape))]
     xb = self.pos[ts.clamp(i + ts.D.X_, 0, ts.vec2(*self.shape))]
     ya = self.pos[ts.clamp(i + ts.D._x, 0, ts.vec2(*self.shape))]
     yb = self.pos[ts.clamp(i + ts.D._X, 0, ts.vec2(*self.shape))]
     return (ya - yb).cross(xa - xb).normalized()
Пример #11
0
 def tex(self):
     return [i / ts.vec2(*self.parent.res) for i in self.seq]
Пример #12
0
__import__('sys').path.insert(0, '/home/bate/Develop/glsl_taichi')
__import__('sys').path.insert(0, 'external')

import numpy as np
import taichi as ti
import taichi_glsl as tl

ts = tl

V = lambda *_: tl.vec(*_).cast(float) if ti.impl.inside_kernel() else tl.vec(*_
                                                                             )
V3 = lambda *_: tl.vec3(*_).cast(float) if ti.impl.inside_kernel(
) else tl.vec3(*_)
V2 = lambda *_: tl.vec2(*_).cast(float) if ti.impl.inside_kernel(
) else tl.vec2(*_)

EPS = 1e-6
INF = 1e6


@ti.pyfunc
def tangent(Z):
    Y = V(0, 1, 0) if any(abs(Z.xz) >= 1e-2) else V(1, 0, 0) if any(
        abs(Z.yz) >= 1e-2) else V(0, 0, 1)
    X = Y.cross(Z).normalized()
    Y = Z.cross(X)
    return ti.Matrix([X.entries, Y.entries, Z.entries]).transpose()


@ti.pyfunc
def spherical(h, phi):
Пример #13
0
 def uncook_coor(self, coor):
     coor_xy = ts.shuffle(coor, 0, 1)
     scale = ti.static(min(*self.img.shape()) / 2)
     I = coor_xy * scale + ts.vec2(*self.img.shape()) / 2
     return I
Пример #14
0
 def cook_coor(self, I):
     scale = ti.static(2 / min(*self.img.shape()))
     coor = (I - ts.vec2(*self.img.shape()) / 2) * scale
     return coor
Пример #15
0
 def uncook_coor(self, coor):
     scale = ti.static(min(*self.img.shape()) / 2)
     I = coor.xy * scale + ts.vec2(*self.img.shape()) / 2
     return I
Пример #16
0
def render_triangle(model, camera, face):
    posa, posb, posc = face.pos   # Position
    texa, texb, texc = face.tex   # TexCoord
    nrma, nrmb, nrmc = face.nrm   # Normal

    pos_center = (posa + posb + posc) / 3
    if ti.static(camera.type == camera.ORTHO):
        pos_center = ts.vec3(0.0, 0.0, 1.0)

    # NOTE: the normal computation indicates that a front-facing face should
    # be COUNTER-CLOCKWISE, i.e., glFrontFace(GL_CCW);
    # this is to be compatible with obj model loading.
    if ts.dot(pos_center, ts.cross(posa - posc, posa - posb)) >= 0:
        tan, bitan = compute_tangent(posb - posa, posc - posa, texb - texa, texc - texa)  # TODO: node-ize this

        clra = [posa, texa, nrma]  # TODO: interpolate tan and bitan? merge with nrm?
        clrb = [posb, texb, nrmb]
        clrc = [posc, texc, nrmc]

        A = camera.uncook(posa)
        B = camera.uncook(posb)
        C = camera.uncook(posc)
        scr_norm = ts.cross(A - C, B - A)
        if scr_norm != 0:  # degenerate to 'line' if zero
            B_A = (B - A) / scr_norm
            A_C = (A - C) / scr_norm

            shake = ts.vec2(0.0)
            if ti.static(camera.fb.n_taa):
                for i, s in ti.static(enumerate(map(ti.Vector, TAA_SHAKES[:camera.fb.n_taa]))):
                    if camera.fb.itaa[None] == i:
                        shake = s * 0.5

            # screen space bounding box
            M = int(ti.floor(min(A, B, C) - 1))
            N = int(ti.ceil(max(A, B, C) + 1))
            M = ts.clamp(M, 0, ti.Vector(camera.fb.res))
            N = ts.clamp(N, 0, ti.Vector(camera.fb.res))
            for X in ti.grouped(ti.ndrange((M.x, N.x), (M.y, N.y))):
                # barycentric coordinates using the area method
                X_A = X - A + shake
                w_C = ts.cross(B_A, X_A)
                w_B = ts.cross(A_C, X_A)
                w_A = 1 - w_C - w_B

                # draw
                eps = ti.get_rel_eps() * 0.2
                is_inside = w_A >= -eps and w_B >= -eps and w_C >= -eps
                if not is_inside:
                    continue

                # https://gitee.com/zxtree2006/tinyrenderer/blob/master/our_gl.cpp
                if ti.static(camera.type != camera.ORTHO):
                    bclip = ts.vec3(w_A / posa.z, w_B / posb.z, w_C / posc.z)
                    bclip /= bclip.x + bclip.y + bclip.z
                    w_A, w_B, w_C = bclip

                depth = (posa.z * w_A + posb.z * w_B + posc.z * w_C)
                if camera.fb.atomic_depth(X, depth):
                    continue

                posx, texx, nrmx = [a * w_A + b * w_B + c * w_C for a, b, c in zip(clra, clrb, clrc)]
                color = ti.static(model.material.pixel_shader(model, posx, texx, nrmx, tan, bitan))
                if ti.static(isinstance(color, dict)):
                    camera.fb.update(X, color)
                else:
                    camera.fb.update(X, dict(img=color))
Пример #17
0
def vgridGradient(field: ti.template(), I):
    return ts.vec2(
        sample(field, I + D.xy) - sample(field, I + D.xz),
        sample(field, I + D.yx) - sample(field, I + D.zx))
Пример #18
0
 def on_render(self):
     ts.paintArrow(self.img, ts.vec2(0.0), self.iMouse)