def L(self, my_ray, current_depth):
        Lo = glm.vec3(.0, .0, .0)
        inter_rec = ir.IntersectionRecord()
        if current_depth < self.max_depth:
            inter_rec.t = sys.float_info.max
            if self.scene.intersect(my_ray, inter_rec):

                if inter_rec.material.name == "Light":
                    return inter_rec.material.getEmittance()

                tangent_to_universe_space = onb.ONB()
                tangent_to_universe_space.setFromV(inter_rec.normal)
                universe_to_tangent_space = onb.ONB()
                universe_to_tangent_space.setFromV(inter_rec.normal)
                universe_to_tangent_space.transpose()

                wi = universe_to_tangent_space.multMatrixVec3(
                    -my_ray.direction)
                wo = inter_rec.material.bounce(wi)

                new_direction = tangent_to_universe_space.multMatrixVec3(wo)

                ref_ray = ray.Ray(inter_rec.position + (new_direction * 0.001),
                                  new_direction)

                current_depth += 1
                Lo = inter_rec.material.getEmittance(
                ) + inter_rec.material.getFr(wi, wo) * self.L(
                    ref_ray, current_depth)

        return Lo
示例#2
0
    def intersect(self, ray, hit, tmin, tmax):
        # transform ray by inverse matrix
        inv = self.mat.inverse()
        tro = inv.vecMult(ray.getOrigin())  # tro = Transformed Ray Origin
        trd = inv.vecMult(ray.getDirection(),
                          0)  # trd = Transformed Ray Direction

        # normalize transformed direction
        trdn = trd.normalize()

        # define transformed ray as a ray
        tr = r.Ray(trdn, tro)
        s = trd.length()

        # Get object hit with transformed ray
        h = self.obj.intersect(tr, hit, tmin * s, tmax * s)

        if h.t == float('inf'):
            return hit
        else:
            # transform the normal by transposed inverse matrix
            invtr = inv.transpose()
            tnor = invtr.vecMult(h.normal).normalize()

            t = h.t / float(s)
            return r.Hit(t, h.color, tnor)
示例#3
0
 def generateRay(self, screenCoord):
     """
     generateRay takes a Point2D and returns a ray  It expects x and y to be between 0 and 1.
     The origin on the ray corresponds to x,y mapped onto the projection plain.
     The direction of the ray is defined by the camera's initializer
     """
     orig = super(PerspectiveCamera,
                  self).screenToPlaneLocation(screenCoord)
     return r.Ray(orig.sub(self.eye).normalize(), self.eye)
示例#4
0
 def generateRay(self, screenCoord):
     """
     generateRay takes a Point2D and returns a ray  It expects x and y to be between 0 and 1.
     The origin on the ray corresponds to x,y mapped onto the projection plain.
     The direction of the ray is defined by the camera's initializer
     """
     return r.Ray(
         self.dir,
         super(OrthographicCamera, self).screenToPlaneLocation(screenCoord))
 def __cast_rays(self):
     # based on http://lodev.org/cgtutor/raycasting.html
     for x_column in range(self._width):
         # initiate a Ray Object
         ray_obj = ray.Ray(self, x_column)
         ray_obj.render_texture()
         # Save the distance to the drawn wall in the buffer. This lets you quickly test,
         # wether the Thing's sprite you're trying to render isn't in fact behind a wall.
         self.zbuffer.append(ray_obj.wall_distance)
示例#6
0
def getColor(r, accelerator, dep):
    dep = dep + 1
    if (dep > 3):
        return np.array([.0, .0, .0])
    prim_hit = accelerator.RayIntersect(r)
    #print("Hit__getColor__", prim_hit.id)
    if (prim_hit.isHit):
        eyeToPrimRay = r
        primToLightRay = (ray.Ray(r.origin + prim_hit.t * r.direction,
                                  camera.light))
        primNormal = accelerator.primList[prim_hit.id].GetNormalVector(
            r.origin + prim_hit.t * r.direction)
        if (np.dot(r.direction, primNormal) > 0):
            primNormal = primNormal * -1
        biSector = npe.Normalize3f(eyeToPrimRay.direction * -1 +
                                   primToLightRay.direction)

        reflect = npe.Normalize3f(
            eyeToPrimRay.direction +
            2 * abs(np.dot(eyeToPrimRay.direction, primNormal)) * primNormal)
        ka = 0.25
        kd = 0.9
        ks = 0.3
        kr = 0.2
        if (dep == 1):
            kr = 1.0
        exp = 20
        shadow_hit = accelerator.RayIntersect(primToLightRay)

        ambient = ka * accelerator.primList[prim_hit.id].ambient
        #(np.dot(eyeToPrimRay.direction, primNormal) * np.dot(primToLightRay.direction, primNormal) > 0)
        diffuse = specular = .0
        if (not shadow_hit.isHit):
            diffuse = abs(kd * np.dot(primToLightRay.direction, primNormal))
            specular = abs(ks * math.pow(np.dot(biSector, primNormal), 20))
        Iad = ambient + diffuse
        R = 255 * Iad + 255 * specular
        G = 255 * Iad + 255 * specular
        B = 255 * Iad + 255 * specular
        hitPoint = r.origin + prim_hit.t * r.direction
        nxt = ray.Ray(hitPoint, hitPoint + reflect)
        return (np.array([R, G, B]) + getColor(nxt, accelerator, dep + 1)) * kr
    else:
        return np.array([.0, .0, .0])
