mirror of
https://github.com/kuhyx/WUT_Computer_Science.git
synced 2026-07-04 19:23:03 +02:00
git-subtree-dir: Programming/TRAK git-subtree-mainline:e11d703c3egit-subtree-split:777937fb9e
119 lines
4.1 KiB
Python
119 lines
4.1 KiB
Python
from PIL import Image
|
|
import numpy as np
|
|
import time
|
|
from .utils import colour_functions as cf
|
|
from .camera import Camera
|
|
from .utils.vector3 import vec3, rgb
|
|
from .ray import get_raycolor, get_distances, get_rays
|
|
from . import lights
|
|
from .backgrounds.skybox import SkyBox
|
|
from .backgrounds.panorama import Panorama
|
|
|
|
|
|
class Scene():
|
|
def __init__(self, ambient_color = rgb(0.01, 0.01, 0.01), n = vec3(1.0,1.0,1.0)) :
|
|
# n = index of refraction (by default index of refraction of air n = 1.)
|
|
|
|
self.scene_primitives = []
|
|
self.collider_list = []
|
|
self.shadowed_collider_list = []
|
|
self.Light_list = []
|
|
self.importance_sampled_list = []
|
|
self.ambient_color = ambient_color
|
|
self.n = n
|
|
self.importance_sampled_list = []
|
|
def add_Camera(self, look_from, look_at, **kwargs):
|
|
self.camera = Camera(look_from, look_at, **kwargs)
|
|
|
|
|
|
def add_PointLight(self, pos, color):
|
|
self.Light_list += [lights.PointLight(pos, color)]
|
|
|
|
def add_DirectionalLight(self, Ldir, color):
|
|
self.Light_list += [lights.DirectionalLight(Ldir.normalize(), color)]
|
|
|
|
def add(self,primitive, importance_sampled = False):
|
|
self.scene_primitives += [primitive]
|
|
self.collider_list += primitive.collider_list
|
|
|
|
if importance_sampled == True:
|
|
self.importance_sampled_list += [primitive]
|
|
|
|
if primitive.shadow == True:
|
|
self.shadowed_collider_list += primitive.collider_list
|
|
|
|
|
|
def add_Background(self, img, light_intensity = 0.0, blur =0.0 , spherical = False):
|
|
|
|
primitive = None
|
|
if spherical == False:
|
|
primitive = SkyBox(img, light_intensity = light_intensity, blur = blur)
|
|
else:
|
|
primitive = Panorama(img, light_intensity = light_intensity, blur = blur)
|
|
|
|
self.scene_primitives += [primitive]
|
|
self.collider_list += primitive.collider_list
|
|
|
|
|
|
def render(self, samples_per_pixel, progress_bar = False):
|
|
|
|
print ("Rendering...")
|
|
|
|
t0 = time.time()
|
|
color_RGBlinear = rgb(0.,0.,0.)
|
|
|
|
if progress_bar == True:
|
|
|
|
|
|
try:
|
|
import progressbar
|
|
|
|
except ModuleNotFoundError:
|
|
print("progressbar module is required. \nRun: pip install progressbar")
|
|
|
|
bar = progressbar.ProgressBar()
|
|
for i in bar(range(samples_per_pixel)):
|
|
color_RGBlinear += get_raycolor(self.camera.get_ray(self.n), scene = self)
|
|
bar.update(i)
|
|
else:
|
|
|
|
|
|
for i in range(samples_per_pixel):
|
|
color_RGBlinear += get_raycolor(self.camera.get_ray(self.n), scene = self)
|
|
|
|
|
|
|
|
#average samples per pixel (antialiasing)
|
|
color_RGBlinear = color_RGBlinear/samples_per_pixel
|
|
#gamma correction
|
|
color = cf.sRGB_linear_to_sRGB(color_RGBlinear.to_array())
|
|
|
|
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 = []
|
|
for c in color:
|
|
# average ray colors that fall in the same pixel. (antialiasing)
|
|
img_RGB += [Image.fromarray((255 * np.clip(c, 0, 1).reshape((self.camera.screen_height, self.camera.screen_width))).astype(np.uint8), "L") ]
|
|
|
|
return Image.merge("RGB", img_RGB)
|
|
|
|
|
|
def get_distances(self): #Used for debugging ray-primitive collisions. Return a grey map of objects distances.
|
|
|
|
print ("Rendering...")
|
|
t0 = time.time()
|
|
color_RGBlinear = get_distances( self.camera.get_ray(self.n), scene = self)
|
|
#gamma correction
|
|
color = color_RGBlinear.to_array()
|
|
|
|
print ("Render Took", time.time() - t0)
|
|
|
|
|
|
img_RGB = [Image.fromarray((255 * np.clip(c, 0, 1).reshape((self.camera.screen_height, self.camera.screen_width))).astype(np.uint8), "L") for c in color]
|
|
return Image.merge("RGB", img_RGB) |