示例#1
0
def render_custom(ro, rd, pr_mat):  # ro: vec3, rd: vec3, t: ti.f32
    """
    Определение цвета каждого пикселя
    :param ro: где расположена камера
    :param rd: направление в сторону каждого пикселя на экране (он идёт дальше, пока не пересечёт какой-то объект)
    :param pr_mat: предыдущий материал
    :return: цвет пикселя, точка падения луча на объект, отражённый луч, материал
    """
    # d, mat_i, p = raymarch(ro, rd)
    d, mat_i, p = raymarch_outline(ro, rd, 0.05)
    n = normal(p, rd)
    r = reflect(rd, n)
    occ = ambient_occlusion(p, n)
    col = vec3(0.)
    lp = vec3(5., 5., -5.)  # lamp position
    ld = normalize(lp - p)
    mat_n = materials.shape[0]
    background = materials[mat_n - 1] - abs(rd.y)
    mate = materials[mat_i]
    coeff_of_reflect = 1.

    if pr_mat == 2 and mat_i != 2 or pr_mat == 2 and mat_i == 2:
        col = vec3(0., 0., 0.)
    elif pr_mat == 4 and mat_i != 4 or pr_mat == 4 and mat_i == 4:
        col = vec3(0., 0., 0.)
    elif pr_mat == 5 and mat_i != 5 or pr_mat == 5 and mat_i == 5:
        col = vec3(0., 0., 0.)
    else:

        if mat_i >= mat_n - 2:
            col = mate  # background, outline
        else:
            diff, spec = phong(n, rd, ld, 16)

            if mat_i == 0:
                mate = boxmap_texture(translate_cube(rotate_cube(p)),
                                      rotate_cube(n), 60, 32.)
                diff = ti.ceil(diff * 2.) / 2.
            if mat_i == 2:
                diff = ti.ceil(diff * 2.) / 2.
                pass

            shad = sharp_shadow(p + n * EPS, ld)
            if flag[None] != 0.:
                shad = soft_shadow(p + n * EPS, ld)
            k_a = 0.3
            k_d = 1.0
            k_s = 1.5  # 1.5
            amb = mate
            dif = diff * mate
            spe = spec * vec3(1.)
            col = coeff_of_reflect * (k_a * amb * occ +
                                      (k_d * dif + k_s * spe * occ) * shad)
        #fog
        col = mix(col, background, smoothstep(20., 50., d))

    ro = p + n * 0.1
    rd = r
    return col, ro, rd, mat_i
示例#2
0
def render_line(model, camera, face, w0=0, w1=1):
    posa, posb = face.pos   # Position
    texa, texb = face.tex   # TexCoord
    nrma, nrmb = face.nrm   # Normal

    clra = [posa, texa, nrma]
    clrb = [posb, texb, nrmb]

    A = camera.uncook(posa)
    B = camera.uncook(posb)

    M = int(ti.floor(min(A, B) - 1))
    N = int(ti.ceil(max(A, B) + 1))
    M = ts.clamp(M, 0, ti.Vector(camera.fb.res))
    N = ts.clamp(N, 0, ti.Vector(camera.fb.res))

    B_A = (B - A).normalized()

    for X in ti.grouped(ti.ndrange((M.x, N.x), (M.y, N.y))):
        udf = abs((X - A).cross(B_A))
        if udf >= w1:
            continue

        strength = ts.smoothstep(udf, w1, w0)
        color = ts.vec3(strength)
        camera.img[X] += color
示例#3
0
def render_particle(model, camera, index):
    scene = model.scene
    a = (model.L2C[None] @ ts.vec4(model.pos[index], 1)).xyz
    r = model.radius[index]
    A = camera.uncook(a)

    rad = camera.uncook(ts.vec3(r, r, a.z), False)

    M = int(ti.floor(A - rad))
    N = int(ti.ceil(A + rad))
    M = ts.clamp(M, 0, ti.Vector(camera.res))
    N = ts.clamp(N, 0, ti.Vector(camera.res))

    for X in ti.grouped(ti.ndrange((M.x, N.x), (M.y, N.y))):
        pos = camera.cook(float(ts.vec3(X, a.z)))
        dp = pos - a
        dp2 = dp.norm_sqr()

        if dp2 > r**2:
            continue

        dz = ti.sqrt(r**2 - dp2)
        if camera.fb.atomic_depth(X, a.z - dz):
            continue

        n = ts.vec3(dp.xy, -dz)
        normal = ts.normalize(n)
        view = ts.normalize(a + n)

        color = model.colorize(pos, normal)
        camera.fb['img'][X] = color
        camera.fb['normal'][X] = normal
