Statistics (#6)

* ray tracing statistics

* ray counter

* photonmapping ray counter

* rays change

* newline fix

---------

Co-authored-by: Jakub <01149663@pw.edu.pl>
This commit is contained in:
JZduns 2025-01-19 17:52:23 +01:00 committed by GitHub
parent d9b8013d2e
commit ee46879048
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 51 additions and 6 deletions

View File

@ -1,5 +1,8 @@
import numpy as np import numpy as np
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import time
PHOTONS = 0
# Define basic vector operations # Define basic vector operations
class Vector3: class Vector3:
@ -103,6 +106,8 @@ def emit_photons():
trace_photon(photon, 0) trace_photon(photon, 0)
def trace_photon(photon, depth): def trace_photon(photon, depth):
global PHOTONS
PHOTONS += 1
if depth > max_depth: if depth > max_depth:
return return
closest_t = np.inf closest_t = np.inf
@ -211,10 +216,19 @@ if __name__ == '__main__':
emit_photons() emit_photons()
print("Rendering image...") print("Rendering image...")
width = 200 width = 100
height = 100 height = 100
t0 = time.time()
image = render_image(width, height) image = render_image(width, height)
print (f"Render Took: {round(time.time() - t0, 2)}s\n"
f"resolution: {width}x{height}\n"
f"photons (emitted): {num_photons}\n"
f"photons (reflected): {PHOTONS - num_photons}\n"
f"photons (total): {PHOTONS}\n"
f"rays: {width*height}"
)
# Display the image # Display the image
plt.imshow(image) plt.imshow(image)
plt.axis('off') plt.axis('off')

View File

@ -2,6 +2,7 @@
""" Renders an image using raytracing """ """ Renders an image using raytracing """
import numpy as np import numpy as np
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import time
def ray_trace(num_spheres, environment, image_width=400, image_height=300, output_file="fig.png"): def ray_trace(num_spheres, environment, image_width=400, image_height=300, output_file="fig.png"):
IMAGE_WIDTH = image_width IMAGE_WIDTH = image_width
@ -381,10 +382,14 @@ def ray_trace(num_spheres, environment, image_width=400, image_height=300, outpu
# Screen coordinates: x0, y0, x1, y1. # Screen coordinates: x0, y0, x1, y1.
S = (-1., -1. / r + .25, 1., 1. / r + .25) S = (-1., -1. / r + .25, 1., 1. / r + .25)
renderTime = time.time()
reflections = 0
rays = 0
initialRays = 0
# Loop through all pixels. # Loop through all pixels.
for i, x in enumerate(np.linspace(S[0], S[2], IMAGE_WIDTH)): for i, x in enumerate(np.linspace(S[0], S[2], IMAGE_WIDTH)):
if i % 10 == 0: if i % 10 == 0:
print(i / float(IMAGE_WIDTH) * 100, "%") print(round(i / float(IMAGE_WIDTH) * 100, 2), "%")
for j, y in enumerate(np.linspace(S[1], S[3], IMAGE_HEIGHT)): for j, y in enumerate(np.linspace(S[1], S[3], IMAGE_HEIGHT)):
col[:] = 0 col[:] = 0
Q[:2] = (x, y) Q[:2] = (x, y)
@ -392,11 +397,14 @@ def ray_trace(num_spheres, environment, image_width=400, image_height=300, outpu
DEPTH = 0 DEPTH = 0
rayO, rayD = camera_origin, D rayO, rayD = camera_origin, D
REFLECTION = 1. REFLECTION = 1.
initialRays += 1
# Loop through initial and secondary rays. # Loop through initial and secondary rays.
while DEPTH < DEPTH_MAX: while DEPTH < DEPTH_MAX:
traced = trace_ray(rayO, rayD) traced = trace_ray(rayO, rayD)
rays += 1
if not traced: if not traced:
break break
reflections += 1
obj, M, N, col_ray = traced obj, M, N, col_ray = traced
# Reflection: create a new ray. # Reflection: create a new ray.
rayO, rayD = M + \ rayO, rayD = M + \
@ -405,6 +413,13 @@ def ray_trace(num_spheres, environment, image_width=400, image_height=300, outpu
col += REFLECTION * col_ray col += REFLECTION * col_ray
REFLECTION *= obj.get('reflection', 1.) REFLECTION *= obj.get('reflection', 1.)
img[IMAGE_HEIGHT - j - 1, i, :] = np.clip(col, 0, 1) img[IMAGE_HEIGHT - j - 1, i, :] = np.clip(col, 0, 1)
renderTime = time.time() - renderTime
plt.imsave(output_file, img) plt.imsave(output_file, img)
print(f"Image saved as {output_file}") print(f"Image saved as {output_file}\n"
f"resolution: {IMAGE_WIDTH}x{IMAGE_HEIGHT}\n"
f"render time: {round(renderTime, 2)} s\n"
f"reflections: {reflections}\n"
f"rays (initial): {initialRays}\n"
f"rays (secondary): {rays - initialRays}\n"
f"rays (total): {rays}")

View File

@ -3,6 +3,9 @@ from .utils.vector3 import vec3, extract, rgb
import numpy as np import numpy as np
from functools import reduce as reduce from functools import reduce as reduce
RAYS = 0
PRIMARY_RAYS = 0
class Ray: class Ray:
"""Info of the ray and the media it's travelling""" """Info of the ray and the media it's travelling"""
@ -25,6 +28,12 @@ class Ray:
self.reflections = reflections #reflections is the number of the refrections, starting at zero for camera rays self.reflections = reflections #reflections is the number of the refrections, starting at zero for camera rays
self.transmissions = transmissions #transmissions is the number of the transmissions/refractions, starting at zero for camera rays self.transmissions = transmissions #transmissions is the number of the transmissions/refractions, starting at zero for camera rays
self.diffuse_reflections = diffuse_reflections #reflections is the number of the refrections, starting at zero for camera rays self.diffuse_reflections = diffuse_reflections #reflections is the number of the refrections, starting at zero for camera rays
global RAYS
RAYS += 1
if self.reflections == 0 and self.transmissions == 0 and self.diffuse_reflections == 0:
global PRIMARY_RAYS
PRIMARY_RAYS += 1
def extract(self,hit_check): def extract(self,hit_check):
@ -97,7 +106,8 @@ def get_distances(ray, scene): #Used for debugging ray-surface collisions. Retur
norm_r_distance = r_distance/max_r_distance norm_r_distance = r_distance/max_r_distance
return rgb(norm_r_distance, norm_r_distance, norm_r_distance) return rgb(norm_r_distance, norm_r_distance, norm_r_distance)
def get_rays():
return RAYS, PRIMARY_RAYS

View File

@ -4,7 +4,7 @@ import time
from .utils import colour_functions as cf from .utils import colour_functions as cf
from .camera import Camera from .camera import Camera
from .utils.vector3 import vec3, rgb from .utils.vector3 import vec3, rgb
from .ray import get_raycolor, get_distances from .ray import get_raycolor, get_distances, get_rays
from . import lights from . import lights
from .backgrounds.skybox import SkyBox from .backgrounds.skybox import SkyBox
from .backgrounds.panorama import Panorama from .backgrounds.panorama import Panorama
@ -88,7 +88,13 @@ class Scene():
#gamma correction #gamma correction
color = cf.sRGB_linear_to_sRGB(color_RGBlinear.to_array()) color = cf.sRGB_linear_to_sRGB(color_RGBlinear.to_array())
print ("Render Took", time.time() - t0) RAYS, PRIMARY_RAYS = get_rays()
print (f"Render Took: {round(time.time() - t0, 2)}s\n"
f"resolution: {self.camera.screen_width}x{self.camera.screen_height}\n"
f"rays (total): {RAYS}\n"
f"rays (primary): {PRIMARY_RAYS}\n"
f"rays (secondary): {RAYS-PRIMARY_RAYS}")
img_RGB = [] img_RGB = []
for c in color: for c in color: