def gourad(render, **kwargs): u, v, w = kwargs['baryCoords'] ta, tb, tc = kwargs['texCoords'] na, nb, nc = kwargs['normals'] b, g, r = kwargs['color'] b /= 255 g /= 255 r /= 255 if render.active_texture: tx = ta['x'] * u + tb['x'] * v + tc['x'] * w ty = ta['y'] * u + tb['y'] * v + tc['y'] * w texColor = render.active_texture.getColor(tx, ty) b *= texColor[0] / 255 g *= texColor[1] / 255 r *= texColor[2] / 255 nx = na['x'] * u + nb['x'] * v + nc['x'] * w ny = na['y'] * u + nb['y'] * v + nc['y'] * w nz = na['z'] * u + nb['z'] * v + nc['z'] * w normal = render.vector(nx, ny, nz) intensity = glmath.dot(normal, render.light) b *= intensity g *= intensity r *= intensity if intensity > 0: return r, g, b return 0,0,0
def ray_intersect(self, orig, dirr): L = sub(self.center, orig) tca = dot(L, dirr) l = frobeniusNorm(L) d = (l ** 2 - tca ** 2) ** 0.5 if d > self.radius: return None thc = (self.radius ** 2 - d ** 2) ** 0.5 t0 = tca - thc t1 = tca + thc if t0 < 0: t0 = t1 if t0 < 0: return None hit = suma(orig, mulEscalarVector(t0, dirr)) norm = sub(hit, self.center) norm = div(norm, frobeniusNorm(norm)) u = 1 - arctan2(norm[2], norm[0]) / (2 * pi) + 0.5 v = arccos(-norm[1]) / pi uvs = [u, v] return Intersect( distance = t0, point = hit, normal = norm, textCoords = uvs, sceneObject = self )
def ray_intersect(self, orig, dirr): denom = dot(dirr, self.normal) if abs(denom) > 0.0001: t = dot(self.normal, sub(self.position, orig)) / denom if t > 0: hit = suma(orig, mulEscalarVector(t, dirr)) return Intersect(distance=t, point=hit, normal=self.normal, textCoords=None, sceneObject=self) return None
def heat(render, **kwargs): u, v, w = kwargs['baryCoords'] ta, tb, tc = kwargs['texCoords'] na, nb, nc = kwargs['normals'] b, g, r = kwargs['color'] b /= 255 g /= 255 r /= 255 if render.active_texture: tx = ta['x'] * u + tb['x'] * v + tc['x'] * w ty = ta['y'] * u + tb['y'] * v + tc['y'] * w texColor = render.active_texture.getColor(tx, ty) b *= texColor[0] / 255 g *= texColor[1] / 255 r *= texColor[2] / 255 nx = na['x'] * u + nb['x'] * v + nc['x'] * w ny = na['y'] * u + nb['y'] * v + nc['y'] * w nz = na['z'] * u + nb['z'] * v + nc['z'] * w normal = render.vector(nx, ny, nz) intensity = glmath.dot(normal, render.light) b *= intensity g *= intensity r *= intensity if (intensity >= 0 and intensity <= 0.2): # Azul return r*0.25, g*0.25, b elif (intensity > 0.2 and intensity <= 0.4): # Verde return r*0.25, g, b*0.25 elif (intensity > 0.4 and intensity <= 0.6): # Amarillo return r, g, b*0.25 elif (intensity > 0.6 and intensity <= 0.8): # Naranja return r, g*0.5, b*0.25 elif (intensity > 0.8): # Rojo return r, g*0.25, b*0.25 if intensity > 0: return r, g, b return 0,0,0
def fresnel(N, I, ior): cosi = max(-1, min(1, glmath.dot(I, N))) etai = 1 etat = ior if cosi > 0: etai, etat = etat, etai sint = etai / etat * (max(0, 1 - cosi * cosi)**0.5) if sint >= 1: return 1 cost = max(0, 1 - sint * sint)**0.5 cosi = abs(cosi) Rs = ((etat * cosi) - (etai * cost)) / ((etat * cosi) + (etai * cost)) Rp = ((etai * cosi) - (etat * cost)) / ((etai * cosi) + (etat * cost)) return (Rs * Rs + Rp * Rp) / 2
def refractVector(N, I, ior): cosi = max(-1, min(1, glmath.dot(I, N))) etai = 1 etat = ior if cosi < 0: cosi = -cosi else: etai, etat = etat, etai N = glmath.mulEscalarVector(-1, N) eta = etai / etat k = 1 - eta * eta * (1 - (cosi * cosi)) if k < 0: return None R = glmath.suma(glmath.mulEscalarVector(eta, I), glmath.mulEscalarVector((eta * cosi - k**0.5), N)) return glmath.div(R, glmath.frobeniusNorm(R))
def grayscale(render, **kwargs): u, v, w = kwargs['baryCoords'] ta, tb, tc = kwargs['texCoords'] na, nb, nc = kwargs['normals'] b, g, r = kwargs['color'] b /= 255 g /= 255 r /= 255 if render.active_texture: tx = ta['x'] * u + tb['x'] * v + tc['x'] * w ty = ta['y'] * u + tb['y'] * v + tc['y'] * w texColor = render.active_texture.getColor(tx, ty) b *= texColor[0] / 255 g *= texColor[1] / 255 r *= texColor[2] / 255 nx = na['x'] * u + nb['x'] * v + nc['x'] * w ny = na['y'] * u + nb['y'] * v + nc['y'] * w nz = na['z'] * u + nb['z'] * v + nc['z'] * w normal = render.vector(nx, ny, nz) intensity = glmath.dot(normal, render.light) if (intensity >= 0 and intensity <= 1): pass else: intensity = 0 b *= intensity g *= intensity r *= intensity c = min([b, g, r]) if intensity > 0: return c, c, c return 0,0,0
def randomPattern(render, **kwargs): u, v, w = kwargs['baryCoords'] ta, tb, tc = kwargs['texCoords'] na, nb, nc = kwargs['normals'] b, g, r = kwargs['color'] b /= 255 g /= 255 r /= 255 if render.active_texture: tx = ta['x'] * u + tb['x'] * v + tc['x'] * w ty = ta['y'] * u + tb['y'] * v + tc['y'] * w texColor = render.active_texture.getColor(tx, ty) b *= texColor[0] / 255 g *= texColor[1] / 255 r *= texColor[2] / 255 nx = na['x'] * u + nb['x'] * v + nc['x'] * w ny = na['y'] * u + nb['y'] * v + nc['y'] * w nz = na['z'] * u + nb['z'] * v + nc['z'] * w normal = render.vector(nx, ny, nz) intensity = glmath.dot(normal, render.light) randomNumber = random.randint(0, 100) if (intensity >= 0 and intensity <= 1): intensity = intensity * randomNumber/100 else: intensity = 0 b *= intensity g *= intensity r *= intensity if intensity > 0: return r, g, b return 0,0,0
def castRay(self, orig, direction, origObj=None, recursion=0): material, intersect = self.scene_intercept(orig, direction, origObj) if material is None or recursion >= MAX_RECURSION_DEPTH: if self.envmap: return self.envmap.getColor(direction) return self.window_color objectColor = self.vector(material.diffuse[2] / 255, material.diffuse[1] / 255, material.diffuse[0] / 255) ambientColor = self.vector(0, 0, 0) dirLightColor = self.vector(0, 0, 0) pLightColor = self.vector(0, 0, 0) reflectColor = self.vector(0, 0, 0) refractColor = self.vector(0, 0, 0) finalColor = self.vector(0, 0, 0) view_dir = glmath.sub(self.camPosition, intersect.point) view_dir = glmath.div(view_dir, glmath.frobeniusNorm(view_dir)) if self.ambientLight: ambientColor = self.vector( self.ambientLight.strength * self.ambientLight.color[2] / 255, self.ambientLight.strength * self.ambientLight.color[1] / 255, self.ambientLight.strength * self.ambientLight.color[0] / 255) if self.dirLight: diffuseColor = [0, 0, 0] specColor = [0, 0, 0] shadow_intensity = 0 light_dir = glmath.mulEscalarVector(-1, self.dirLight.direction) intensity = self.dirLight.intensity * max( 0, glmath.dot(light_dir, intersect.normal)) diffuseColor = self.vector( intensity * self.dirLight.color[2] / 255, intensity * self.dirLight.color[1] / 255, intensity * self.dirLight.color[0] / 255) reflect = reflectVector(intersect.normal, light_dir) spec_intensity = self.dirLight.intensity * (max( 0, glmath.dot(view_dir, reflect))**material.spec) specColor = self.vector( spec_intensity * self.dirLight.color[2] / 255, spec_intensity * self.dirLight.color[1] / 255, spec_intensity * self.dirLight.color[0] / 255) shadMat, shadInter = self.scene_intercept(intersect.point, light_dir, intersect.sceneObject) if shadInter: shadow_intensity = 1 dirLightColor = glmath.mulEscalarVector( (1 - shadow_intensity), glmath.suma(diffuseColor, specColor)) for pointLight in self.pointLights: diffuseColor = [0, 0, 0] specColor = [0, 0, 0] shadow_intensity = 0 light_dir = glmath.sub(pointLight.position, intersect.point) light_dir = glmath.div(light_dir, glmath.frobeniusNorm(light_dir)) intensity = pointLight.intensity * max( 0, glmath.dot(light_dir, intersect.normal)) diffuseColor = self.vector(intensity * pointLight.color[2] / 255, intensity * pointLight.color[1] / 255, intensity * pointLight.color[0] / 255) reflect = reflectVector(intersect.normal, light_dir) spec_intensity = pointLight.intensity * (max( 0, glmath.dot(view_dir, reflect))**material.spec) specColor = self.vector(spec_intensity * pointLight.color[2] / 255, spec_intensity * pointLight.color[1] / 255, spec_intensity * pointLight.color[0] / 255) shadMat, shadInter = self.scene_intercept(intersect.point, light_dir, intersect.sceneObject) if shadInter and shadInter.distance < glmath.frobeniusNorm( glmath.sub(pointLight.position, intersect.point)): shadow_intensity = 1 pLightColor = glmath.suma( pLightColor, glmath.mulEscalarVector((1 - shadow_intensity), glmath.suma(diffuseColor, specColor))) if material.matType == OPAQUE: finalColor1 = glmath.suma(ambientColor, dirLightColor) finalColor = glmath.suma(pLightColor, finalColor1) if material.texture and intersect.textCoords: texColor = material.texture.getColor(intersect.textCoords[0], intersect.textCoords[1]) finalColor = self.vector((texColor[2] / 255) * finalColor['x'], (texColor[1] / 255) * finalColor['y'], (texColor[0] / 255) * finalColor['z']) elif material.matType == REFLECTIVE: reflect = reflectVector(intersect.normal, glmath.mulEscalarVector(-1, direction)) reflectColor = self.castRay(intersect.point, reflect, intersect.sceneObject, recursion + 1) reflectColor = self.vector(reflectColor[2] / 255, reflectColor[1] / 255, reflectColor[0] / 255) finalColor = reflectColor elif material.matType == TRANSPARENT: outside = glmath.dot(direction, intersect.normal) < 0 bias = glmath.mulEscalarVector(0.001, intersect.normal) kr = fresnel(intersect.normal, direction, material.ior) reflect = reflectVector(intersect.normal, glmath.mulEscalarVector(-1, direction)) reflectOrig = glmath.suma(intersect.point, bias) if outside else glmath.sub( intersect.point, bias) reflectColor = self.castRay(reflectOrig, reflect, None, recursion + 1) reflectColor = self.vector(reflectColor[2] / 255, reflectColor[1] / 255, reflectColor[0] / 255) if kr < 1: refract = refractVector(intersect.normal, direction, material.ior) refractOrig = glmath.sub(intersect.point, bias) if outside else glmath.suma( intersect.point, bias) refractColor = self.castRay(refractOrig, refract, None, recursion + 1) refractColor = self.vector(refractColor[2] / 255, refractColor[1] / 255, refractColor[0] / 255) finalColor = glmath.suma( glmath.mulEscalarVector(kr, reflectColor), glmath.mulEscalarVector((1 - kr), refractColor)) finalColor = glmath.mulVectores(finalColor, objectColor) r = min(1, finalColor['x']) g = min(1, finalColor['y']) b = min(1, finalColor['z']) return Color.color(r, g, b)
def reflectVector(normal, dirVector): reflect = 2 * glmath.dot(normal, dirVector) reflect = glmath.mulEscalarVector(reflect, normal) reflect = glmath.sub(reflect, dirVector) reflect = glmath.div(reflect, glmath.frobeniusNorm(reflect)) return reflect