Exemplo n.º 1
0
    def target_surface(self):
        for I in ti.grouped(self.phi):
            sign_change = False
            est = ti.cast(1e20, self.real)
            for k in ti.static(range(self.dim)):
                for s in ti.static((-1, 1)):
                    offset = ti.Vector.unit(self.dim, k) * s
                    I1 = I + offset
                    if I1[k] >= 0 and I1[k] < self.res[k] and \
                    ts.sign(self.phi[I]) != ts.sign(self.phi[I1]):
                        theta = self.phi[I] / (self.phi[I] - self.phi[I1])
                        est0 = ts.sign(self.phi[I]) * theta * self.dx
                        est = est0 if ti.abs(est0) < ti.abs(est) else est
                        sign_change = True

            if sign_change:
                self.phi_temp[I] = est
                self.valid[I] = 0
            else:
                self.phi_temp[I] = ti.cast(
                    1e20,
                    self.real)  # an upper bound for all possible distances
Exemplo n.º 2
0
    def target_minus(self):
        for I in ti.grouped(self.phi):
            self.phi[I] -= (
                0.99 * self.dx
            )  # the particle radius r (typically just a little less than the grid cell size dx)

        for I in ti.grouped(self.phi):
            sign_change = False
            for k in ti.static(range(self.dim)):
                for s in ti.static((-1, 1)):
                    offset = ti.Vector.unit(self.dim, k) * s
                    I1 = I + offset
                    if I1[k] >= 0 and I1[k] < self.res[k] and \
                    ts.sign(self.phi[I]) != ts.sign(self.phi[I1]):
                        sign_change = True

            if sign_change and self.phi[I] <= 0:
                self.valid[I] = 0
                self.phi_temp[I] = self.phi[I]
            elif self.phi[I] <= 0:
                self.phi_temp[I] = ti.cast(-1, self.real)
            else:
                self.phi_temp[I] = self.phi[I]
                self.valid[I] = 0
Exemplo n.º 3
0
    def propagate(self):
        while not self.priority_queue.empty():
            I0 = self.priority_queue.top()
            self.priority_queue.pop()

            for k in ti.static(range(self.dim)):
                for s in ti.static((-1, 1)):
                    offset = ti.Vector.unit(self.dim, k) * s
                    I = I0 + offset
                    if I[k] >= 0 and I[k] < self.res[k] and \
                    self.valid[I] == -1:
                        d = self.update_from_neighbor(I)
                        if d < ti.abs(self.phi_temp[I]):
                            self.phi_temp[I] = d * ts.sign(self.phi[I0])
                        self.valid[I] = 0
                        self.priority_queue.push(ti.abs(self.phi_temp[I]), I)
Exemplo n.º 4
0
 def propagate_update(self, I, s):
     if self.valid[I] == -1:
         d = self.update_from_neighbor(I)
         if ti.abs(d) < ti.abs(self.phi_temp[I]):
             self.phi_temp[I] = d * ts.sign(self.phi[I])
     return s
