def getColorFromRay(self, scene, vec, viewPoint, recur=0): """ Given other objects in the scene, return the color at the specified point. @param scene: Scene object this World Object belongs to. @param vec: (x,y,z) Vector point to return the current color of. NOTE: We're assuming the passed in vec is on the surface of this object, that value is caclulated at using self.intersection(), but we avoid calculating it again. @param viewPoint: Current viewpoint we're looking at this object from. @param recur: Recursion Level (we'll stop at 3) """ # Calculate Color from Ambient Light surfaceColor = self.surfaceColor(vec) colorPoint = self._getColorAmbient(scene, vec, surfaceColor) # Calculate Color from Light Sources for light in scene.lights: colorFromLight = self._getColorFromLight(scene, vec, light, viewPoint, surfaceColor) colorPoint = color.add(colorPoint, colorFromLight) # Calculate Color from Reflection if (self.kr) and (recur <= 3): colorReflect = self._getColorFromReflect(scene, vec, viewPoint, recur) colorPoint = color.add(colorPoint, colorReflect) # Calculate Color from Refraction if (self.kt) and (recur <= 3): colorRefract = self._getColorFromRefract(scene, vec, viewPoint, recur) colorPoint = color.add(colorPoint, colorRefract) return colorPoint
def calculateShading(self, intersection, depth): point = intersection[1] shape = intersection[2] normal = shape.getNormalAtPoint(point) incident_vector = (point - self.camera.position).normalized() shapeColor = shape.getColorAtPoint(point) log.debug("Shading {0} {1}".format(shape, point)) # ambient portion result = color.component_scale(shapeColor, [x/255 for x in self.ambient_light]) specular_lights = [] for light in self.lights: # shadow lightDir = (light.position - point).normalized() lightDist = (light.position - point).magnitude() shadowed = False for shape in self.shapes: try: dist, point = shape.intersection(lightDir, point + (normal * 0.001)) if dist <= lightDist: shadowed = True log.debug("Shadowed by {0} at distance {1}".format(shape, dist)) break except TypeError: pass if not shadowed: # diffuse diffIntensity = min(max(lightDir * normal, 0), 1) diff = color.scale(light.color, diffIntensity) diff = color.component_scale(shapeColor, [x/255 for x in diff]) log.debug("Diff: {0} (intensity {1})".format(diff, diffIntensity)) result = color.add(result, diff) if diffIntensity > 0: specular_lights.append(light) # reflection if shape.material.reflection > 0: reflective_vector = incident_vector - (2 * (incident_vector * normal) * normal) reflective_component = self.fireRay(reflective_vector, point + (normal * 0.001), depth + 1) result = color.scale(result, 1 - shape.material.reflection) result = color.add(result, color.scale(reflective_component, shape.material.reflection)) for light in specular_lights: # blinn-phong viewDir = -incident_vector halfDir = (lightDir + viewDir).normalized() specAngle = min(max(halfDir * normal, 0), 1) specIntensity = specAngle ** shape.material.hardness spec = color.scale(light.color, specIntensity) spec = color.scale(spec, shape.material.specular) result = color.add(result, spec) return result
def _getColorFromLight(self, scene, vec, light, viewPoint, surfaceColor): """ Return the color of this point on the World Object prodecuded by the the specified light source. @param scene: Scene object this World Object belongs to. @param vec: (x,y,z) Vector point to return the current color of. @param light: Light object to use when calculating color. @param viewPoint: Current viewpoint we're looking at this object from. """ # Calculate some variables to work with normObject = self.normal(vec) normLight = (light.center - vec).normalize() isShadow = scene.isShadow(vec, light, self) # Calculate the color from Lamberts Diffuse Algorithm kd = [self.kd, self.kd * 0.3][isShadow] factorLambert = max(normObject * normLight, 0) colorLambert = color.mul(surfaceColor, factorLambert) colorLambert = color.mul(colorLambert, kd) # Calculate the color from Phongs Highlight Algorithm colorPhong = (0, 0, 0) if (not isShadow): normReflect = normLight.reflect(normObject) normToView = (viewPoint - vec).normalize() factorPhong = pow(max(normReflect * normToView, 0), self.se) colorPhong = color.mul(light.color, factorPhong) colorPhong = color.mul(colorPhong, self.ks) return color.add(colorLambert, colorPhong)
def get_at(self, pos): """ Return the color at the specified point. @param pos: (x,y) Position in the window to return the color of. """ obj, vec = self.getVisibleObject(pos) if (obj): # Update coordinfo (for footer); And return object's color objName = obj.__class__.__name__ simpVec = tuple(map(int, vec.val())) self.coordinfo[pos] = "%s: %s" % (objName, simpVec) return obj.get_at(self, vec) else: # TODO: This should be removed, its a fake BG for prog1 vec = Vector(pos[0], pos[1], 0) bgColor = (255, 255, 255) bgkd = 0.7 colorPoint = color.mul(bgColor, self.ka) for light in self.lights: normLight = (light.center - vec).normalize() isShadow = self.isShadow(vec, light) # Calculate the color from Lamberts Diffuse Algorithm kd = [bgkd, bgkd * 0.3][isShadow] factorLambert = max(Vector(0, 0, 1) * normLight, 0) colorLambert = color.mul(bgColor, factorLambert) colorLambert = color.mul(colorLambert, kd) colorPoint = color.add(colorPoint, colorLambert) return colorPoint return None
def __call__(self, time, delta): frames=[] for source in self.sources: frames.append(source(time,delta)) firstFrame=frames[0] #cubes c=[] for i in range(len(firstFrame[0])): c.append([]) for j in range(len(firstFrame[0][i])): c[i].append([]) for k in range(len(firstFrame[0][i][j])): c[i][j].append([]) currentSum=firstFrame[0][i][j][k] for iFrame in range(1,len(frames)): currentSum=color.add(currentSum,frames[iFrame][0][i][j][k]) c[i][j][k]=currentSum #leaves l=[] for i in range(len(firstFrame[1])): l.append([]) for j in range(len(firstFrame[1][i])): l[i].append([]) currentSum=firstFrame[1][i][j] for iFrame in range(1,len(frames)): currentSum=color.add(currentSum,frames[iFrame][1][i][j]) l[i][j]=currentSum #fissures f=[] for i in range(len(firstFrame[2])): f.append([]) currentSum=firstFrame[2][i] for iFrame in range(1,len(frames)): currentSum=color.add(currentSum,frames[iFrame][2][i]) f[i]=currentSum return [c,l,f]
def AddFrames(frames): firstFrame=frames[0] #cubes c=[] for i in range(len(firstFrame[0])): c.append([]) for j in range(len(firstFrame[0][i])): c[i].append([]) for k in range(len(firstFrame[0][i][j])): c[i][j].append([]) currentSum=firstFrame[0][i][j][k] for iFrame in range(1,len(frames)): currentSum=color.add(currentSum,frames[iFrame][0][i][j][k]) c[i][j][k]=currentSum #leaves l=[] for i in range(len(firstFrame[1])): l.append([]) for j in range(len(firstFrame[1][i])): l[i].append([]) currentSum=firstFrame[1][i][j] for iFrame in range(1,len(frames)): currentSum=color.add(currentSum,frames[iFrame][1][i][j]) l[i][j]=currentSum #fissures f=[] for i in range(len(firstFrame[2])): f.append([]) currentSum=firstFrame[2][i] for iFrame in range(1,len(frames)): currentSum=color.add(currentSum,frames[iFrame][2][i]) f[i]=currentSum return [c,l,f]
def get_at(self, scene, vec): """ Given other objects in the scene, return the color at the specified point. @param scene: Scene object this Sphere belongs to. @param vec: (x,y,z) Vector point to return the current color of. NOTE: We're assuming the passed in vec is on the surface of this object, that value is caclulated at using self.intersection(), but we want to avoid calculating it again. """ colorPoint = self._getColorAmbient(scene) for light in scene.lights: colorFromLight = self._getColorFromLight(scene, vec, light) colorPoint = color.add(colorPoint, colorFromLight) return colorPoint