Practical way to use SER on Principled shader

Principled shader is an older thing with many branches, they are driven by random value and many parameters. Parameters are derived from node graph at runtime, they could be different per shading point even on the same object. I made the node graph into optix callable for fast replacement, it brings more complexity.

Naive SER on material index cannot truly help on the branch issue, case one material maps to one callable. It’s not direct mapping to shader lobes. Principled shader runs later after callable in CH. Since we cannot insert optixReorder into CH, and there is no multistage SER. I was considering move the callable and rng decision into Raygen shader, code become very ugly and runs even slower than naive SER. Before callingoptixReorder, we make decision on diffuse, metal, dielectric, opacity, etc.

// Naive approach
RayGen {optional optixReorder } → CH{ geometry → callbale → principled shader → lighting }
// More logical approach but slower
RayGen {geometry → callbale → rng decision → optixReorder } → CH{ principled shader → lighting }

I also take a look at Blender’s code, although it has a mega kernel. The Principled shader is divided into several stages, and probably has its own ray sorting kernel somewhere, didn’t find SER.

Since SER has been out for years, I am curious are there already more practical approach using it on complex shader.

Hi @iaomw, great question.

You are indeed highligting one of the tricky problems with SER.

There are two separate issues to consider. The first one, you are describing here - the order of decisions and execution of different parts of your shading. You need to know the rng decisions in advance of the reorder, which necessarily has to be done before shading begins. This means trying to move the rng decision to earlier in the pipeline. This approach is illustrated in a very simplified way in the SER whitepaper where the code makes the rng decision for Russian Roulette in advance of reorder & shader invocation. This means that the decision to prune the ray has been delayed until after shading is done, which might not be optimal, but can still produce large meaningful speedups compared to not using SER.

The second issue to consider is what live state exists when you reorder, and this can be affected by moving your rng decision. The issue is that live state incurs a migration cost during reorder, so minimizing the live state is critical for SER effectiveness. Live state means all variables and local stack memory that are used (read & written) both before and after your reorder & trace calls. Variables that are finished being used before you reorder, or variables you only start using after reorder, don’t count. Only variables that are ‘live’ both before and after reorder+trace matter. So far there haven’t been any tools for analyzing live state with OptiX. Nsight Graphics does this for Vulkan and Direct-X ray tracing, but Nsight Graphics generally doesn’t work for OptiX. In the very near future, Nsight Compute is going to have a live state report for OptiX applications. In the mean time, you can still estimate your live state and try to minimize it. You can consider recomputing or “re-materializing” variables that are easy to compute, occasionally that can help reduce live state and produce speedups despite the redundant computation.

We’ve heard reports that “micro-jittered sampling” can be effective at improving SER performance. Specifically, Sony Pictures Imageworks published a paper titled “Spear: Across the Streaming Multiprocessors: Porting a Production Renderer to the GPU” that mentions micro-jittering in the context of SER, and my understanding is that this addresses the problem you’re talking about. I believe the basic idea is to split rng decisions into two parts - a base random number decision that is shared across warps or blocks of neighboring threads, and a micro-jitter random number that still allows threads in a warp to make differing decisions and arrive at an unbiased result. This allows warps to statistically make similar decisions, while preserving thread randomness. In theory this might run some risk of getting warp-based block artifacts, but Sony reported to us that once it was tuned, this wasn’t a problem in practice.

–
David.