示例#7
0
    def generateRay(self, pix_x, pix_y):

        # compute direction
        xmax = np.sin(self.fov) * self.flength
        dx = -xmax + pix_x * (2 * xmax) / (self.image.shape[0])
        dy = -xmax + pix_y * (2 * xmax) / (self.image.shape[1])

        dir = np.array([dx, dy, 1.0])
        dir = dir / np.linalg.norm(dir)

        r = ray.Ray(self.pos, dir)
        return r
    def getWorldSpaceRay(self, pixel_coord):
        u = self.max_x - self.min_x
        v = -(self.max_y - self.min_y)
        w = -self.distance

        cam_x = (pixel_coord.x) / float(self.camera.resolution.x)
        cam_y = (pixel_coord.y) / float(self.camera.resolution.y)

        cam_vec = glm.vec3(cam_x * u + self.min_x, cam_y * v - self.min_y, w)

        return ray.Ray(self.camera.position,
                       glm.normalize(self.camera.onb.multMatrixVec3(cam_vec)))
示例#9
0
 def draw_canvas(scene, filename):
     f = open(filename, "w")
     f.write("P3 \n")
     f.write(str(int(CANVAS_WIDTH)) + " " + str(int(CANVAS_HEIGHT)) + "\n")
     f.write("255 \n")
     for i in range(0, int(CANVAS_HEIGHT)):
         for j in range(0, int(CANVAS_WIDTH)):
             [x, y, z] = Canvas.get_view_point(j, i)
             r = ray.Ray(EYE_LOCATION, np.array([x, y, z]))
             f.write(
                 Canvas.col_string(scene.trace_ray(r, 0, RECURSION_DEPTH)))
         f.write("\n")
    def getWorldSpaceRay(self, pixel_coord):
        width = self.max_x - self.min_x
        height = self.max_y - self.min_y
        origin = glm.vec3(
            pixel_coord.x / float(self.camera.resolution.x) * width +
            self.min_x,
            (pixel_coord.y / float(self.camera.resolution.y) * height +
             self.min_y) * (-1), 0.0)

        return ray.Ray(
            self.camera.onb.multMatrixVec3(origin) + self.camera.position,
            glm.normalize(
                self.camera.onb.multMatrixVec3(glm.vec3(0.0, 0.0, -1.0))))
示例#11
0
 def doesIntersect(self, srcobject=None, lightray=None, intpoint=None):
     global logger
     assert (srcobject != None and lightray != None and intpoint != None)
     for item in self.objects:
         if item == srcobject:
             continue
         # TODO Origin numpy.array constant would be a good idea.
         tmpray = ray.Ray(orig=intpoint, dir=lightray)
         (hitpoint, viewvec, un, t) = \
                 item.findIntersection( dray = tmpray )
         if hitpoint != None and t > 0.0:
             # logger.debug( "%s hits %s" %
             #               (srcobject.myname, item.myname) )
             return True
     return False
示例#12
0
 def update(self, element_list, fov_step=2):
     #######################################################################################
     # Programmer Name: Alec
     # Date: 5/15/17
     # Purpose: update attributes of a player
     # Input: self, element_list, fov_step
     # Output: updated attributes for object
     #######################################################################################
     # movement/collision
     self.movement()
     for element in element_list:
         self.collision(element)
     # rays
     self.rays = []
     start = self.direction - (self.fov / 2)
     for i in range(0, self.fov + fov_step, fov_step):
         cast_ray = ray.Ray(i, self, 500, start + i, element_list)
         self.rays.append(cast_ray)
示例#13
0
def main():
    rnd = []
    for i in range(1):
        rnd.append(random.uniform(0, 1))
    rnd[0] = 0.5
    [vertices, face] = ply.parse_PLY()
    T_list = []
    for i in range(len(face)):
        v0 = vertices[face[i]['index1']]
        v1 = vertices[face[i]['index2']]
        v2 = vertices[face[i]['index3']]
        ambient = (v0[4] + v1[4] + v2[4]) / 3
        t = geo.Triangle(v0[0:3], v1[0:3], v2[0:3])
        t.ambient = ambient
        T_list.append(t)
    t = time.time()
    bvhAccelerator = BVH.BVHTree(T_list)
    print("Construct time", time.time() - t)
    t = time.time()
    for i in range(picture.height):
        for j in range(picture.width):
            color = np.zeros((3, ))
            for k in range(len(rnd)):
                #rnd = 0.5
                to = camera.lu + (j / picture.width) * camera.dy + (
                    i / picture.height) * camera.dx
                to = to + rnd[k] * (1 / picture.width) * camera.dy + rnd[k] * (
                    1 / picture.height) * camera.dx
                r = ray.Ray(camera.position, to)
                color = color + getColor(r, bvhAccelerator, 0)

            for k in range(len(color)):
                color[k] = min(math.floor(color[k] / len(rnd)), 255)

            picture.RGBarray[i * (picture.width * 3) + j * 3 + 0] = color[0]
            picture.RGBarray[i * (picture.width * 3) + j * 3 + 1] = color[1]
            picture.RGBarray[i * (picture.width * 3) + j * 3 + 2] = color[2]

    print("Render time", time.time() - t)
    img_bytes = bytes(picture.RGBarray)
    img = Image.frombytes("RGB", (picture.width, picture.height), img_bytes)
    img.save('output.png')