示例#4
0
def paintArrow(img: ti.template(),
               orig,
               dir,
               color=1,
               width=3,
               max_size=12,
               min_scale=0.4):
    res = ts.vec(*img.shape)
    I = orig * res
    D = dir * res
    J = I + D
    DL = ts.length(D)
    S = min(max_size, DL * min_scale)
    DS = D / (DL + 1e-4) * S
    SW = S + width
    D1 = ti.Matrix.rotation2d(+math.pi * 3 / 4) @ DS
    D2 = ti.Matrix.rotation2d(-math.pi * 3 / 4) @ DS
    bmin, bmax = ti.floor(max(0,
                              min(I, J) - SW)), ti.ceil(
                                  min(res - 1,
                                      max(I, J) + SW))
    for P in ti.grouped(ti.ndrange((bmin.x, bmax.x), (bmin.y, bmax.y))):
        c0 = ts.smoothstep(abs(sdLine(I, J, P)), width, width / 2)
        c1 = ts.smoothstep(abs(sdLine(J, J + D1, P)), width, width / 2)
        c2 = ts.smoothstep(abs(sdLine(J, J + D2, P)), width, width / 2)
        ti.atomic_max(img[P], max(c0, c1, c2) * color)
示例#5
0
def render_cylinder(model, camera, v1, v2, radius, c1, c2):
    scene = model.scene
    a = camera.untrans_pos(v1)
    b = camera.untrans_pos(v2)
    A = camera.uncook(a)
    B = camera.uncook(b)
    bx = int(ti.ceil(camera.fx * radius / min(a.z, b.z)))
    by = int(ti.ceil(camera.fy * radius / min(a.z, b.z)))

    M, N = ti.floor(min(A, B)), ti.ceil(max(A, B))
    M.x -= bx
    N.x += bx
    M.y -= by
    N.y += by
    M.x, N.x = min(max(M.x, 0),
                   camera.img.shape[0]), min(max(N.x, 0), camera.img.shape[1])
    M.y, N.y = min(max(M.y, 0),
                   camera.img.shape[0]), min(max(N.y, 0), camera.img.shape[1])
    if (M.x < N.x and M.y < N.y):
        for X in ti.grouped(ti.ndrange((M.x, N.x), (M.y, N.y))):
            t = ti.dot(X - A, B - A) / (B - A).norm_sqr()
            if t < 0 or t > 1:
                continue
            proj = a * (1 - t) + b * t
            W = ti.cast(ti.Vector([X.x, X.y, proj.z]), ti.f32)
            w = cook_coord(camera, W)
            dw = w - proj
            dw2 = dw.norm_sqr()
            if dw2 > radius**2:
                continue
            dz = ti.sqrt(radius**2 - dw2)
            n = ti.Vector([dw.x, dw.y, -dz])
            zindex = 1 / (proj.z - dz)

            if zindex >= ti.atomic_max(camera.zbuf[X], zindex):
                basecolor = c1 if t < 0.5 else c2
                normal = ts.normalize(n)
                view = ts.normalize(a + n)
                color = get_ambient(camera, normal, view) * basecolor
                for light in ti.static(scene.lights):
                    light_color = scene.opt.render_func(a + n, normal, \
                        view, light, basecolor)
                    color += light_color
                camera.img[X] = color
                camera.nbuf[X] = normal
def draw_box(cx: ti.f32, cy: ti.f32, theta: ti.f32, w: ti.f32, h: ti.f32,
             r: ti.f32):
    costheta = abs(ti.cos(theta))
    sintheta = abs(ti.sin(theta))
    tw = w * 0.5
    th = h * 0.5
    x0 = max(int(ti.floor(cx - tw * costheta - th * sintheta)) - 1, 0)
    x1 = min(
        int(ti.ceil(cx + tw * costheta + th * sintheta)) + 1, WINDOW_WIDTH)
    y0 = max(int(ti.floor(cy - tw * sintheta - th * costheta)) - 1, 0)
    y1 = min(
        int(ti.ceil(cy + tw * sintheta + th * costheta)) + 1, WINDOW_HEIGHT)
    w -= r * 2.0
    h -= r * 2.0
    for i, j in ti.ndrange((y0, y1), (x0, x1)):
        alpha_blend(
            j, i,
            max(min(0.5 - boxSDF(j, i, cx, cy, theta, w, h) + r, 1.0), 0.0),
            0.8)
