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
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)
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)
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)
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])
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)))
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))))
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
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)
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')
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()
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