def intersectAll(self, ray, tmin, tmax): l = float(self.side) / 2 p1 = self.center.add(r.Vec3(l, l, l)) p2 = self.center.add(r.Vec3(l, l, -l)) p3 = self.center.add(r.Vec3(l, -l, -l)) p4 = self.center.add(r.Vec3(-l, l, l)) p5 = self.center.add(r.Vec3(-l, -l, l)) p6 = self.center.add(r.Vec3(-l, -l, -l)) hits = [] # top hits.append(self.intersectSide(ray, tmin, tmax, (p1, p4, p2))) # right side hits.append(self.intersectSide(ray, tmin, tmax, (p2, p3, p1))) # back hits.append(self.intersectSide(ray, tmin, tmax, (p3, p6, p2))) # front hits.append(self.intersectSide(ray, tmin, tmax, (p4, p1, p5))) # left side hits.append(self.intersectSide(ray, tmin, tmax, (p5, p6, p4))) # bottom hits.append(self.intersectSide(ray, tmin, tmax, (p6, p3, p5))) return hits
def __init__(self, color=r.Vec3(0.1, 0.1, 0.1)): """___init___ takes a optional color. If no color is provided the Object is dark grey""" self.color = color
def final_demo(): persp = PerspectiveCamera(r.Vec3(0, 0, 0), r.Vec3(0, 1, 0), r.Vec3(0, 0, -1), 32, 24, r.Vec3(16, 12, 50)) c = Cube(r.Vec3(7, 14, 10), 4, r.Vec3(1, 0, 0)) c2 = Cube(r.Vec3(9.5, 14, 10), 5, r.Vec3(1, 0.5, 0)) s = Sphere(r.Vec3(7, 14, 10), 2.8, r.Vec3(0, 0, 1)) s2 = Sphere(r.Vec3(7, 14, 10), 2.2, r.Vec3(0, 1, 0)) csg = CSG(c, s, Operation.INTERSECTION) csg2 = CSG(csg, c2, Operation.DIFFERENCE) #csg3 = CSG(csg2, s2, Operation.DIFFERENCE) group = Group() group.addObject(csg2) l1 = AmbientLight(r.Vec3(0.3, 0.3, 0.3)) l2 = DirectionalLight(r.Vec3(1, -0.5, 1), r.Vec3(0.2, 0.7, 0.2)) l3 = DirectionalLight(r.Vec3(1, 2, 1), r.Vec3(0, 0, 0.3)) l4 = DirectionalLight(r.Vec3(-1, 0, 1), r.Vec3(0.6, 0.1, 0.1)) l5 = DirectionalLight(r.Vec3(0, 0, -1), r.Vec3(1, 1, 1)) lights = [l1, l2, l3, l4, l5] #lights = [l1,l5] generateImage(320, 240, persp, group, 0.001, 55, lights, RenderMode.SHADOWS, r.Vec3(1, 1, 1))
def cube_demo(): persp = PerspectiveCamera(r.Vec3(0, 0, 0), r.Vec3(0, 1, 0), r.Vec3(0, 0, -1), 32, 24, r.Vec3(16, 12, 50)) c = Cube(r.Vec3(7, 8, 10), 4, r.Vec3(1, 0, 0)) c2 = Cube(r.Vec3(7, 8, 12), 2, r.Vec3(0, 1, 0)) t = Transformation(c2) t.setTransform( m.Matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 3, 0], [0, 0, 0, 1]])) s = Sphere(r.Vec3(7, 8, 10), 2.8, r.Vec3(0, 0, 1)) s2 = Sphere(r.Vec3(7, 8, 10), 1, r.Vec3(0, 1, 0)) csg = CSG(c, s, Operation.INTERSECTION) csg2 = CSG(csg, s2, Operation.DIFFERENCE) csg3 = CSG(csg2, t, Operation.DIFFERENCE) #t.setTransform(m.Matrix([[math.cos(-45),0,math.sin(-45),0],[0,1,0,0],[-(math.sin(-45)),0,math.cos(-45),0],[0,0,0,1]])) group = Group() group.addObject(csg3) l1 = AmbientLight(r.Vec3(0.3, 0.3, 0.3)) l2 = DirectionalLight(r.Vec3(1, -0.5, 1), r.Vec3(0.2, 0.7, 0.2)) l3 = DirectionalLight(r.Vec3(1, 2, 1), r.Vec3(0, 0, 0.3)) l4 = DirectionalLight(r.Vec3(-1, 0, 1), r.Vec3(0.6, 0.1, 0.1)) l5 = DirectionalLight(r.Vec3(0, 0, -1), r.Vec3(1, 1, 1)) lights = [l1, l2, l3, l5] #lights = [l1,l5] generateImage(320, 240, persp, group, 0, 55, lights, RenderMode.DIFFUSE, r.Vec3(1, 1, 1))
def sphere_demo(): persp = PerspectiveCamera(r.Vec3(0, 0, 0), r.Vec3(0, 1, 0), r.Vec3(0, 0, -1), 32, 24, r.Vec3(16, 12, 50)) s1 = Sphere(r.Vec3(16, 12, 10), 5, r.Vec3(1, 0, 0)) s2 = Sphere(r.Vec3(13, 13, 15), 3, r.Vec3(0, 0, 1)) s3 = Sphere(r.Vec3(14, 9, 12), 4, r.Vec3(0, 1, 0)) cTest = CSG(s1, s2, Operation.DIFFERENCE) cTest2 = CSG(cTest, s3, Operation.DIFFERENCE) group = Group() #group.addObject(s1) # group.addObject(s2) #group.addObject(cTest) group.addObject(cTest2) l1 = AmbientLight(r.Vec3(0.3, 0.3, 0.3)) l2 = DirectionalLight(r.Vec3(1, -0.5, 1), r.Vec3(0.2, 0.7, 0.2)) l3 = DirectionalLight(r.Vec3(1, 2, 1), r.Vec3(0, 0, 0.3)) l4 = DirectionalLight(r.Vec3(-1, 0, 1), r.Vec3(0.6, 0.1, 0.1)) l5 = DirectionalLight(r.Vec3(1, 2, 1), r.Vec3(1, 1, 1)) #lights = [l1,l2,l3] lights = [l1, l5] generateImage(320, 240, persp, group, 0, 55, lights, RenderMode.SHADOWS, r.Vec3(1, 1, 1))
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()
def getIntensity(self, intersectionPoint, surfaceNormal): dotp = surfaceNormal.dot(self.direction) if dotp > 0: return self.color.scalarMult(dotp) else: return r.Vec3(0, 0, 0)