示例#7
0
    def make_tests():
        x = 1.5
        v = ti.math.vec3(1.1, 2.2, 3.3)

        assert ti.floor(x) == 1
        assert ti.floor(x, dt) == 1.0
        assert ti.floor(x, int) == 1

        assert all(ti.floor(v) == [1, 2, 3])
        assert all(ti.floor(v, dt) == [1.0, 2.0, 3.0])
        assert all(ti.floor(v, int) == [1, 2, 3])

        assert ti.ceil(x) == 2
        assert ti.ceil(x, dt) == 2.0
        assert ti.ceil(x, int) == 2

        assert all(ti.ceil(v) == [2, 3, 4])
        assert all(ti.ceil(v, dt) == [2.0, 3.0, 4.0])
        assert all(ti.ceil(v, int) == [2, 3, 4])

        assert ti.round(x) == 2
        assert ti.round(x, dt) == 2.0
        assert ti.round(x, int) == 2

        assert all(ti.round(v) == [1, 2, 3])
        assert all(ti.round(v, dt) == [1.0, 2.0, 3.0])
        assert all(ti.round(v, int) == [1, 2, 3])
示例#8
0
def render_particle(model, camera, vertex, radius):
    scene = model.scene
    L2W = model.L2W
    a = camera.untrans_pos(L2W @ vertex)
    A = camera.uncook(a)

    M = int(ti.floor(A - radius))
    N = int(ti.ceil(A + radius))

    for X in ti.grouped(ti.ndrange((M.x, N.x), (M.y, N.y))):
        if X.x < 0 or X.x >= camera.res[0] or X.y < 0 or X.y >= camera.res[1]:
            continue
        if (X - A).norm_sqr() > radius**2:
            continue

        camera.img[X] = ts.vec3(1)
示例#9
0
 def func():
     xi[0] = -yi[None]
     xi[1] = ~yi[None]
     xi[2] = ti.logical_not(yi[None])
     xi[3] = ti.abs(yi[None])
     xf[0] = -yf[None]
     xf[1] = ti.abs(yf[None])
     xf[2] = ti.sqrt(yf[None])
     xf[3] = ti.sin(yf[None])
     xf[4] = ti.cos(yf[None])
     xf[5] = ti.tan(yf[None])
     xf[6] = ti.asin(yf[None])
     xf[7] = ti.acos(yf[None])
     xf[8] = ti.tanh(yf[None])
     xf[9] = ti.floor(yf[None])
     xf[10] = ti.ceil(yf[None])
     xf[11] = ti.exp(yf[None])
     xf[12] = ti.log(yf[None])
示例#10
0
 def raster(self):  # 8x8 rough rasterization
     for q in ti.grouped(self.tml):
         self.tml[q] = 0
         self.tmd[q] = 1e6
     # TODO: use brensel instead of barycent for raster
     for e in self.tri:
         aa, bb, cc = self.getverts(self.tri[e])
         a, b, c = V(aa.x, aa.y), V(bb.x, bb.y), V(cc.x, cc.y)
         xy2uvw = self.makexy2uvw(a, b, c)  # xy-to-distance matrix
         pmin = max(0, int(ti.floor(min(a, b, c) / self.S)))
         pmax = min(self.N // self.S,
                    int(ti.ceil(max(a, b, c) / self.S) + 1))
         for q in ti.grouped(ti.ndrange(*zip(pmin, pmax))):
             p = q * self.S + self.S // 2
             uvw = xy2uvw @ V(p.x, p.y, 1)
             if all(uvw > -self.S) or all(uvw < self.S):
                 l = ti.atomic_add(self.tml[q], 1)
                 self.tmp[l, q] = e  # append an element
