Blog Archive About

Psychopath Renderer

a slightly psychotic path tracer

2018 - 11 - 21

Random Notes on Future Direction

This post is not going to be especially coherent. I wanted to jot down some thoughts about the future direction of Psychopath, given the decisions in my previous post. Normally I would do this in a random text file on my computer, but I thought it might be interesting to others if I just posted it to the blog instead. It should be fun to check back on this later and see which bits actually ended up in Psychopath.

2018 - 11 - 13

A Different Approach

I've been away from Psychopath for a while working on other projects, but recently I stumbled upon a blog post by Yining Karl Li, entitled "Mipmapping with Bidirectional Techniques". In it, he describes his solution to a problem I've been pondering for a while: how to handle texture filtering in the context of bidirectional light transport.

The problem essentially comes down to this: texture filtering should be done with respect to the projected area on screen, but when tracing rays starting from a light source you don't know what that projected area is going to be yet. In Psychopath's case it's even worse because it applies not just to texture filtering but also to dicing rates for geometry. In Psychopath you can't even calculate ray intersections without a filter width. So this problem has been bugging me for a while.

Yining explores an approach to this problem that I've also considered, which is to have the filter width simply be independent of the rays being traced. In other words: screw ray differentials, just use camera-based heuristics. The benefit of this approach is that every point on every surface has a single well-defined filter width, regardless of where rays are coming from or how they're being generated. The down side is that there are circumstances (such as magnification through a lens) where those filters become too blurry.

These are all things I've thought about before, and I've gone back and forth many times about how I want to approach this. However, Yining's post also linked to a paper from Weta Digital about their renderer Manuka. And that sent me down a rabbit hole that has me reconsidering how I want Psychopath's entire architecture to work.

2017 - 08 - 03

BVH4 Without SIMD

I recently switched the Rust version of Psychopath over from a binary BVH (BVH2) to a 4-branching BVH (BVH4). This is a fairly standard thing to do in a ray tracer to take advantage of SIMD operations on modern CPUs. With a BVH4 you can test against four bounding boxes at once with SIMD, which in theory can get you some pretty significant speedups.

However, my BVH4 implementation in Psychopath doesn't use SIMD, and is nevertheless faster than (or at least comparable to) my BVH2 implementation. This surprised me because I thought (?) the conventional wisdom was that a BVH4 is slower except when used to exploit SIMD.

So I'm writing this post to explain how I arrived here and why BVH4 might always be better.

2017 - 06 - 13

Switching from C++ to Rust

I'll get right to it: I've rewritten Psychopath in Rust. And I feel like this requires an explanation.

The short version is that Psychopath is a personal project that I work on for fun, and I had fun rewriting it in Rust. The rest of this post is the long version, as seen through the lens of my experiences developing in Rust.

But first I want to be really, really clear that I do not advocate rewriting things in Rust. It's apparently a meme to say that things should be rewritten in Rust (or so I hear... I haven't actually witnessed it much). If you have a working code-base that's actually used for real things, then rewriting it in Rust (or any language) requires strong justification. In my case, Psychopath isn't used for real things, so it doesn't take much justification aside from "I felt like it".

With that out of the way, let's dive in!

2015 - 07 - 16

Subdivision Surfaces

I recently implemented Catmull-Clark subdivision surfaces in Psychopath.

One of my goals with Psychopath is for all curved surfaces to actually render as curved surfaces rather than as tessellated triangle meshes. To accomplish this for subdivision surfaces I am leveraging OpenSubdiv to pre-process the cage mesh into b-spline patches. Psychopath then converts the b-spline patches into bezier patches which it already knows how to render.

The end result is this:

Pontiac GTO '67

(Model by 'thecali', available on BlendSwap--please note that the version in the render above has some parts missing, as some bits were modeled with curves which Psychopath can't render yet.)

In other words, I can finally render interesting models! Yay! Most things are modeled with Catmull-Clark subdivision surfaces these days, so this a big step.

The only down-side so far is that OpenSubdiv seems to be a bit on the slow side when converting the mesh to b-spline patches—it takes around 45 seconds for this model. It's possible I'm not using the library optimally. It's certainly something I'll need to investigate. But I'm quite pleased for now!