Exemplo n.º 5
0
def render():
    for i, j in rt_canvas.hdr:

        next_origin = rt_canvas.get_ray_origin()
        next_dir = rt_canvas.get_ray_direction(i, j)
        depth = 0
        pdf = 1.0
        perfect_spec = 0
        f_or_b = 1.0
        brdf = ti.Vector([1.0, 1.0, 1.0])
        throughout = ti.Vector([1.0, 1.0, 1.0])
        radiance = ti.Vector([0.0, 0.0, 0.0])

        while (depth < MAX_DEPTH):
            origin = next_origin
            direction = next_dir

            t, pos, normal, tex, prim_id = bvh.closet_hit(
                origin, direction, rt_canvas.stack, i, j, Canvas.STACK_SIZE)
            fnormal = faceforward(normal, -direction, normal)
            mat_id = UF.get_prim_mindex(bvh.primitive, prim_id)
            mat_emission = UF.get_material_emission(bvh.material, mat_id)
            mat_type = UF.get_material_type(bvh.material, mat_id)

            if t < UF.INF_VALUE:
                if mat_emission.sum() > Bvh.IS_LIGHT:
                    fCosTheta = direction.dot(normal)
                    if fCosTheta < 0.0:
                        area = bvh.get_prim_area(prim_id)
                        if (perfect_spec == 1) | (depth == 0):
                            radiance += mat_emission
                            #radiance = radiance
                        else:
                            lightPdf = (t * t) / (area * fCosTheta)
                            radiance += powerHeuristic(
                                pdf, lightPdf) * throughout * mat_emission
                    break
                else:
                    next_origin = offset_ray(pos, fnormal)

                    #btdf
                    if mat_type == 1:
                        perfect_spec = 1
                        next_dir, f_or_b = glass.sample(
                            direction, normal, t, i, j, bvh.material, mat_id)
                        brdf, pdf = glass.evaluate(normal, next_dir,
                                                   -direction, bvh.material,
                                                   mat_id)
                    else:
                        #disney
                        perfect_spec = 0

                        #direct lighting
                        light_prim_id = bvh.get_random_light_prim_index()
                        light_pos, light_normal = bvh.get_prim_random_point_normal(
                            light_prim_id)

                        light_dir = light_pos - next_origin
                        light_dist = light_dir.norm()
                        light_dir = light_dir / light_dist
                        NdotL_light = -light_normal.dot(light_dir)
                        NdotL_surface = normal.dot(light_dir)

                        ####shadow
                        if (NdotL_light > 0.0) & (NdotL_surface > 0.0):
                            shadow_prim = bvh.closet_hit_shadow(
                                next_origin, light_dir, rt_canvas.stack, i, j,
                                Canvas.STACK_SIZE)
                            shadow_mat = UF.get_prim_mindex(
                                bvh.primitive, shadow_prim)
                            shadow_emission = UF.get_material_emission(
                                bvh.material, shadow_mat)
                            if shadow_emission.sum() > Bvh.IS_LIGHT:
                                brdf, pdf = disney.evaluate(
                                    normal, -direction, light_dir,
                                    bvh.material, mat_id)
                                if pdf > 0.0:
                                    light_emission = UF.get_material_emission(
                                        bvh.material,
                                        UF.get_prim_mindex(
                                            bvh.primitive, light_prim_id))
                                    light_area = bvh.get_prim_area(
                                        light_prim_id)
                                    lightPdf = light_dist * light_dist / (
                                        light_area * NdotL_light)
                                    radiance += powerHeuristic(
                                        lightPdf, pdf) * light_emission / max(
                                            0.001,
                                            lightPdf) * throughout * brdf

                        next_dir, f_or_b = disney.sample(
                            direction, normal, i, j, bvh.material, mat_id)
                        brdf, pdf = disney.evaluate(normal, next_dir,
                                                    -direction, bvh.material,
                                                    mat_id)

                    next_origin = offset_ray(pos, ts.sign(f_or_b) * fnormal)

                    if pdf > 0.0:
                        throughout *= brdf / pdf * abs(f_or_b)
                        depth += 1
                    else:
                        break

                    #debug code , color map
                    #nl = -normal.dot(direction)
                    #nv = -normal.dot(direction)
                    #radiance = ts.reflect(-direction, normal)
                    #radiance = (next_dir + ti.Vector([1.0, 1.0, 1.0]))*0.5
                    #radiance  = brdf
                    #if depth == 0:
                    #    radiance  = ti.Vector([1.0, 0.0, 0.0])
                    #if depth == 1:
                    #    radiance  = ti.Vector([0.0, 1.0, 0.0])
                    #if depth == 2:
                    #    radiance  = ti.Vector([0.0, 0.0, 1.0])
                    #break

            else:
                dis = ti.sqrt(direction.x * direction.x +
                              direction.z * direction.z)
                tx = (ts.atan(direction.z, direction.x) +
                      3.1415926) / 3.1415926 / 2.0
                ty = (ts.atan(direction.y, dis)) / 3.1415926 + 0.5
                radiance += env.teture2D(tx, ty) * throughout
                break

        frame = float(rt_canvas.frame_gpu[0])
        rt_canvas.hdr[i, j] = (radiance +
                               rt_canvas.hdr[i, j] * frame) / (frame + 1.0)
Exemplo n.º 6
0
def faceforward(n, i, nref):
    return ts.sign(i.dot(nref)) * n