示例#11
0
 def do_render(self, scene):
     W = 1
     A = scene.uncook_coor(scene.camera.untrans_pos(self.a))
     B = scene.uncook_coor(scene.camera.untrans_pos(self.b))
     M, N = int(ti.floor(min(A, B) - W)), int(ti.ceil(max(A, B) + W))
     for X in ti.grouped(ti.ndrange((M.x, N.x), (M.y, N.y))):
         P = B - A
         udf = (ts.cross(X, P) + ts.cross(B, A))**2 / P.norm_sqr()
         XoP = ts.dot(X, P)
         AoB = ts.dot(A, B)
         if XoP > B.norm_sqr() - AoB:
             udf = (B - X).norm_sqr()
         elif XoP < AoB - A.norm_sqr():
             udf = (A - X).norm_sqr()
         if udf < 0:
             scene.img[X] = ts.vec3(1.0)
         elif udf < W**2:
             t = ts.smoothstep(udf, 0, W**2)
             ti.atomic_min(scene.img[X], ts.vec3(t))
示例#12
0
    def do_render(self):
        model = self.model
        scene = model.scene
        L2W = model.L2W
        a = scene.camera.untrans_pos(L2W @ self.vertex(0).pos)
        b = scene.camera.untrans_pos(L2W @ self.vertex(1).pos)
        c = scene.camera.untrans_pos(L2W @ self.vertex(2).pos)
        A = scene.uncook_coor(a)
        B = scene.uncook_coor(b)
        C = scene.uncook_coor(c)
        B_A = B - A
        C_B = C - B
        A_C = A - C
        ilB_A = 1 / ts.length(B_A)
        ilC_B = 1 / ts.length(C_B)
        ilA_C = 1 / ts.length(A_C)
        B_A *= ilB_A
        C_B *= ilC_B
        A_C *= ilA_C
        BxA = ts.cross(B, A) * ilB_A
        CxB = ts.cross(C, B) * ilC_B
        AxC = ts.cross(A, C) * ilA_C
        normal = ts.normalize(ts.cross(a - c, a - b))
        light_dir = scene.camera.untrans_dir(scene.light_dir[None])
        pos = (a + b + c) / 3
        color = scene.opt.render_func(pos, normal, ts.vec3(0.0), light_dir)
        color = scene.opt.pre_process(color)

        Ak = 1 / (ts.cross(A, C_B) + CxB)
        Bk = 1 / (ts.cross(B, A_C) + AxC)
        Ck = 1 / (ts.cross(C, B_A) + BxA)

        W = 1
        M, N = int(ti.floor(min(A, B, C) - W)), int(ti.ceil(max(A, B, C) + W))
        for X in ti.grouped(ti.ndrange((M.x, N.x), (M.y, N.y))):
            AB = ts.cross(X, B_A) + BxA
            BC = ts.cross(X, C_B) + CxB
            CA = ts.cross(X, A_C) + AxC
            if AB <= 0 and BC <= 0 and CA <= 0:
                zindex = pos.z  #(Ak * a.z * BC + Bk * b.z * CA + Ck * c.z * AB)
                zstep = zindex - ti.atomic_max(scene.zbuf[X], zindex)
                if zstep >= 0:
                    scene.img[X] = color
示例#13
0
    def initialize_particle_grid(self):
        for p in range(self.num_particles[None]):
            v = ti.Vector([0.0, 0.0, 0.0])
            if ti.static(self.enable_motion_blur):
                v = self.particle_v[p]
            x = self.particle_x[p]
            ipos = ti.floor(x * self.inv_dx).cast(ti.i32)

            offset_begin = shutter_begin * self.shutter_time * v
            offset_end = (shutter_begin + 1.0) * self.shutter_time * v
            offset_begin_grid = offset_begin
            offset_end_grid = offset_end

            for k in ti.static(range(3)):
                if offset_end_grid[k] < offset_begin_grid[k]:
                    t = offset_end_grid[k]
                    offset_end_grid[k] = offset_begin_grid[k]
                    offset_begin_grid[k] = t

            offset_begin_grid = int(ti.floor(
                offset_begin_grid * self.inv_dx)) - 1
            offset_end_grid = int(ti.ceil(offset_end_grid * self.inv_dx)) + 2

            for i in range(offset_begin_grid[0], offset_end_grid[0]):
                for j in range(offset_begin_grid[1], offset_end_grid[1]):
                    for k in range(offset_begin_grid[2], offset_end_grid[2]):
                        offset = ti.Vector([i, j, k])
                        box_ipos = ipos + offset
                        if self.inside_particle_grid(box_ipos):
                            box_min = box_ipos * self.dx
                            box_max = (box_ipos +
                                       ti.Vector([1, 1, 1])) * self.dx
                            if sphere_aabb_intersect_motion(
                                    box_min, box_max, x + offset_begin,
                                    x + offset_end, self.sphere_radius):
                                self.voxel_has_particle[box_ipos] = 1
                                self.voxel_grid_density[box_ipos] = 1
                                ti.append(
                                    self.pid.parent(), box_ipos -
                                    ti.Vector(self.particle_grid_offset), p)
