def triangle_bc(self, A, B, C, texcoords, color=None, normals=()): minX = int(min(A['x'], B['x'], C['x'])) minY = int(min(A['y'], B['y'], C['y'])) maxX = int(max(A['x'], B['x'], C['x'])) maxY = int(max(A['y'], B['y'], C['y'])) for x in range(minX, maxX + 1): for y in range(minY, maxY + 1): if x >= self.width or x < 0 or y >= self.height or y < 0: continue u, v, w = glmath.baryCoords(A, B, C, self.vector(x, y)) if u >= 0 and v >= 0 and w >= 0: z = A['z'] * u + B['z'] * v + C['z'] * w if z > self.zbuffer[y][x]: if self.active_shader: r, g, b = self.active_shader( self, # verts = verts, baryCoords=(u, v, w), texCoords=texcoords, normals=normals, color=color or self.draw_color) else: b, g, r = color or self.draw_color self.glVertex_coords(x, y, Color.color(r, g, b)) self.zbuffer[y][x] = z
def getColor(self, tx, ty): if tx >= 0 and tx <= 1 and ty >= 0 and ty <= 1: x = int(tx * self.width) y = int(ty * self.height) return self.pixels[y][x] else: return Color.color(0, 0, 0)
def glZBuffer(self, filename='output/zbuffer.bmp'): archivo = open(filename, 'wb') height, width = self.height, self.width # File header 14 bytes archivo.write(bytes('B'.encode('ascii'))) archivo.write(bytes('M'.encode('ascii'))) archivo.write(MemorySize.dword(14 + 40 + width * height * 3)) archivo.write(MemorySize.dword(0)) archivo.write(MemorySize.dword(14 + 40)) # Image Header 40 bytes archivo.write(MemorySize.dword(40)) archivo.write(MemorySize.dword(width)) archivo.write(MemorySize.dword(height)) archivo.write(MemorySize.word(1)) archivo.write(MemorySize.word(24)) archivo.write(MemorySize.dword(0)) archivo.write(MemorySize.dword(width * height * 3)) archivo.write(MemorySize.dword(0)) archivo.write(MemorySize.dword(0)) archivo.write(MemorySize.dword(0)) archivo.write(MemorySize.dword(0)) minZ = float('inf') maxZ = -float('inf') for x in range(height): for y in range(width): if self.zbuffer[x][y] != -float('inf'): if self.zbuffer[x][y] < minZ: minZ = self.zbuffer[x][y] if self.zbuffer[x][y] > maxZ: maxZ = self.zbuffer[x][y] for x in range(height): for y in range(width): depth = self.zbuffer[x][y] if depth == -float('inf'): depth = minZ depth = (depth - minZ) / (maxZ - minZ) archivo.write(Color.color(depth, depth, depth)) archivo.close()
def read(self): image = open(self.path, 'rb') image.seek(10) headerSize = struct.unpack('=l', image.read(4))[0] image.seek(14 + 4) self.width = struct.unpack('=l', image.read(4))[0] self.height = struct.unpack('=l', image.read(4))[0] image.seek(headerSize) self.pixels = [] for y in range(self.height): self.pixels.append([]) for x in range(self.width): b = ord(image.read(1)) / 255 g = ord(image.read(1)) / 255 r = ord(image.read(1)) / 255 self.pixels[y].append(Color.color(r, g, b)) image.close()
def dr(): white_snow = Material(diffuse=Color.color(1, 0.98, 0.98), spec=96) black = Material(diffuse=Color.color(0, 0, 0), spec=96) orange_carrot = Material(diffuse=Color.color(0.92, 0.54, 0.13), spec=96) white = Material(diffuse=Color.color(1, 1, 1), spec=96) gray = Material(diffuse=Color.color(0.22, 0.22, 0.22), spec=96) darkblue = Material(diffuse=Color.color(0.031, 0.255, 0.361), spec=64) rayTracer = Raytracer(500, 500) rayTracer.pointLight = PointLight(position=Raytracer.vector(0, 0, 0), intensity=1) rayTracer.ambientLight = AmbientLight(strength=0.1) # Cuarto # Techo rayTracer.scene.append( Plane(Raytracer.vector(0, 5, 0), Raytracer.vector(0, -1, 0), black)) # Suelo rayTracer.scene.append( Plane(Raytracer.vector(0, -5, 0), Raytracer.vector(0, 1, 0), gray)) # Pared atras rayTracer.scene.append( Plane(Raytracer.vector(0, 0, -15), Raytracer.vector(0, 0, 1), gray)) # Pared izquierda rayTracer.scene.append( Plane(Raytracer.vector(-5, 0, 0), Raytracer.vector(1, 0, 0), gray)) # Pared derecha rayTracer.scene.append( Plane(Raytracer.vector(5, 0, 0), Raytracer.vector(-1, 0, 0), gray)) # Cubos rayTracer.scene.append(AABB(Raytracer.vector(-1, -2, -7), 1.5, darkblue)) rayTracer.scene.append( AABB(Raytracer.vector(1, -2, -7), 1.5, orange_carrot)) rayTracer.rtRender() rayTracer.glFinish('output/dr3.bmp')
def proyecto(): wood = Material(texture=Texture('assets/wood.bmp')) white_snow = Material(diffuse=Color.color(1, 0.98, 0.98), spec=96) grass = Material(diffuse=Color.color(0.26, 0.42, 0.18), spec=96) water = Material(diffuse=Color.color(0.031, 0.255, 0.361), spec=50, ior=1.5, matType=REFLECTIVE) darkblue = Material(diffuse=Color.color(0.031, 0.255, 0.361), spec=64) playera = Material(diffuse=Color.color(0.2, 0.86, 0.85), spec=64) piel = Material(diffuse=Color.color(0.85, 0.71, 0.45), spec=64) cafe = Material(diffuse=Color.color(0.32, 0.24, 0.08), spec=64) window = Material(spec=40, ior=1.5, matType=TRANSPARENT) rayTracer = Raytracer(500, 500) rayTracer.pointLight = PointLight(position=Raytracer.vector(0, 0, 0), intensity=1) rayTracer.pointLight = PointLight(position=Raytracer.vector(0, 1, 0), intensity=1) rayTracer.ambientLight = AmbientLight(strength=0.1) rayTracer.dirLight = DirectionalLight(direction=rayTracer.vector( 1, -1, -2), intensity=0.5) rayTracer.envmap = Envmap('assets/unnamed.bmp') # Suelo rayTracer.scene.append( Plane(Raytracer.vector(0, -5, 0), Raytracer.vector(0, 1, 0), grass)) # Agua rayTracer.scene.append( AABB(Raytracer.vector(-5, -5, -10), Raytracer.vector(7, 0.2, 5), water)) # Suelo rayTracer.scene.append( AABB(Raytracer.vector(-1, -4, -19), Raytracer.vector(20, 1, 10), grass)) rayTracer.scene.append( AABB(Raytracer.vector(3, -3, -21), Raytracer.vector(17, 1, 10), grass)) rayTracer.scene.append( AABB(Raytracer.vector(6, -2, -23), Raytracer.vector(15, 1, 10), grass)) # Casa rayTracer.scene.append( AABB(Raytracer.vector(9, 0, -25), Raytracer.vector(10, 10, 10), wood)) # Ventana rayTracer.scene.append( AABB(Raytracer.vector(8, 2, -25), Raytracer.vector(5, 3, 11), window)) # Steve # ======================= # Piernas rayTracer.scene.append( AABB(Raytracer.vector(2, -4, -10), Raytracer.vector(0.5, 1.5, 0.5), darkblue)) rayTracer.scene.append( AABB(Raytracer.vector(2.6, -4, -10), Raytracer.vector(0.5, 1.5, 0.5), darkblue)) # Playera rayTracer.scene.append( AABB(Raytracer.vector(2.3, -2.5, -10), Raytracer.vector(1.1, 1.5, 0.5), playera)) rayTracer.scene.append( AABB(Raytracer.vector(1.5, -2, -10), Raytracer.vector(0.5, 0.5, 0.5), playera)) rayTracer.scene.append( AABB(Raytracer.vector(3.1, -2, -10), Raytracer.vector(0.5, 0.5, 0.5), playera)) # Brazos rayTracer.scene.append( AABB(Raytracer.vector(1.5, -2.75, -10), Raytracer.vector(0.5, 1, 0.5), piel)) rayTracer.scene.append( AABB(Raytracer.vector(3.1, -2.75, -10), Raytracer.vector(0.5, 1, 0.5), piel)) # Cabeza rayTracer.scene.append( AABB(Raytracer.vector(2.3, -1.3, -10), Raytracer.vector(1.1, 0.9, 1), piel)) # Pelo rayTracer.scene.append( AABB(Raytracer.vector(2.3, -0.75, -10), Raytracer.vector(1.1, 0.2, 1), cafe)) # Ojos rayTracer.scene.append( AABB(Raytracer.vector(2.1, -1.2, -9.5), Raytracer.vector(0.1, 0.1, 0.2), cafe)) rayTracer.scene.append( AABB(Raytracer.vector(2, -1.2, -9.5), Raytracer.vector(0.1, 0.1, 0.2), white_snow)) rayTracer.scene.append( AABB(Raytracer.vector(2.5, -1.2, -9.5), Raytracer.vector(0.1, 0.1, 0.2), cafe)) rayTracer.scene.append( AABB(Raytracer.vector(2.6, -1.2, -9.5), Raytracer.vector(0.1, 0.1, 0.2), white_snow)) # Boca rayTracer.scene.append( AABB(Raytracer.vector(2.1, -1.4, -9.5), Raytracer.vector(0.1, 0.1, 0.2), cafe)) rayTracer.scene.append( AABB(Raytracer.vector(2.1, -1.5, -9.5), Raytracer.vector(0.1, 0.1, 0.2), cafe)) rayTracer.scene.append( AABB(Raytracer.vector(2.5, -1.4, -9.5), Raytracer.vector(0.1, 0.1, 0.2), cafe)) rayTracer.scene.append( AABB(Raytracer.vector(2.5, -1.5, -9.5), Raytracer.vector(0.1, 0.1, 0.2), cafe)) rayTracer.scene.append( AABB(Raytracer.vector(2.2, -1.5, -9.5), Raytracer.vector(0.1, 0.1, 0.2), cafe)) rayTracer.scene.append( AABB(Raytracer.vector(2.3, -1.5, -9.5), Raytracer.vector(0.1, 0.1, 0.2), cafe)) rayTracer.scene.append( AABB(Raytracer.vector(2.4, -1.5, -9.5), Raytracer.vector(0.1, 0.1, 0.2), cafe)) rayTracer.rtRender() rayTracer.glFinish('output/dr3.bmp')
def glColor(self, r=0, g=0, b=0): self.draw_color = Color.color(r, g, b)
def glClear(self, r=0, g=0, b=0): self.pixels = [[Color.color(r, g, b) for y in range(self.height)] for x in range(self.width)] self.zbuffer = [[-float('inf') for x in range(self.width)] for y in range(self.height)]
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)