def getCheckerImage(cls,ImageSize,sqSize): from math import floor nx = ImageSize/sqSize ny = ImageSize/sqSize colors = [] for i in range (ImageSize): row = [] for j in range(int(nx)): for px in range(sqSize): if((floor(i/sqSize)+j)%2): row.append(Color(1,1,1)) else: row.append(Color(0,0,0)) colors.append(row) return cls(ImageSize,ImageSize,colors)
def __init__(self,center,r,color=Color(0.5,0.5,0.5),texture=None,specularFactor=1,reflectionFactor=0): self.center=center self.r=r self.color=color self.specularFactor=specularFactor self.reflectionFactor=reflectionFactor if not texture==None: self.texture= Image.fromFile(texture) else: self.texture = self.color
def getBlankImage(cls,sizeX,sizeY,r=0,g=0,b=0): c = Color(r,g,b) colors = [] for i in range (int(sizeX)): row = [] for j in range(int(sizeY)): row.append(c) colors.append(row) return cls(sizeX,sizeY,colors)
def fromFile(cls,filename): file = open(filename,"r") lines = file.readlines() sizeX=int(lines[2].split(" ")[0]) sizeY=int(lines[2].split(" ")[1]) max=int(lines[3]) linecounter=4 colors = [] for i in range(int(sizeY)): counter=0 filecolors = lines[linecounter].split(" ") row = [] for j in range(int(sizeX)): row.append(Color(float(filecolors[counter])/max,float(filecolors[counter+1])/max,float(filecolors[counter+2])/max)) # print("",linecounter," ", len(filecolors)," ",filecolors[counter]," ",filecolors[counter+1]," ",filecolors[counter+2]) counter+=3 linecounter+=1 colors.append(row) # print("DONE") image = cls(sizeX,sizeY,colors) # print(image) return image
def getRef1(cls, ray, p, obj, scene, factor, color): # print("Call : ",factor) if (factor < 0.25): return color if isinstance(obj, Triangle): normal = obj.normal elif isinstance(obj, Sphere): normal = p - obj.center normal = normal.normalize() d = p - ray.a reflectionRay = Ray(p, d - (normal * d.dot(normal) * 2)) tminRef, closestObjRef = Utility.getClosestIntersection( reflectionRay, scene, 0.001) diffuseRef = 0 specularRef = 0 rRef = 0 pRef = None if not closestObjRef == None: for light in scene.lights: pRef = reflectionRay.a + reflectionRay.b * tminRef lightDistance = Vector.distance(pRef, light.position) lrspecular, lrdiffuse = Utility.shading( pRef, closestObjRef, reflectionRay, scene, light) specularRef += lrspecular * (light.intensity**0.005) diffuseRef += light.intensity * lrdiffuse / (lightDistance**2) rRef = closestObjRef.getTexture(pRef) * diffuseRef + Color( 1, 1, 1) * ( specularRef ) * closestObjRef.specularFactor + closestObjRef.getTexture( pRef) * scene.ambient color = rRef * factor + color return cls.getRef1(reflectionRay, pRef, closestObjRef, scene, closestObjRef.reflectionFactor * 0.8, color) return color
def fromFile(cls,filename): file = open(filename,"r") lines = file.readlines() counter=0 ambient=float(lines[counter].replace(" ","").replace("\n","")) counter+=1 numerOfSpheres=int(lines[counter]) spheres=[] for i in range(numerOfSpheres): center = Vector() color = Color() radius = 0 counter+=1 center.x=float(lines[counter].split(" ")[0]) center.y=float(lines[counter].split(" ")[1]) center.z=float(lines[counter].split(" ")[2]) counter+=1 radius=float(lines[counter]) texture = None counter+=1 if str.isdigit(lines[counter].replace(" ","").replace("\n","")): color.r=float(lines[counter].split(" ")[0]) color.g=float(lines[counter].split(" ")[1]) color.b=float(lines[counter].split(" ")[2]) else: texture = lines[counter].replace("\n","").strip() counter+=1 specFactor=float(lines[counter].split(" ")[0]) refFactor=float(lines[counter].split(" ")[1]) spheres.append(Sphere(center,radius,color,texture,specFactor,refFactor)) counter+=1 triangles=[] numberOfTriangles=int(lines[counter]) for i in range(numberOfTriangles): a = Vector() b = Vector() c = Vector() color = Color() counter+=1 a.x=float(lines[counter].split(" ")[0]) a.y=float(lines[counter].split(" ")[1]) a.z=float(lines[counter].split(" ")[2]) counter+=1 b.x=float(lines[counter].split(" ")[0]) b.y=float(lines[counter].split(" ")[1]) b.z=float(lines[counter].split(" ")[2]) counter+=1 c.x=float(lines[counter].split(" ")[0]) c.y=float(lines[counter].split(" ")[1]) c.z=float(lines[counter].split(" ")[2]) counter+=1 color.r=float(lines[counter].split(" ")[0]) color.g=float(lines[counter].split(" ")[1]) color.b=float(lines[counter].split(" ")[2]) triangles.append(Triangle(a,b,c,color)) counter+=1 lights=[] numberOfLights=int(lines[counter]) counter+=1 for i in range(numberOfLights): position = Vector() position.x=float(lines[counter].split(" ")[0]) position.y=float(lines[counter].split(" ")[1]) position.z=float(lines[counter].split(" ")[2]) counter+=1 intensity=int(lines[counter]) light = Light(position,intensity) lights.append(light) counter+=1 return Scene(spheres,triangles,lights,ambient)
def render(op, camera, scene, image): start_time = time.time() progress = 0 if op == 1: for i in range(image.sizeX): for j in range(image.sizeY): progress += 1 sys.stdout.write("\r" + "{:.1f}%".format(100 * (progress) / (image.sizeX * image.sizeY))) sys.stdout.flush() ray = Ray.generate(camera, i, j) tmin = float('inf') closestObj = None for sphere in scene.spheres: t = ray.intersect(sphere) if t > 1: if (t < tmin): tmin = t closestObj = sphere for triangle in scene.triangles: t = ray.intersect(triangle) if t > 1: if (t < tmin): tmin = t closestObj = triangle if not closestObj == None: # if isinstance(closestObj,Sphere): p = ray.a + ray.b * tmin image.colors[i][j] = closestObj.getTexture(p) # else : # image.colors[i][j]= closestObj.color # image.colors[i][j]= closestObj.color #diffuse if op == 2: for i in range(image.sizeX): for j in range(image.sizeY): progress += 1 sys.stdout.write("\r" + "{:.1f}%".format(100 * (progress) / (image.sizeX * image.sizeY))) sys.stdout.flush() ray = Ray.generate(camera, i, j) tmin = float('inf') closestObj = None for sphere in scene.spheres: t = ray.intersect(sphere) if t > 1: if (t < tmin): tmin = t closestObj = sphere for triangle in scene.triangles: t = ray.intersect(triangle) if t > 1: if (t < tmin): tmin = t closestObj = triangle diffuse = 1 if not closestObj == None: for light in scene.lights: normal = None p = ray.a + ray.b * tmin toLight = light.position - p if isinstance(closestObj, Triangle): normal = closestObj.normal elif isinstance(closestObj, Sphere): normal = p - closestObj.center flag = 0 normal = normal.normalize() toLight = toLight.normalize() diffuse = normal.dot(toLight) image.colors[i][ j] = closestObj.color * diffuse + closestObj.color * scene.ambient #specular if op == 3: for i in range(image.sizeX): for j in range(image.sizeY): progress += 1 sys.stdout.write("\r" + "{:.1f}%".format(100 * (progress) / (image.sizeX * image.sizeY))) sys.stdout.flush() ray = Ray.generate(camera, i, j) tmin = float('inf') closestObj = None for sphere in scene.spheres: t = ray.intersect(sphere) if t > 1: if (t < tmin): tmin = t closestObj = sphere for triangle in scene.triangles: t = ray.intersect(triangle) if t > 1: if (t < tmin): tmin = t closestObj = triangle diffuse = 0 specular = 0 if not closestObj == None: for light in scene.lights: # print(light.position) ldiffuse = 0 lspecular = 0 normal = None p = ray.a + ray.b * tmin toLight = light.position - p view = ray.b * -1 view = view.normalize() toLight = toLight.normalize() half = view + toLight if isinstance(closestObj, Triangle): normal = closestObj.normal elif isinstance(closestObj, Sphere): normal = p - closestObj.center flag = 0 normal = normal.normalize() half = half.normalize() lspecular = normal.dot(half) ldiffuse = normal.dot(toLight) if lspecular < 0: lspecular = 0 else: lspecular = lspecular**150 specular += lspecular * (light.intensity**0.005) diffuse += ldiffuse image.colors[i][j] = closestObj.color * diffuse + Color( 1, 1, 1) * (specular) #+shadows if op == 4: for i in range(image.sizeX): for j in range(image.sizeY): ray = Ray.generate(camera, i, j) tmin, closestObj = Utility.getClosestIntersection( ray, scene, 1) progress += 1 sys.stdout.write("\r" + "{:.1f}%".format(100 * (progress) / (image.sizeX * image.sizeY))) sys.stdout.flush() diffuse = 0 specular = 0 if not closestObj == None: for light in scene.lights: p = ray.a + ray.b * tmin lightDistance = Vector.distance(p, light.position) lspecular, ldiffuse = Utility.shading( p, closestObj, ray, scene, light) specular += lspecular * (light.intensity**0.005) diffuse += light.intensity * ldiffuse / (lightDistance **2) r = closestObj.color * diffuse + Color(1, 1, 1) * ( specular) + closestObj.color * scene.ambient image.colors[i][j] = r #+reflection (1 iteration) if op == 5: for i in range(image.sizeX): for j in range(image.sizeY): ray = Ray.generate(camera, i, j) tmin, closestObj = Utility.getClosestIntersection( ray, scene, 1) progress += 1 sys.stdout.write("\r" + "{:.1f}%".format(100 * (progress) / (image.sizeX * image.sizeY))) sys.stdout.flush() diffuse = 0 specular = 0 if not closestObj == None: for light in scene.lights: p = ray.a + ray.b * tmin lightDistance = Vector.distance(p, light.position) lspecular, ldiffuse = Utility.shading( p, closestObj, ray, scene, light) specular += lspecular * (light.intensity**0.005) diffuse += light.intensity * ldiffuse / (lightDistance **2) # print(scene.ambient) r = closestObj.color * diffuse + Color(1, 1, 1) * ( specular) + closestObj.color * scene.ambient image.colors[i][j] = r #REFLECTION closestObj.texture = closestObj.color # to remove the texture rRef = Utility.getRef2(ray, p, closestObj, scene, closestObj.reflectionFactor, r) image.colors[i][j] = rRef * closestObj.reflectionFactor + r if op == 6: for i in range(image.sizeX): for j in range(image.sizeY): ray = Ray.generate(camera, i, j) tmin, closestObj = Utility.getClosestIntersection( ray, scene, 1) progress += 1 sys.stdout.write("\r" + "{:.1f}%".format(100 * (progress) / (image.sizeX * image.sizeY))) sys.stdout.flush() diffuse = 0 specular = 0 if not closestObj == None: for light in scene.lights: p = ray.a + ray.b * tmin lightDistance = Vector.distance(p, light.position) lspecular, ldiffuse = Utility.shading( p, closestObj, ray, scene, light) specular += lspecular diffuse += light.intensity * ldiffuse / (lightDistance **2) r = closestObj.getTexture(p) * diffuse + Color(1, 1, 1) * ( specular ) * closestObj.specularFactor + closestObj.getTexture( p) * scene.ambient rRef = Utility.getRef1(ray, p, closestObj, scene, closestObj.reflectionFactor, r) image.colors[i][j] = rRef * closestObj.reflectionFactor + r print("\nimage rendered in {:.2f} seconds".format(time.time() - start_time)) Scene.writeImage(camera.outFile, image) print("image file is ready [{}]".format(camera.outFile)) import subprocess opener = "open" if sys.platform == "darwin" else "xdg-open" subprocess.call([opener, camera.outFile])