示例#14
0
    def do_render(self, scene):
        a = scene.camera.untrans_pos(self.a)
        b = scene.camera.untrans_pos(self.b)
        c = scene.camera.untrans_pos(self.c)
        A = scene.uncook_coor(a)
        B = scene.uncook_coor(b)
        C = scene.uncook_coor(c)
        B_A = B - A
        C_B = C - B
        A_C = A - C
        ilB_A = 1 / ts.length(B_A)
        ilC_B = 1 / ts.length(C_B)
        ilA_C = 1 / ts.length(A_C)
        B_A *= ilB_A
        C_B *= ilC_B
        A_C *= ilA_C
        BxA = ts.cross(B, A) * ilB_A
        CxB = ts.cross(C, B) * ilC_B
        AxC = ts.cross(A, C) * ilA_C
        normal = ts.normalize(ts.cross(a - c, a - b))
        light_dir = scene.camera.untrans_dir(scene.light_dir[None])
        pos = (a + b + c) * (1 / 3)
        dir = ts.vec3(0.0)
        color = scene.opt.render_func(pos, normal, dir, light_dir)
        color = scene.opt.pre_process(color)

        W = 0.4
        M, N = int(ti.floor(min(A, B, C) - W)), int(ti.ceil(max(A, B, C) + W))
        for X in ti.grouped(ti.ndrange((M.x, N.x), (M.y, N.y))):
            AB = ts.cross(X, B_A) + BxA
            BC = ts.cross(X, C_B) + CxB
            CA = ts.cross(X, A_C) + AxC
            udf = max(AB, BC, CA)
            if udf < 0:
                scene.img[X] = color
            elif udf < W:
                t = ts.smoothstep(udf, W, 0)
                ti.atomic_max(scene.img[X], t * color)
示例#15
0
def render_particle(model, camera, index):
    scene = model.scene
    L2W = model.L2W
    a = model.pos[index]
    r = model.radius[index]
    a = camera.untrans_pos(L2W @ a)
    A = camera.uncook(a)

    rad = camera.uncook(ts.vec3(r, r, a.z), False)

    M = int(ti.floor(A - rad))
    N = int(ti.ceil(A + rad))
    M = ts.clamp(M, 0, ti.Vector(camera.res))
    N = ts.clamp(N, 0, ti.Vector(camera.res))

    for X in ti.grouped(ti.ndrange((M.x, N.x), (M.y, N.y))):
        pos = camera.cook(float(ts.vec3(X, a.z)))
        dp = pos - a
        dp2 = dp.norm_sqr()

        if dp2 > r**2:
            continue

        dz = ti.sqrt(r**2 - dp2)
        zindex = 1 / (a.z - dz)

        if zindex < ti.atomic_max(camera.fb['idepth'][X], zindex):
            continue

        n = ts.vec3(dp.xy, -dz)
        normal = ts.normalize(n)
        view = ts.normalize(a + n)
        color = ts.vec3(1.0)

        color = model.colorize(pos, normal, color)
        camera.fb['img'][X] = color
        camera.fb['normal'][X] = normal
示例#16
0
文件: 1st.py 项目: luxuia/taichi_test
def gradientNoise(t:ti.template)->ti.f32:
    fraction = t-int(t)
    interpolator = easeInOut(fraction)

    #return fraction.dot(fraction)
    #return fraction[0]
    ft = int(t)
    ct = ti.cast(ti.ceil(t), ti.i32)

    lowerleftd = rand1dT1d(ti.Vector([ft[0], ft[1]]))*2-1
    
    #return (lowerleftd.dot(ti.Vector([1,1])))/2

    #return lowerleftd[1]

    lowerrightd = rand1dT1d(ti.Vector([ct[0], ft[1]]))*2-1
    upleftd = rand1dT1d(ti.Vector([ft[0], ct[1]]))*2-1
    uprightd = rand1dT1d(ti.Vector([ct[0], ct[1]]))*2-1


    lowleftv = lowerleftd.dot(fraction-ti.Vector([0, 0]))
    lowrightv = lowerrightd.dot(fraction-ti.Vector([1, 0]))

    #-return ti.abs(lowleftv)

    upleftv = upleftd.dot(fraction-ti.Vector([0, 1]))
    uprightv= uprightd.dot(fraction-ti.Vector([1, 1]))

    low = lerp(lowleftv, lowrightv, interpolator[0])
    #return low
    up = lerp(upleftv, uprightv, interpolator[0])

    #return low

    noise = lerp(low, up, interpolator[1])
    return noise
