Victory!

Throughout this weird year I managed to accomplished a lot of different milestones when refactoring the rendering system in Crimild. Yet, the year was coming to an end and there was one feature in particular that was still missing: compute operations.

Then, this happened:

That, my friends, is the very first image created by using a compute pass in Crimild. The image is then used as a texture that is presented to the screen. Both compute and rendering passes are managed by the frame graph and executed every frame in real-time.

At the time of this writing I haven't implemented true synchronization between the graphics and compute queues, meaning that the compute shader might still be writing the image by the time it is read by the rendering engine, which produce some visual artifacts every once in a while. 

Of course, I had to push forward.

A few hours passed and the next compute shader that I made was used to implement a very basic path tracer completely in the GPU:

It’s not a true real-time ray tracing solution (since I don’t have a GPU with proper RTX support), but sampling is done incrementally, allowing me to reposition the camera in real-time:

I’m still amazed about how easy it was to port my software-based path tracer to the GPU.

So much power…

So much potential…

I wanted more…

I needed more…

I became greedy.

I flew too close to the Sun.

And I got burnt.

Then I learned a valuable lesson. It turns out that if I screwed up the shader code in some specific way (which I’m still trying to understand), weird things happens. Like my compute crashing… bad (as in having to turn it off and on again bad).

Next steps

I’m planning on (finally) merging the Vulkan branch at this point, since all major features are done. Sure, there are things that still need to be fixed and cleaned up, yet they don’t really depend on Vulkan itself, like behaviors, animations and sound, which is broken (again).

Plus, I really want to release Crimild v5.0 in the next decade.

See you next year!

I spent a weekend with a path tracer

This is definitely not how I was planning to spending my weekend (don’t get me wrong, I was going to work on some other things. What else would I do? Go outside and play with the other kids?)

output_12e

It was Friday evening and I was doing a mandatory email check before leaving work when I saw it: one email from Amazon with some book recommendations, including the following one:

414m4etx0al
Go ahead, click the image and check out the book. I’ll wait

The goal of this book by Peter Shirley is to implement a basic path tracer in C++ in just a couple of days. I didn’t pay too much attention at the moment, other than it was quite cheap and got several goods reviews. But it stuck in my head for the rest of the night and I bought it as soon as I got home.

And that, kids, is how I meet you mother spent the weekend: in between math and a lot of waiting for low-resolution images to be rendered. I mean, A LOT of waiting. What an amazing weekend!

Honestly, it was an enlightening experience. The book is well written and a lot of fun to read. I’ve worked with ray tracers before, but a path tracer is a bit different. And, even when I follow most of the code examples from the book, implementing it on top of Crimild was a challenge on its own.

My implementation still needs a lot of work, but it produce pretty good images. Take a look:

As it is right now, the path tracer supports diffuse illumination for metallic, lambertian and dielectric materials. I ended up not implementing depth of field, since I’m not interested on that at the moment.

What’s next? Well, it does need some heavy optimizations, of course. The image at the top of this post took about 3.5 hours to render (no, that wasn’t a typo). The good news is that parallelizing the algorithm should’t require too much work. On the other hand, it would be great to render some actual triangles, not just spheres.

The other books in the series look promising and continue to improve the path tracer, so I’ll be giving them a look in the future. Check out Peter Shirley’s blog for more about his books.

As a side effect, being a math-based project, it allowed me to revisit Crimild’s math classes, making them even more robust. That’s pretty old code and somehow there’s always something to fix or improve.

Finally, if you need a good introduction to what a path tracer does, take a look at this excellent video from Disney’s labs

The code is in one of the examples projects. At the time of this writing I haven’t migrated the reusable code to the core library since I still need to do some review and cleanup, but that will have to do for now.