Skip to content

Commit

Permalink
Merge pull request #22 from mmcardle/master
Browse files Browse the repository at this point in the history
Add multiprocessing renderer
  • Loading branch information
martinchristen authored Oct 7, 2020
2 parents 1594594 + f429c80 commit ff7a85b
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 0 deletions.
1 change: 1 addition & 0 deletions pyrt/renderer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@

from .renderer import Renderer
from .simplert import SimpleRT
from .mprt import MultiProcessRT
from .rgbimage import RGBImage, loadimage
90 changes: 90 additions & 0 deletions pyrt/renderer/mprt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
"""
A multi processing ray tracer
"""

from .rgbimage import *
from .renderer import Renderer
from ..scene import Scene
from ..math import *

from .simplert import SimpleRT

from multiprocessing import Pool
import time


class MultiProcessRT(SimpleRT):

def __init__(self, shadow=False, iterations=1):
Renderer.__init__(self, "MP Raytracer")
self.shadow = shadow
self.iterations = iterations
if self.shadow:
print("# Shadow Enabled")
if self.iterations>1:
print("# Iterations: " + str(self.iterations))


def trace_ray_multiprocess(engine, scene, x, y):
ray = scene.camera.primaryRay(x, y)
hitrecord = HitRecord()
engine.num_rays += 1

# Reset shadow rays for the process
engine.num_shadow_rays = 0

num_secondary_rays = 0

# Primary Ray:
hit, r, g, b = engine._shade(scene, ray, hitrecord)

if hit and hitrecord.material.reflectivity != 0.0:
refhit = hitrecord.copy()
refray = ray.copy()
for i in range(engine.iterations - 1):
r, g, b, refray, refhit = engine._reflect(r,g,b, scene, refray, refhit)
num_secondary_rays += 1
if refray is None:
break

return x, y, r, g, b, num_secondary_rays, engine.num_shadow_rays

def render(self, scene: Scene) -> RGBImage:
if not scene.camera:
print("Warning: Can't render: there is no (active) camera in the scene!")
return None

time_start = time.time()
self.num_shadow_rays = 0
self.num_secondary_rays = 0

w = scene.camera.width
h = scene.camera.height

self.num_rays = w * h

image = RGBImage(w,h)

args = []
for y in range(0, h):
for x in range(0, w):
args.append([scene, x, y])

with Pool() as p:
for result in p.starmap(self.trace_ray_multiprocess, args):
x, y, r, g, b, secondary_rays, shadow_rays = result
image.drawPixelFast8(x, y, r, g, b)
self.num_secondary_rays += secondary_rays
self.num_shadow_rays += shadow_rays

time_end = time.time()
print("# RENDER STATISTICS" + 31 * "#")
time_total = time_end - time_start
print("TIME FOR RENDERING: " + str(time_total) + "s")
print("NUMBER OF PRIMARY RAYS: " + str(self.num_rays))
print("NUMBER OF SECONDARY RAYS: " + str(self.num_secondary_rays))
print("NUMBER OF SHADOW RAYS: " + str(self.num_shadow_rays))
print("RAYS/s: " + str((self.num_rays + self.num_secondary_rays + self.num_shadow_rays) / time_total))
print(50 * "#")

return image

0 comments on commit ff7a85b

Please sign in to comment.