Skip to content

Commit

Permalink
Mipmaps implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
kystyn committed Feb 5, 2021
1 parent 27dcd08 commit e8d017e
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 9 deletions.
6 changes: 3 additions & 3 deletions examples/16_textured_scene.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Example 16: Textured raytracing
#
# This time we render a triangle and scene
# This time we render a triangle and sphere

from pyrt.light import PointLight
from pyrt.scene import *
Expand Down Expand Up @@ -38,11 +38,11 @@
Vertex(position=(0, 1, 5), texcoord=(1, 0)),
Vertex(position=(5, 1, 0), texcoord=(1, 1)),
material=
TextureMaterial(texturepath='tex16.png'))
TextureMaterial(texturepath=['tex16.png']))

s = Sphere(center=Vec3(0, -3, 0), radius=1,
material=
TextureMaterial(texturepath='tex16.png'))
TextureMaterial(texturepath=['tex16.png']))

# Add triangle and sphere to the scene:
scene.add(t)
Expand Down
Binary file added examples/17.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
67 changes: 67 additions & 0 deletions examples/17_mipmaps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Example 17: Textured raytracing
#
# This time we render a triangle and scene with mipmaps
# Used textures contain funny digits
# Digit corresponds to level of detalization

from pyrt.light import PointLight
from pyrt.scene import *
from pyrt.material.texturematerial import TextureMaterial
from pyrt.camera import PerspectiveCamera
from pyrt.renderer import SimpleRT

from pyrt.renderer import RGBImage
from pyrt.math import Vec3
from pyrt.geometry import Triangle, Vertex
import moviepy.editor as mpy


def make_frame(t):
w = 320
h = 240

# Create a camera with width, height and field of view:
camera = PerspectiveCamera(w, h, 60)

# Set View matrix of camera: define where to look at
camera.setView(Vec3(0, -t - 10, 0), Vec3(0, 0, 0), Vec3(0, 0, 1))

# Create view-projection matrix (right to left)
vp = camera.projection * camera.view

# Create a scene
scene = Scene()

# Add a light to the scene
scene.addLight(PointLight(Vec3(0, -2, 0)))

# Create a triangle
t1 = Triangle(Vertex(position=(-5, -4, 5), texcoord=(0, 0)),
Vertex(position=(5, -4, 5), texcoord=(1, 0)),
Vertex(position=(5, -4, -5), texcoord=(1, 1)),
material=
TextureMaterial(texturepath=['tex17-1.png', 'tex17-2.png']))

t2 = Triangle(Vertex(position=(-5, -4, 5), texcoord=(0, 0)),
Vertex(position=(5, -4, -5), texcoord=(1, 1)),
Vertex(position=(-5,-4, -5), texcoord=(0, 1)),
material=
TextureMaterial(texturepath=['tex17-1.png', 'tex17-2.png']))

# Add triangle and sphere to the scene:
scene.add(t1)
scene.add(t2)

# Now tell the scene which camera we use
scene.setCamera(camera)

# Create a raytracer using "SimpleRT"
engine = SimpleRT()

# Render the scene:
image = engine.render(scene)
return image.data


clip = mpy.VideoClip(make_frame, duration=7)
clip.write_gif("17.gif",fps=1)
Binary file added examples/tex17-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/tex17-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions pyrt/camera/camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,11 @@ def getMatrix(self) -> Mat4:
:return:
"""
pass

@abstractmethod
def getSize(self) -> tuple:
"""
Returns the resolution tuple (w, h)
:return:
"""
pass
3 changes: 3 additions & 0 deletions pyrt/camera/orthographiccamera.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@ def __init__(self, width=512, height=512):
def primaryRay(self, x: float, y: float) -> Ray:
r = Ray(Vec3(x, y, 0.), self.direction)
return r

def getSize(self) -> tuple:
return self.width, self.height
3 changes: 2 additions & 1 deletion pyrt/camera/perspectivecamera.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ def setProjection(self, fov: float, width: int, height: int, znear: float, zfar:
self.matrix = self.projection * self.view
self.matrixinv = inverse4(self.matrix)


def getMatrix(self) -> Mat4:
"""
Returns the view-projection matrix
Expand All @@ -98,3 +97,5 @@ def getMatrix(self) -> Mat4:
"""
return self.matrix

def getSize(self) -> tuple:
return self.width, self.height
19 changes: 14 additions & 5 deletions pyrt/material/texturematerial.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,22 @@
from .material import Material
from ..math import Vec3, Ray, HitRecord, dot3, reflect3, normalize3, clamp3
from ..camera import Camera
from math import log2, floor


class TextureMaterial(Material):

"""Texture Material Class"""

def __init__(self, color: Vec3 = Vec3(1.,1.,1.), shininess: float = 10.0, reflectivity: float = 0.0, refraction: float = 1.0,
texturepath: str = ''):
texturepath: list = None):
Material.__init__(self, color, shininess, reflectivity, refraction)
self.texture = None if len(texturepath) == 0 else Texture(texturepath)
self.texture = None \
if texturepath is None \
else {i: Texture(texturepath[i]) for i in range(len(texturepath))}

def setTexture(self, texture: Texture):
self.texture = texture
def addTexture(self, lod: int, texture: Texture):
self.texture.update({lod: texture})

def shade(self, camera: Camera, ray: Ray, hitrecord: HitRecord, lights: list) -> Vec3:
"""
Expand All @@ -29,7 +32,13 @@ def shade(self, camera: Camera, ray: Ray, hitrecord: HitRecord, lights: list) -
"""
colorsum = Vec3(0.,0.,0.)

texcolor = self.texture.color(hitrecord.texcoord)
if self.texture is None or len(self.texture) == 0:
texcolor = self.color
else:
size = camera.getSize();
resolution = size[0] * size[1];
lod = floor(log2((hitrecord.point - camera.position).length() / resolution) + 14)
texcolor = self.texture[max(0, min(lod, len(self.texture) - 1))].color(hitrecord.texcoord)

if len(lights) > 0:
for light in lights:
Expand Down
1 change: 1 addition & 0 deletions pyrt/renderer/simplert.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def __init__(self, shadow=False, iterations=1):
Renderer.__init__(self, "Simple Raytracer")
self.shadow = shadow
self.iterations = iterations

if self.shadow:
print("# Shadow Enabled")
if self.iterations>1:
Expand Down

0 comments on commit e8d017e

Please sign in to comment.