Made a GPU pathtracer

I made a very basic GPU pathtracer. Check out the code at Github if you want to play with it. Below is a devlog of sorts.

21. feb 2015

I implemented most of the features I wanted, so the experiment is done for now.

Feel free to mess around with the application. It's all open source on Github!

20. feb 2015

Alright. Got direct lighting now. Sort of.

This means we get crisp shadows.

Not sure if I'm doing it right though!

The lighting computation is now basically:

dir = CosineWeightedHemisphereSample(normal)
result = (0 0 0)
if ray traced from surface along dir does not hit anything:
    result += SampleSky(dir)

dir = SunDirection()
if ray traced from surface towards sun does not hit anything:
    result += SunColor(dir) * dot(normal, dir) / PI

So basically, I only trace a single bounce. I could incorporate multiple bounces by iteratively computing the light at the hit point if we DO hit something in the above ray tracings.

The divide by PI term in the second expression comes from the rendering equation, which I now sample directly.

11. feb 2015

Heck yeah! Got the camera working again. Turns out I made an error in deriving the lens direction, which caused the depth of field to not actually follow the camera. Sounds weird? Well it looked weird too.

Also, raymarching everything allows you to do some cool debugging tricks. Like checking if the hit point was within some margin, and marking the area with a specific color.

In this image I've projected the extent of the field of depth (that is, where objects are in focus) onto the ground, and marked the region with red.

09. feb 2015

Attempting to get depth of field working. Somewhat successful, but the view-matrix transformation is broken now.

I'll try to give a more detailed description of how it works once it uh... actually works...

06. feb 2015

Got anti-aliasing working. I moved the image-coordinate matrix transformation out of the vertex shader and into the fragment shader for easier math. Surprisingly, it didn't really affect performance. Or well, an additional millisecond won't overflow your cup when you're already at 80ms. Heh.

Anti-aliasing is basically free after that. I just add a random offset of half the pixel size to the sample coordinate.

"Ah! Those smooth edges!"

"I call it the spherktal."

Also I upped the rendering resolution by twofold for these renders. It really does look alot better with anti-aliasing.

05. feb 2015

Having fun with more advanced raymarching scenes.

I'm wondering if I want to implement anti-aliasing, or just leave it like this. Part of me kinda likes the rough outlines mixed with smooth internal edges...

Also, since I integrate light by additively blending over multiple frames, motion blur is super simple. Just let time advance while integrating!

04. feb 2015

Loading textures. Basic IBL. Got a chance to whip out my trig to do sky-dome sampling.

02. feb 2015

Got sampling and integration somewhat working. The way it works is rather cool:

  1. Store a floating point framebuffer to store accumulated light

  2. For each frame of refinement, render the scene to the framebuffer with additive blending enabled

  3. Each frame has its RNG seeded differently, so that bouncing rays sample the entire scene.

I've bound the R-key to accumulate light and advance the iteration count. After holding R for a while, an image will start to appear. I'm currently only sampling against an open sky (with plenty of light!), so the render converges pretty quickly.

I tried to sample against in-scene light sources, like a hovering sphere. But the result was waaaay to dark. I guess I need to read up on Monte Carlo integration.

01. feb 2015

Implemented a matrix-based camera system. This means I can use the same view-transformation matrix as I do in traditional triangle rendering. Not sure if I want to do that for this project, but I'm used to working with those type of transformations anyway.

19. jan 2015

Got SDL and OpenGL set up. I don't want to have too many dependencies for this project, so I'd like to implement the matrix math that I need. I reckon it should be enough with basic vec2/3/4 types and mat4 (does anyone ever use mat2/3?).

Resources

Some pages have been useful while developing this.