Пример #1
0
    def intersect(self, ray):

        r = Normalize(ray.d)
        # Checando se o triangulo e o raio são paralelos
        if Dot(r, self.normal) == 0.0:
            # Raio nao intersecta o triangulo
            hit = False
            distance = 0.0
            hit_point = Vector3D(0.0, 0.0, 0.0)

            return (hit, distance, hit_point, self.normal)

        ray_dir = Normalize(ray.d)
        # Calculando o ponto que pode está no plano do triangulo
        t = Dot(self.normal, (self.A - ray.o)) / Dot(ray_dir, self.normal)
        hit_point = ray.get_hitpoint(t)

        if t < 0.0001:
            # Raio nao intersecta o triangulo
            hit = False
            distance = 0.0
            hit_point = Vector3D(0.0, 0.0, 0.0)

            return (hit, distance, hit_point, self.normal)

        # Checando se o Ponto está dentro do triangulo
        # Inside-OutSide Test
        vectorAB = self.B - self.A;
        vectorBC = self.C - self.B;
        vectorCA = self.A - self.C;

        C0 = hit_point - self.A
        C1 = hit_point - self.B
        C2 = hit_point - self.C

        if (Dot(self.normal, Cross(vectorAB, C0)) > 0
                and Dot(self.normal, Cross(vectorBC, C1)) > 0
                and Dot(self.normal, Cross(vectorCA, C2))) > 0:
            #print("Acertou: " + str (vectorAB))
            hit = True
            distance = t
            hit_point = ray.get_hitpoint(t)
            return (hit, distance, hit_point, self.normal)  # tuple

        if (Dot(self.normal, Cross(vectorAB, C0)) < 0
                and Dot(self.normal, Cross(vectorBC, C1)) < 0
                and Dot(self.normal, Cross(vectorCA, C2))) < 0:
            #print("Acertou")
            hit = True
            distance = t
            hit_point = ray.get_hitpoint(t)
            return (hit, distance, hit_point, self.normal)  # tuple

        # Didn't hit the triangule
        hit = False
        distance = 0.0
        hit_point = Vector3D(0.0, 0.0, 0.0)

        return (hit, distance, hit_point, self.normal)
    def trace_ray(self, ray, depth):
        difuso = BLACK
        especular = BLACK

        # Checando interseções com cada objeto
        dist = 100
        hit = False
        objeto = 1
        hit_point = Vector3D(0.0, 0.0, 0.0)
        normal = Vector3D(0.0, 0.0, 0.0)

        for obj in self.obj_list:
            inter = obj.intersect(ray)
            tmp_hit = inter[0]
            distance = inter[1]

            if tmp_hit and distance < dist:
                dist = distance
                objeto = obj
                hit = tmp_hit
                hit_point = inter[2]
                normal = inter[3]

        if hit: ## Se o raio bateu no objeto calculamos a cor do ponto
            if isinstance(objeto, Light):
                return objeto.color
            else:
                result = local_color(objeto, normal, ray, self.ambient)
        else:
            return self.background


        # Calculando os Raios Secúndarios
        ktot = obj.kd + obj.ks + obj.kt
        aleatorio = random.random()*ktot


        if depth > 0:
            if aleatorio < obj.kd:                            ## Raio Difuso
                x = random.random()
                y = random.random()
                dir = random_direction(x, y, normal)

                new_ray = Ray(hit_point, Normalize(dir))
                difuso = self.trace_ray(new_ray, depth - 1)
            elif aleatorio < obj.kd + obj.ks:        #         ## Raio especular
                L = Normalize(flip_direction(ray.d))
                N = objeto.normal
                R = (N * (Dot(N, L)) - L) * 2.0

                new_ray = Ray(hit_point, Normalize(R))
                especular = self.trace_ray(new_ray, depth - 1)
            else:                                               ## Raio Transmitido
                pass

        return result + difuso*objeto.trans_difusa + especular*objeto.trans_especular
Пример #3
0
 def __init__(self, eye_point, focal_point, view_distance, up_vector,
              image_height, image_width, samples_per_pixel):
     self.eye = eye_point
     self.focal = focal_point
     self.view_dist = view_distance
     self.up = up_vector
     self.height = image_height
     self.width = image_width
     self.spp = samples_per_pixel
     # setup orthonormal basis
     #####default values
     self.u = Vector3D(-1.0, 0.0, 0.0)
     self.v = Vector3D(0.0, 1.0, 0.0)
     self.w = Vector3D(0.0, 0.0, -1.0)
     self.compute_uvw()
     # create empty image array
     self.image_array = array.array('B', [0] * (image_width * image_height * 3))
    def photon_ray(self, ray, depth):

        # Checando interseções com cada objeto
        dist = 100
        hit = False
        objeto = 1
        hit_point = Vector3D(0.0, 0.0, 0.0)
        normal = Vector3D(0.0, 0.0, 0.0)

        for n in self.numeroPhotons:

            for obj in self.obj_list:

                # setado com os valores da fonte de luz para o primeiro caso
                if self.depth == 4:
                    inter = obj.intersect(-0.9100,
                                          3.8360 - 23.3240), (0.0, -1.0, 0.0)
                else:
                    inter = obj.intersect(ray)

                tmp_hit = inter[0]
                distance = inter[1]

                if tmp_hit and distance < dist:
                    dist = distance
                    objeto = obj
                    hit = tmp_hit
                    hit_point = inter[2]
                    normal = inter[3]

            if hit:  ## Se o raio bateu no objeto adicionamos o photon a estrutura de dados
                R1 = uniform(0.0, 1.0)
                R2 = uniform(0.0, 1.0)
                direcaoPhi = 1 / cos(sqrt(R1))
                direcaoTheta = 2 * pi * R2
                R = 1.0
                T = 1.0
                self.photons_list[self.contador] = Photon(
                    hit_point, R * 1.0 / self.numeroPhotons,
                    T * 1.0 / self.numeroPhotons, direcaoPhi, direcaoTheta)
                self.contador = self.contador + 1
