2

I'm working on a ray tracing project in Python and have encountered a performance bottleneck. I believe implementing frustum culling in my Camera class could significantly improve rendering times.

Camera:

class Camera():
    def __init__(self, look_from, look_at, screen_width = 400 ,screen_height = 300,  field_of_view = 90., aperture = 0., focal_distance = 1.):
        self.screen_width = screen_width
        self.screen_height = screen_height
        self.aspect_ratio = float(screen_width) / screen_height
        self.look_from = look_from
        self.look_at = look_at
        self.camera_width = np.tan(field_of_view * np.pi/180   /2.)*2.
        self.camera_height = self.camera_width/self.aspect_ratio
        self.cameraFwd = (look_at - look_from).normalize()
        self.cameraRight = (self.cameraFwd.cross(vec3(0.,1.,0.))).normalize()
        self.cameraUp = self.cameraRight.cross(self.cameraFwd)
        self.lens_radius =  aperture / 2.
        self.focal_distance = focal_distance
        self.x = np.linspace(-self.camera_width/2., self.camera_width/2., self.screen_width)
        self.y = np.linspace(self.camera_height/2., -self.camera_height/2., self.screen_height)
        xx,yy = np.meshgrid(self.x,self.y)
        self.x = xx.flatten()
        self.y = yy.flatten()
    def get_ray(self,n):
        x = self.x + (np.random.rand(len(self.x )) - 0.5)*self.camera_width  /(self.screen_width)
        y = self.y + (np.random.rand(len(self.y )) - 0.5)*self.camera_height /(self.screen_height)
        r = np.sqrt(np.random.rand(x.shape[0]))
        phi = np.random.rand(x.shape[0])*2*np.pi
        ray_origin = self.look_from  +   self.cameraRight *r * np.cos(phi)* self.lens_radius   +   self.cameraUp *r * np.sin(phi)* self.lens_radius
        return Ray(origin=ray_origin, dir=(self.look_from  +   self.cameraUp*y*self.focal_distance  +  self.cameraRight*x*self.focal_distance  + self.cameraFwd*self.focal_distance  - ray_origin  ).normalize(), depth=0,  n=n, reflections = 0, transmissions = 0, diffuse_reflections = 0)

2
  • Frustum culling is not a suitable approach to increase your ray tracing performance. If you ignore objects outside the view frustum, you will degrade the indirect lighting. In a dynamic scene, this will manifest itself in abrupt changes when new objects enter the frustum. Commented Jan 16, 2024 at 15:15
  • You mean the speed won't increase? Commented Jan 16, 2024 at 15:40

1 Answer 1

6

You just need to modify the Camera class as following:

class Camera():
    def __init__(self, look_from, look_at, screen_width = 400 ,screen_height = 300,  field_of_view = 90., aperture = 0., focal_distance = 1.):
        self.screen_width = screen_width
        self.screen_height = screen_height
        self.aspect_ratio = float(screen_width) / screen_height
        self.look_from = look_from
        self.look_at = look_at
        self.camera_width = np.tan(field_of_view * np.pi / 180 / 2.) * 2.
        self.camera_height = self.camera_width / self.aspect_ratio
        self.cameraFwd = (look_at - look_from).normalize()
        self.cameraRight = (self.cameraFwd.cross(vec3(0., 1., 0.))).normalize()
        self.cameraUp = self.cameraRight.cross(self.cameraFwd)
        self.lens_radius = aperture / 2.
        self.focal_distance = focal_distance
        self.near = .1
        self.far = 100.
        self.x = np.linspace(-self.camera_width / 2., self.camera_width / 2., self.screen_width)
        self.y = np.linspace(self.camera_height / 2., -self.camera_height / 2., self.screen_height)
        xx, yy = np.meshgrid(self.x, self.y)
        self.x = xx.flatten()
        self.y = yy.flatten()
    def get_ray(self,n):
        x = self.x + (np.random.rand(len(self.x)) - 0.5) * self.camera_width / (self.screen_width)
        y = self.y + (np.random.rand(len(self.y)) - 0.5) * self.camera_height / (self.screen_height)
        ray_origin = self.look_from + self.cameraRight * x * self.near + self.cameraUp * y * self.near
        return Ray(origin=ray_origin, dir=(self.look_from + self.cameraUp * y * self.focal_distance +self.cameraRight * x * self.focal_distance +self.cameraFwd * self.focal_distance - ray_origin).normalize(), depth=0, n=n, reflections=0, transmissions=0, diffuse_reflections=0)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.