示例#17
0
def round(val):
    # 向上取整
    _round_val = ti.ceil(val)
    if (_round_val - val) > 0.5:
        _round_val -= 1.0
    return _round_val
示例#18
0
 def foo():
     x[None] = -y[None]
     x[None] = ti.floor(x[None])
     y[None] = ti.ceil(y[None])
示例#19
0
def iceil(x):
    return int(ti.ceil(x))
示例#20
0
 def frac(x):
     fractional = x - ti.floor(x) if x > 0. else x - ti.ceil(x)
     return fractional
示例#21
0
    def __init__(self, x_list, flag_list, gui, dim=2, **kwargs):
        # basic render settings
        self.dim = dim
        assert self.dim == 1 or self.dim == 2 or self.dim == 3
        self.dim_size = ti.Vector([1, 1.02])
        self.dt = 5e-4
        self.gui = gui

        # basic solver settings
        self.r = 5e-3  # particle spacing
        self.h = self.r * 2.0
        self.nbrs_num_max = 500
        self.grid_pnum_max = 500
        self.theta_c = 0.025
        self.theta_s = 0.0075
        self.density = 400
        self.snow_m = self.density * self.h**3
        self.mu_b = 1.0
        self.psi = 1.5
        self.E = 140
        self.mu = 0.2
        self.omega = 0.5
        self.epsilon = 10.0
        self.error_rate = 1e-3
        if 'theta_c' in kwargs:
            self.theta_c = kwargs['theta_c']
        if 'theta_s' in kwargs:
            self.theta_s = kwargs['theta_s']
        if 'density' in kwargs:
            self.density = kwargs['density']

        # inferenced settings
        self.p_num = len(x_list)
        self.grid_size = ti.ceil(self.dim_size / (2 * self.h)) + 1
        self.kernel_sig = 0.
        if self.dim == 1:
            self.kernel_sig = 2. / 3.
        elif self.dim == 2:
            self.kernel_sig = 10. / (7 * np.pi)
        elif self.dim == 3:
            self.kernel_sig = 1 / np.pi
        self.kernel_sig /= self.h**self.dim

        # particle attributes
        self.x = ti.Vector(self.dim, ti.f32)  # positions
        self.v = ti.Vector(self.dim, ti.f32)  # velocity
        self.v_tmp = ti.Vector(self.dim, ti.f32)  # velocity_star
        self.rho = ti.var(ti.f32)  # density
        self.rho_0 = ti.var(ti.f32)  # rest density of the current time
        self.rho_tmp = ti.var(ti.f32)  # density_star
        self.a_other = ti.Vector(self.dim, ti.f32)  # acceleration_other
        self.a_friction = ti.Vector(self.dim, ti.f32)  # acceleration_friction
        self.a_lambda = ti.Vector(self.dim, ti.f32)  # acceleration_lambda
        self.a_G = ti.Vector(self.dim, ti.f32)  # acceleration_G
        self.pressure = ti.var(ti.f32)
        self.flag = ti.var(ti.f32)
        self.F_E = ti.Matrix(self.dim, self.dim, ti.f32)
        self.L = ti.Matrix(self.dim, self.dim, ti.f32)
        self.lbda = ti.var(ti.f32)
        self.G = ti.var(ti.f32)
        self.diag = ti.var(ti.f32)  # a_ii for jacobi solver
        self.vec_tmp = ti.Vector(self.dim, ti.f32)
        self.var_tmp = ti.var(ti.f32)
        self.lhs = ti.Vector(self.dim, ti.f32)
        self.rhs = ti.Vector(self.dim, ti.f32)
        self.mat_tmp = ti.Matrix(self.dim, self.dim, ti.f32)
        self.p_solve = ti.Vector(self.dim, ti.f32)
        self.v_solve = ti.Vector(self.dim, ti.f32)
        self.res_solve = ti.Vector(self.dim, ti.f32)
        self.s_solve = ti.Vector(self.dim, ti.f32)
        self.t_solve = ti.Vector(self.dim, ti.f32)
        ti.root.dense(ti.i, self.p_num).place(
            self.x, self.flag, self.v, self.v_tmp, self.rho, self.rho_0,
            self.rho_tmp, self.a_other, self.a_friction, self.a_lambda,
            self.a_G, self.pressure, self.F_E, self.L, self.lbda, self.G,
            self.diag, self.vec_tmp, self.var_tmp, self.lhs, self.rhs,
            self.mat_tmp, self.p_solve, self.v_solve, self.res_solve,
            self.s_solve, self.t_solve)
        self.nbrs_num = ti.var(ti.i32)
        self.nbrs_list = ti.var(ti.i32)
        nbrs_nodes = ti.root.dense(ti.i, self.p_num)
        nbrs_nodes.place(self.nbrs_num)
        nbrs_nodes.dense(ti.j, self.nbrs_num_max).place(self.nbrs_list)

        # grid attributes
        self.grid_p_num = ti.var(ti.i32)
        self.grids = ti.var(ti.i32)
        grid_nodes = ti.root.dense(ti.ij,
                                   (self.grid_size[0], self.grid_size[1]))
        grid_nodes.place(self.grid_p_num)
        grid_nodes.dense(ti.k, self.grid_pnum_max).place(self.grids)

        # data initialize
        self.rho.fill(self.density)
        self.parallel_init(np.array(x_list), np.array(flag_list))