Пример #5
0
    def compute_uvw(self):
        # w
        self.w = self.eye - self.focal
        self.w = Normalize(self.w)
        # u
        self.u = Cross(self.up, self.w)
        self.u = Normalize(self.u)
        # v
        self.v = Cross(self.w, self.u)
        self.v = Normalize(self.v)

        # check for singularity. if conditions met, camera orientations are hardcoded
        # camera looking straight down
        if (self.eye.x == self.focal.x and self.eye.z == self.focal.z
                and self.focal.y < self.eye.y):
            self.u = Vector3D(0.0, 0.0, 1.0)
            self.v = Vector3D(1.0, 0.0, 0.0)
            self.w = Vector3D(0.0, 1.0, 0.0)

        # camera looking straight up
        if (self.eye.x == self.focal.x and self.eye.z == self.focal.z
                and self.focal.y > self.eye.y):
            self.u = Vector3D(1.0, 0.0, 0.0)
            self.v = Vector3D(0.0, 0.0, 1.0)
            self.w = Vector3D(0.0, -1.0, 0.0)
Пример #6
0
    def intersect(self, ray):
        d = ray.d - ray.o

        dx = d[0]
        dy = d[1]
        dz = d[2]

        x0 = ray.o[0]
        y0 = ray.o[1]
        z0 = ray.o[2]

        acoef = 2 * self.f * dx * dz + 2 * self.e * dy * dz + self.c * dz * dz + self.b * dy * dy + self.a * dx * dx + 2 * d * dx * dy

        bcoef = (2 * self.b * y0 * dy + 2 * self.a * x0 * dx + 2 * self.c * z0 * dz) + \
                (2 * self.h * dy + 2 * self.g * dx + 2 * self.j * dz + 2 * d * x0 * dy) + \
                (2 * self.e * y0 * dz + 2 * self.e * z0 * dy + 2 * d * y0 * dx) + \
                (2 * self.f * x0 * dz + 2 * self.f * z0 * dx)

        ccoef = (self.a * x0 * x0 + 2 * self.g * x0 + 2 * self.f * x0 * z0 + self.b * y0 * y0) + \
                (2 * self.e * y0 * z0 + 2 * d * x0 * y0 + self.c * z0 * z0 + 2 * self.h * y0) + \
                (2 * self.j * z0 + self.k)

        ## The following was modified by David J. Brandow to allow for planar

        ## quadrics
        if 1.0 + acoef == 1.0:
            if 1.0 + bcoef == 1.0:
                hit = False
                distance = 0.0
                hit_point = Vector3D(0.0, 0.0, 0.0)

                return (hit, distance, hit_point, self.normal)

            t = (-ccoef) / (bcoef)
        else:
            disc = bcoef * bcoef - 4 * acoef * ccoef

            if 1.0 + disc < 1.0:
                hit = False
                distance = 0.0
                hit_point = Vector3D(0.0, 0.0, 0.0)

                return (hit, distance, hit_point, self.normal)

            root = sqrt(disc)
            t = (-bcoef - root) / (acoef + acoef)

            if t < 0.0:
                t = (-bcoef + root) / (acoef + acoef)

        if (t < 0.001):
            hit = False
            distance = 0.0
            hit_point = Vector3D(0.0, 0.0, 0.0)

            return (hit, distance, hit_point, self.normal)

        hit_point = ray.get_hitpoint(t)
        normal = hit_point - Vector3D(self.a, self.b, self.c)

        return (True, t, hit_point, normal)
Пример #7
0
    elif line_type in obj_types_list:
        new_objs_list = (read(line_type, values))
        obj_list = obj_list + new_objs_list
    elif line_type in prop_types_list:
        prop_dict[line_type] = (read(line_type, values))
    else:
        print("Tipo não encontrado")
        print(line_type)

FILENAME = str(prop_dict['output'])

#print("Lista de objetos: ", obj_list)
#print("Lista de propriedades: ", prop_dict)

#Create Camera
eye = Vector3D(prop_dict['eye'][0], prop_dict['eye'][1],
               prop_dict['eye'][2])  #higher z = more narrow view
focal = Vector3D(0.0, 0.0, 0.0)
view_distance = 1000
up = Vector3D(0.0, 1.0, 0.0)
height = int(prop_dict['size'][0])
width = int(prop_dict['size'][1])
spp = int(prop_dict['npaths'])
cam = Camera(eye, focal, view_distance, up, height, width, spp)

# Realiza o path tracing
pathTracer = PathTraceIntegrator()
pathTracer.obj_list = obj_list
cam.render(pathTracer, FILENAME, int(prop_dict["deepth"]),
           float(prop_dict["tonemapping"]))

#-------------------------------------------------Temporary GUI