Transcending the RGB abstraction for full spectral physics is a masterclass in bridging the gap between computer graphics and true optical reality. This work elegantly demonstrates how modern hardware can finally capture the intricate, wavelength-dependent beauty of light.
Deep Dive
Prerequisite Knowledge
- No data available.
Where to go next
- No data available.
Deep Dive
I Replaced RGB with Actual PhysicsAdded:
This rainbow is not a texture. Most renderers fake color with RGB. Blender can make beautiful glass, but it doesn't really trace [music] light like this.
Real light has wavelengths, and each wavelength bends by a different amount.
So, I built a spectral [music] path tracer from scratch, and at first it looked pretty bad.
Let's start by creating a ray of light.
To create a ray, we start by calculating a vector perpendicular to the main beam direction. To create a thick beam, we need to know which way is sideways relative to the beam's forward direction. Source stir. In 2D, we get a perpendicular vector by swapping X and Y and negating the new X. This mathematically rotates the vector 90Β°.
Then, we shift the ray origin sideways along the perpendicular vector to give the beam some thickness. And finally, we slightly angle the ray direction using the perpendicular vector to simulate light spreading. Here's how it looks.
>> [music] >> Physically, this beam represents a path of photons. And now that we have a ray, we need something for it to hit. First, we need the three points that make up our triangle.
For the current pixel we are rendering, how close is it to the three line segments that connect our corners? We calculate the thickness for each edge, then add them together to form a complete closed triangle. If the current pixel is on one of those edges, prism edges will be a high value like one. If it's far away, it will be zero. We multiply a light blue color by that value and add it to the canvas. [music] So, now we have this variable glass object that will act as our prism. But, now we have to consider how a spectral renderer works and how it's even different from a regular renderer. When light hits a denser medium like glass, it slows down. [music] Because it hits at an angle, one side of the light wave slows down before the other, causing the whole beam to pivot. This is called Snell's law. Let's look at the boundary between two transparent media. A light ray arrives from point P hitting the origin. We measure the angle theta one from the normal line. In medium two, the ray bends based on index ratios. We can use this to calculate transmission vectors.
Most graphics engines like Unreal or Unity store light as a three-dimensional vector. This is designed for monitors, not for physics. A spectral renderer discards RGB entirely, storing light as a wavelength in nanometers.
So, you can see that the index of refraction is no longer fixed. [music] It changes with the wavelength. So, the combination of Snell's law with a unique index of refraction for each ray means that every wavelength bends by a different angle.
As you can see, Snell's law is working, but there's a problem. The light doesn't seem to be smoothly transitioning. It's broken up into four distinct colors. In order to have a smooth gradient or spectrum of light, we need to use something called Monte Carlo sampling.
>> [music] >> To understand Monte Carlo sampling, we will try to understand calculating pi through a standpoint of probability.
Imagine a square box with a circle drawn inside it. The circle has area pi r squared. The square has area 4 r squared.
A randomly dropped coin lands inside with probability pi over 4. So, pi is equal to 4 * the fraction of coins that land inside [music] the circle.
So, let's start dropping coins.
As you can see, after 500 coins, >> [music] >> we get pretty close to the true value of pi.
Now, here's the first look we're going to take at the rendering [music] equation. Now, I'm not going to expect you to understand this equation yet, but when we eventually do calculate it, you can see we can do a numerical approximation. But, can you see that this looks [music] familiar?
When you sample uniformly between A and B, the probability density function [music] P is a flat constant. Since the total probability must equal 1 over that interval, the probability of hitting any specific [music] X is 1 over B minus A.
Now, when we look at the general form of the Monte Carlo estimator, which divides by P, you can see that if we plug our uniform probability into that general equation, it reduces down to the average value of a function equation from calculus one. Or put simply, the foundation of Monte Carlo is just the mean value theorem. It's just the integral over the interval.
So, in the shader, we loop through our [music] samples and generate a few random numbers for each one. We use the first number to pick a random wavelength and calculate [music] its exact index of refraction so the glass bends correctly.
The other number slightly jitter the [music] light beam's starting position and direction before we fire that specific ray at the prism and add up the results.
>> [music] >> I don't know, you stare at the math for hours, but seeing it actually disperse into a perfect rainbow is just very satisfying. Now, let's continue on to 3D.
We start by shooting a ray from the camera and letting it bounce through the scene.
>> [music] >> Two values travel with the ray, throughput, which is the surviving energy, and radiance, which is the collected energy.
If the ray escapes the scene, it picks up skylight, added directly to the radiance.
At each point, we cast a shadow ray. If it's unblocked, we add Lambert shading.
>> [music] >> Indirect light randomly picks a new direction in the hemisphere and continues bouncing.
>> [music] >> What we solved is the light transport equation that we saw earlier.
Here's how it looks.
>> [music] >> Already, it looks pretty cool, but the goal still remains to switch to spectral path tracing.
So, for each sample, we pick one random wavelength.
Then we convert wavelength to RGB weight acting as a spectral band pass filter.
Each wavelength gets a unique index of refraction.
>> [music] >> Reflectance also uses a per wavelength value.
If you remember our light transport equation from before, basically all we're doing is making it depend on wavelength.
>> [music] [bell] >> Now let's look at our trace function, which handles the core spectral path tracing loop for our glass and ground intersections. It tracks the individual wavelengths across each bounce, executing the ray mesh interactions, environment sampling, and reflectance calculations we discussed. It may look complicated, but it's just what we discussed earlier. At the end we return our radiance. And this radiance that we're returning is our L in our radiance equation.
So I imported [music] it to cancer model so you could better see the radiance.
If you look closely, you might notice that the noise is colorful now, and that the glass is almost producing a rainbow.
This is pretty cool, but I noticed that it's missing a pretty important feature that real glass has, caustics.
>> [music] >> I want to show you this.
This is a lens I made in glass blowing.
And this bright spot where it converges light is called a caustic. You can see that I'm trying to focus the sunlight to burn this plastic, and there's the melted spot. To replicate this effect graphically, we need to learn photon mapping. As you may know from my previous video, I've been trying to get into university, and I have. I got accepted to UCSD for this fall. And while learning caustics, I found out a lot about a professor who taught at UCSD until 2018. His name is Henrik Jensen, and he received a technical achievement Academy Award in 2004. [music] His foundational math and direct technical consulting were rapidly adopted across major visual effects studios, proving instrumental in rendering the lifelike skin of Gollum in Lord of the Rings, and in Avatar, as well as the hair in Tangled. He also co-founded the render engine KeyShot. Really quite the guy.
And he also invented this process called photon mapping.
So, let's try to understand how photon mapping works.
So, path tracing shoots rays from the camera, >> [music] >> whereas photon mapping shoots from the light. First, we spawn a photon at a random position on the beam with a random wavelength.
Then at each glass surface, we refract using our index of refraction.
We only record the photon when it lands on the floor after passing through glass. [music] Then we write into an accumulation texture called the photon map.
So, here's the function for that process we just [music] described. To sum up what we're doing, we're shooting rays from the light.
The rays refract through our glass and then accumulate on the ground.
>> [music] [music] >> So, as I move, you might be able to see the photons accumulating in the photon map.
And we do have a pretty interesting-looking optical effect, even though it looks a little bit wrong. But there's a major issue. It's running at around 1 FPS.
This footage is sped up by quite a bit.
And this is a problem that I really just couldn't get my head around.
I couldn't figure out any meaningful optimization that would allow us to have a spectral path tracer and be relatively quick.
So, I had a choice.
I could keep going and try to optimize the engine more or I could reconsider the engine altogether.
So, I chose the second option and realized that I had to do something that I vowed never to do.
Hardware ray tracing.
You see, I have a MacBook.
And already that is probably turning on alarm bells in your head for the mere thought of RTX. How is this Apple product supposed to hardware ray trace?
Well, guess what? My MacBook is the very first MacBook to have secret RT cores.
The only reason that we are not so familiar with these powers is that nobody develops for them until now.
WebGPU has this very year added experimental hardware ray tracing support.
That means my apprehension to purchase a thousand dollar GPU was founded in a lie.
I already had what I needed. But there was a problem. My engine doesn't support the newest version of WebGPU, version 29. I programmed it with C++ headers and so to switch to the new version I would have to switch [music] the whole thing to C headers. Well, that was so jank to process that I considered something I had long ago decided I would never do.
Rust. WebGPU is made in Rust, so developing it in C++ is already a bit of a translation.
So I wondered, why not just do it in Rust? The problem?
Here's some C++.
>> [music] >> And this is the same thing in Rust.
See how it makes you want to throw up?
Me too.
I just didn't know how I was going to not only learn Rust but make a whole engine in it.
Let's start by writing a default simple quad. You might be able to tell that a lot of the boilerplate actually looks the same. And here's our quad.
Then I had to figure out how to re-implement my 3D pipeline.
I started by making a simple spinning cube. Since the graphics code is exactly the same, it was mainly a port. Here's what it looks like.
Then I re-implemented our spectral path tracer and as expected the FPS made a massive jump from two up to 80 FPS, [music] which was the purpose of this port to begin with. And here's what that looks like.
>> [music] [music] [music] >> Mhm.
Related Videos
Is dark matter real? - Why can't we find it? - physicist explains | Don Lincoln and Lex Fridman
LexClips
1K viewsβ’2026-05-30
Saptarshi Basu - Spectacular Voyage of Droplets: A Multiscale Journey to Extreme Flow Conditions
DAlembert-SU-CNRS
152 viewsβ’2026-06-02
A 6.0 Just Hit Hawaii β And It Came From The Wrong Place
TerraWatchHQ
115 viewsβ’2026-06-03
The Split-Second Mistake That Made Bouncing Bettys So Deadly
NoMansLandChannel
253 viewsβ’2026-06-02
Nobody Expected This Lava Reaction π€― #faits #facts
TendzDora
28K viewsβ’2026-05-30
The Difference In Charged And Neutral Particles
heavybrainspace
959 viewsβ’2026-05-29
The Silent Memory of Glass
UnchartedScienceworld
146 viewsβ’2026-05-30
A380 vs Every Vehicles Crash Test Challenge | Which One Win?
BeamLap
163 viewsβ’2026-05-29