示例#14
0
def generateImage(width,
                  height,
                  camera,
                  group,
                  dist_min,
                  dist_max,
                  lights,
                  renderMode,
                  bgc=r.Vec3(1, 1, 1)):
    #create Raster
    ra = raster.Raster(width, height)
    #loop over all pixels
    for x in range(0, width):
        for y in range(0, height):

            #create Ray
            rayX = float(x) / width
            rayY = float(height - y) / height
            #ray = camera.screenToPlaneLocation(r.Point2D(rayX,rayY))
            ray = camera.generateRay(r.Point2D(rayX, rayY))

            #find closest hit
            h = group.intersect(ray, dist_min, dist_max)

            #in case no hit is found
            if h.t != float('inf'):
                #set pixel color based on render mode
                if renderMode == RenderMode.COLOR:
                    color = h.color

                elif renderMode == RenderMode.DISTANCE:
                    gray = (dist_max - h.t) / (dist_max - dist_min)
                    color = r.Vec3(gray, gray, gray)

                elif renderMode == RenderMode.DIFFUSE:
                    lsum = r.Vec3(0, 0, 0)
                    intersectionPoint = ray.pointAtParameter(h.t)
                    surfaceNormal = h.getNormal().normalize()
                    for l in lights:
                        lco = l.getIntensity(intersectionPoint, surfaceNormal)
                        lsum.x += h.color.x * lco.x
                        lsum.y += h.color.y * lco.y
                        lsum.z += h.color.z * lco.z
                    # Check lsum values (cap at 1)
                    if lsum.x > 1: lsum.x = 1
                    if lsum.y > 1: lsum.y = 1
                    if lsum.z > 1: lsum.z = 1

                    color = lsum

                elif renderMode == RenderMode.SHADOWS:
                    lsum = r.Vec3(0, 0, 0)
                    intersectionPoint = ray.pointAtParameter(h.t)
                    surfaceNormal = h.getNormal().normalize()
                    for l in lights:
                        lco = l.getIntensity(intersectionPoint, surfaceNormal)
                        h2 = r.Hit()

                        # Use 'try' to assume the light is directional,
                        # so shadows can be calculated

                        try:
                            #mode = 'directional'
                            ray2 = r.Ray(l.direction.normalize(),
                                         intersectionPoint)
                            h2 = group.intersect(ray2, 0.001, dist_max)
                            if h2.t == float('inf'):
                                lsum.x += h.color.x * lco.x
                                lsum.y += h.color.y * lco.y
                                lsum.z += h.color.z * lco.z

                        # if code throws an attribute error, light is ambient
                        # (ambient lights have no attribute "direction")
                        except AttributeError:
                            #mode = 'ambient'
                            lsum.x += h.color.x * lco.x
                            lsum.y += h.color.y * lco.y
                            lsum.z += h.color.z * lco.z

                    # Check lsum values (cap at 1)
                    if lsum.x > 1: lsum.x = 1
                    if lsum.y > 1: lsum.y = 1
                    if lsum.z > 1: lsum.z = 1

                    color = lsum

                else:
                    print("invalid render mode")
                    pass
            else:
                color = bgc

            # color up until this point must be a Vec3 between 0-1
            color = color.scalarMult(255)
            color = (color.x, color.y, color.z)
            ra.setPixel(x, y, color)

    ra.display()
示例#15
0
            amblight = numpy.array([150, 10, 10])
            im = self.ill_model2
        color = numpy.array( [0.0, 0.0, 0.0] )
        for l in lightlist:
            lightvec = l.GetOrigin() - intpoint
            lightvec = lightvec / numpy.linalg.norm( lightvec )
            normalvec = self.normal / numpy.linalg.norm( self.normal )
            lightflag = True
            if self.wintfn( srcobject = self,
                            lightray = lightvec,
                            intpoint = intpoint ):
                # It intersects something.
                # Light does not affect this object.
                lightflag = False
            color = color + im.GetColor( amblight = amblight,
                                         light = light,
                                         lightvec = lightvec,
                                         normalvec = normalvec,
                                         lightflag = lightflag,
                                         viewvec = viewvec )
        return [ max(0, min( 255, x )) for x in color ]

if __name__ == "__main__":
    print "Basic Plane class test:"
    myplane = Plane( numpy.array( [ 1., 5., 0. ] ),
                     -3. )
    rOrig = numpy.array([ 1., 1., 0. ])
    rDir = numpy.array([ 0., 1., 0. ])
    xtn = myplane.findIntersection( ray.Ray( rOrig, rDir ) )
    print "Intersection: ", xtn