示例#22
0
def render_triangle(model, camera, face):
    scene = model.scene
    L2W = model.L2W
    posa, posb, posc = model.pos[face[0, 0]], model.pos[face[1, 0]], model.pos[
        face[2, 0]]
    texa, texb, texc = model.tex[face[0, 1]], model.tex[face[1, 1]], model.tex[
        face[2, 1]]
    nrma, nrmb, nrmc = model.nrm[face[0, 2]], model.nrm[face[1, 2]], model.nrm[
        face[2, 2]]
    posa = camera.untrans_pos(L2W @ posa)
    posb = camera.untrans_pos(L2W @ posb)
    posc = camera.untrans_pos(L2W @ posc)
    nrma = camera.untrans_dir(L2W.matrix @ nrma)
    nrmb = camera.untrans_dir(L2W.matrix @ nrmb)
    nrmc = camera.untrans_dir(L2W.matrix @ nrmc)

    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)
    tan, bitan = compute_tangent(-dpab, -dpac, -dtab, -dtac)

    # 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:

        clra = model.vertex_shader(posa, texa, nrma, tan, bitan)
        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 = 1 / ts.cross(A - C, B - A)
        B_A = (B - A) * scr_norm
        C_B = (C - B) * scr_norm
        A_C = (A - C) * scr_norm

        # 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.res))
        N = ts.clamp(N, 0, ti.Vector(camera.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
            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
            zindex = 1 / (posa.z * w_A + posb.z * w_B + posc.z * w_C)
            if zindex < ti.atomic_max(camera.fb['idepth'][X], zindex):
                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))
示例#23
0
def render_triangle(model, camera, face):
    scene = model.scene
    L2W = model.L2W
    _1 = ti.static(min(1, model.faces.m - 1))
    _2 = ti.static(min(2, model.faces.m - 1))
    ia, ib, ic = model.vi[face[0, 0]], model.vi[face[1, 0]], model.vi[face[2,
                                                                           0]]
    ta, tb, tc = model.vt[face[0, _1]], model.vt[face[1,
                                                      _1]], model.vt[face[2,
                                                                          _1]]
    na, nb, nc = model.vn[face[0, _2]], model.vn[face[1,
                                                      _2]], model.vn[face[2,
                                                                          _2]]
    a = camera.untrans_pos(L2W @ ia)
    b = camera.untrans_pos(L2W @ ib)
    c = camera.untrans_pos(L2W @ ic)

    # 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.
    normal = ts.normalize(ts.cross(a - b, a - c))
    pos = (a + b + c) / 3
    view_pos = (a + b + c) / 3
    if ti.static(camera.type == camera.ORTHO):
        view_pos = ts.vec3(0.0, 0.0, 1.0)
    if ts.dot(view_pos, normal) <= 0:
        # shading
        color = ts.vec3(0.0)
        for light in ti.static(scene.lights):
            color += scene.opt.render_func(pos, normal, ts.vec3(0.0), light)
        color = scene.opt.pre_process(color)
        A = camera.uncook(a)
        B = camera.uncook(b)
        C = camera.uncook(c)
        scr_norm = 1 / ts.cross(A - C, B - A)
        B_A = (B - A) * scr_norm
        C_B = (C - B) * scr_norm
        A_C = (A - C) * scr_norm

        W = 1
        # screen space bounding box
        M, N = int(ti.floor(min(A, B, C) - W)), int(ti.ceil(max(A, B, C) + W))
        M.x, N.x = min(max(M.x, 0),
                       camera.img.shape[0]), min(max(N.x, 0),
                                                 camera.img.shape[1])
        M.y, N.y = min(max(M.y, 0),
                       camera.img.shape[0]), min(max(N.y, 0),
                                                 camera.img.shape[1])
        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
            w_C = ts.cross(B_A, X_A)
            w_B = ts.cross(A_C, X_A)
            w_A = 1 - w_C - w_B
            # draw
            in_screen = w_A >= 0 and w_B >= 0 and w_C >= 0 and 0 < X[
                0] < camera.img.shape[0] and 0 < X[1] < camera.img.shape[1]
            if not in_screen:
                continue
            zindex = 1 / (a.z * w_A + b.z * w_B + c.z * w_C)
            if zindex < ti.atomic_max(camera.zbuf[X], zindex):
                continue

            coor = (ta * w_A + tb * w_B + tc * w_C)
            camera.img[X] = color * model.texSample(coor)
示例#24
0
    def __init__(self, x_list, gui, dim=2, **kwargs):
        # basic render settings
        self.dim = dim
        self.dim_size = ti.Vector([1., 1.])
        self.minx = ti.Vector([-1., -1.])
        assert self.dim == 1 or self.dim == 2 or self.dim == 3
        self.dt = 2e-3  # time unit is 1/30 second
        # self.dt = 0.022
        self.gui = gui
        self.vel_max = 50

        # basic solver settings
        self.r = 0.1  # particle spacing
        self.h = self.r
        self.nbrs_num_max = 3000
        self.grid_pnum_max = 3000
        self.g = ti.Vector([0, -9.8])
        # check section 5.3 for setting
        self.sigma = 0.3
        self.beta = 0.3  # a non-zero value
        self.gamma = 0.1  # typically 0 ~ 0.2
        self.alpha = 0.3
        # check section 7 at the last for setting
        self.k = 0.504
        self.k_near = 5.04
        self.k_spring = 0.3
        self.rho_0 = 100.0
        # see section 6.1
        self.mu = 0
        # see https://github.com/omgware/fluid-simulator-v2/blob/master/fluid-simulator/src/com/fluidsimulator/FluidSimulatorSPH.java
        self.collisionForce = 100.0

        # inferenced settings
        self.p_num = len(x_list)
        self.grid_size = ti.ceil(
            (self.dim_size - self.minx) / (2 * self.h)) + 10

        # particle attributes
        self.x = ti.Vector(self.dim, ti.f32)  # positions
        self.x_old = ti.Vector(self.dim, ti.f32)  # old positions
        self.v = ti.Vector(self.dim, ti.f32)  # velocity
        ti.root.dense(ti.i, self.p_num).place(self.x, self.x_old, self.v)

        self.nbrs_num = ti.var(ti.i32)
        self.nbrs_list = ti.var(ti.i32)
        self.strs_list = ti.var(ti.f32)
        self.strs_flag = ti.var(ti.i32)
        # self.L_list = ti.var(ti.f32)
        nbrs_nodes = ti.root.dense(ti.i, self.p_num)
        nbrs_nodes.place(self.nbrs_num)
        nbrs_nodes.dense(ti.j,
                         self.nbrs_num_max).place(self.nbrs_list,
                                                  self.strs_list,
                                                  self.strs_flag)

        # grid attributes
        self.grid_p_num = ti.var(ti.i32)
        self.grids = ti.var(ti.i32)
        grid_nodes = ti.root.dense(ti.ij,
                                   (self.grid_size[0], self.grid_size[1]))
        grid_nodes.place(self.grid_p_num)
        grid_nodes.dense(ti.k, self.grid_pnum_max).place(self.grids)

        self.particle_list = np.array(x_list)
示例#25
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))
示例#26
0
 def foo():
     x[None] = ti.neg(y[None])
     x[None] = ti.floor(x[None])
     y[None] = ti.ceil(y[None])
示例#27
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))