# \[ANN\] RayMakie, the new PBRT based rendering backend!

**URL:** <https://discourse.julialang.org/t/ann-raymakie-the-new-pbrt-based-rendering-backend/135734>\
**Category:** Package Announcements\
**Tags:** plotting, visualization, makie\
**Created:** [February 19, 2026, 3:09pm UTC](https://discourse.julialang.org/t/ann-raymakie-the-new-pbrt-based-rendering-backend/135734 "2026-02-19T15:09:46Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [February 19, 2026, 3:09pm UTC](https://discourse.julialang.org/t/ann-raymakie-the-new-pbrt-based-rendering-backend/135734/1 "2026-02-19T15:09:47Z")

</div>

We’ve been working on a new 100% Julia backend for GPU accelerated raytracing for Makie to replace RPRMakie!  
Its physically based ray tracing (pbrt) and is pretty much a Julia port of the amazing [pbrt-v4](https://github.com/mmp/pbrt-v4) ray tracer.  
I also added an experimental rasterizer, which also runs on the GPU via KernelAbstractions - which could pave a way to have a 100% Julia GPU graphics API, which has the potential to rival OpenGL in the future (still pretty hypothetical, we will need to see how it matches performance and how well it works across platforms).  
I just want to say, that I’m really happy with how the GPU stack has matured and how it has become possible to write this while reaching performance which is in the same regime as established ray tracers!  
Read all the details in [https://makie.org/website/blogposts/raytracing/](https://makie.org/website/blogposts/raytracing/).

| | |
| --- | --- |
| ![](https://global.discourse-cdn.com/julialang/original/3X/7/4/7490e0f200d7d21b9939f40d3ae056303ff09668.png) | ![](https://global.discourse-cdn.com/julialang/original/3X/7/4/74f41881716c68553befaaf08bed466afea53de9.png) |
| Terrain with volumetric clouds | Black hole with gravitational lensing |
| ![](https://global.discourse-cdn.com/julialang/original/3X/7/8/787d7f1b3b7c74e068358ded52efe9076fbf776f.png) | ![](https://global.discourse-cdn.com/julialang/original/3X/7/2/72a405c31aa38c604188cdaa8896d3a1b13a2c70.png) |
| Protein structure from [ProtPlot](https://github.com/MurrellGroup/ProtPlot.jl/) | Protein structure (gold, DoF) |
| ![](https://global.discourse-cdn.com/julialang/original/3X/0/e/0e69bd342a80124b2c839496b2b7669fff30dee0.png) | ![](https://global.discourse-cdn.com/julialang/original/3X/7/7/77c67ea9920cfc5271851edac12628d1f9be2f85.png) |
| CMS particle detector (Geant4.jl) | CMS detector full view |
| ![](https://global.discourse-cdn.com/julialang/original/3X/3/b/3be5dc5a818d173b4f728621af775ab8372a92f9.png) | ![](https://global.discourse-cdn.com/julialang/original/3X/2/8/2812eb73434d363855572de13dbab2d79c65ddad.png) |
| Oil palm (PlantGeom.jl) | Stanford bunny cloud (NanoVDB) |
| ![](https://global.discourse-cdn.com/julialang/original/3X/9/8/989464f798dde5b229bebf1b68ce0303a1b94075.png) | ![](https://global.discourse-cdn.com/julialang/original/3X/3/b/3b6581ea9f2fc79a0336f8bc16f45632372e31d3.png) |
| BOMEX cumulus clouds | Christmas tree (GLTF) |

---

<div class="post-metadata">

**Author:** ![langestefan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/langestefan/32/207923_2.png) [@langestefan](https://discourse.julialang.org/u/langestefan)\
**Post date:** [February 19, 2026, 3:14pm UTC](https://discourse.julialang.org/t/ann-raymakie-the-new-pbrt-based-rendering-backend/135734/2 "2026-02-19T15:14:58Z")

</div>

Really cool. My favourite is the gold ball dropping in water, looks gorgeous.

I hope there will be more demo’s at [Julia4PDEs 2026 workshop at Vrije Universiteit Amsterdam](https://discourse.julialang.org/t/julia4pdes-2026-workshop-at-vrije-universiteit-amsterdam/134524)!

---

<div class="post-metadata">

**Author:** ![oschulz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oschulz/32/2998_2.png) [@oschulz](https://discourse.julialang.org/u/oschulz)\
**Post date:** [February 19, 2026, 4:38pm UTC](https://discourse.julialang.org/t/ann-raymakie-the-new-pbrt-based-rendering-backend/135734/3 "2026-02-19T16:38:34Z")

</div>

Would it be possible to take advantage of RT-core-like hardware via Vulcan.jl in this context, in principle?

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [February 19, 2026, 7:30pm UTC](https://discourse.julialang.org/t/ann-raymakie-the-new-pbrt-based-rendering-backend/135734/4 "2026-02-19T19:30:09Z")

</div>

Awesome work!! Congratulations!

I saw that the post mentions NVIDIA and AMD GPU. What about Metal? Do we have support? If not, is there anything I can do to help supporting it?

---

<div class="post-metadata">

**Author:** ![garrek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/garrek/32/27937_2.png) [@garrek](https://discourse.julialang.org/u/garrek)\
**Post date:** [February 20, 2026, 2:22am UTC](https://discourse.julialang.org/t/ann-raymakie-the-new-pbrt-based-rendering-backend/135734/5 "2026-02-20T02:22:10Z")

</div>

This looks incredible. I’m very excited to find reasons to use it!

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [February 20, 2026, 7:37am UTC](https://discourse.julialang.org/t/ann-raymakie-the-new-pbrt-based-rendering-backend/135734/6 "2026-02-20T07:37:19Z")

</div>

I have tried Metal many times while Simon was developing this and it never worked quite right. Not sure about the current state, last I tried was two weeks ago or so. Either the code would not compile at all, because Metal is a bit stricter than the other backends with requiring Float32 types. And when it compiled and returned an image, there was a weird issue that I assume is because of some race condition, maybe related to atomics? The visual effect was that objects looked more or less transparent because in each sample, they’d sometimes be hit by rays and sometimes not. This would even happen after I removed all random number generation from the kernels, so rays should have been completely deterministic across samples. I was not able to debug this yet, I dug in to a point where I could see nondeterministic behavior in the queue sizes but not where it ultimately stemmed from. Simon recommended to try and build up a simpler example of the problem than starting with the full tracer but I didn’t have time for that.

To test, you have to pass `Metal.MtlArray` as the backend type to the integrator.

---

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [February 20, 2026, 12:15pm UTC](https://discourse.julialang.org/t/ann-raymakie-the-new-pbrt-based-rendering-backend/135734/7 "2026-02-20T12:15:44Z")

</div>

Yeah, I hope we figure out Metal support soon!  
I do bet a bit on claude code, which is pretty good at debugging these kind of problems when it is allowed to execute Julia code.  
Usually its enough to dev all the involved packages and set it on one of the example scenes with a low resolution and sample count and tell it to fix all errors it encounters. It may also be required to guide it to towards creating MWEs until it has isolated the problems for harder problems (e.g. like the atomic operation bug).  
Btw, the API has changed, so now one needs to pass `device=Metal.MetalBackend()`.

---

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [February 20, 2026, 12:41pm UTC](https://discourse.julialang.org/t/ann-raymakie-the-new-pbrt-based-rendering-backend/135734/8 "2026-02-20T12:41:09Z")

</div>

In theory, yes!  
In practice quite a lot would be required to get julia to compile to SPIR-V and have the RT core extensions available.  
I do hope that the GPU infrastructure matures in that direction and I do think we have most of the puzzle pieces together for this (we do already compile to SPIR-V e.g. in OpenCL.jl).

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [February 20, 2026, 3:41pm UTC](https://discourse.julialang.org/t/ann-raymakie-the-new-pbrt-based-rendering-backend/135734/9 "2026-02-20T15:41:57Z")

</div>

> [@sdanisch](#):
>
> (we do already compile to SPIR-V e.g. in [OpenCL.jl](https://juliaregistries.github.io/General/packages/redirect_to_repo/OpenCL))

Note that OpenCL is a different SPIR-V dialect than GLSL/Vulkan with stricter semantics regarding control flow etc., which complicates things a bit (there are already issues with the OpenCL dialect not supporting the way Julia throws exceptions for example). There has recently been some work on supporting GLSL SPIR-V in the LLVM backend, which might help, but I believe SPIRV.jl even decided to skip LLVM entirely

---

<div class="post-metadata">

**Author:** ![lazarusA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lazarusa/32/6571_2.png) [@lazarusA](https://discourse.julialang.org/u/lazarusA)\
**Post date:** [February 20, 2026, 4:21pm UTC](https://discourse.julialang.org/t/ann-raymakie-the-new-pbrt-based-rendering-backend/135734/10 "2026-02-20T16:21:57Z")

</div>

Also, before the API changed, I was able get things alright. I remember I had to unroll the `for loops` in the kernels, otherwise all was messy and most of the times black. We will need to start again and see. I should have the MWE around, somewhere.

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [February 20, 2026, 5:03pm UTC](https://discourse.julialang.org/t/ann-raymakie-the-new-pbrt-based-rendering-backend/135734/11 "2026-02-20T17:03:01Z")

</div>

Ideally, the same KernelAbstractions code would work for all backends, but there seem to be many differences left to account for..

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [February 21, 2026, 2:18pm UTC](https://discourse.julialang.org/t/ann-raymakie-the-new-pbrt-based-rendering-backend/135734/12 "2026-02-21T14:18:19Z")

</div>

~~Yeah, I tried it here but I could not make it even compile using Metal.jl~~

Never mind, it was not a compilation problem but my inability to install the correct packages and run the example 😅

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [February 21, 2026, 7:06pm UTC](https://discourse.julialang.org/t/ann-raymakie-the-new-pbrt-based-rendering-backend/135734/13 "2026-02-21T19:06:32Z")

</div>

So you managed to render something with Metal with the current state of the package?

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [February 21, 2026, 7:28pm UTC](https://discourse.julialang.org/t/ann-raymakie-the-new-pbrt-based-rendering-backend/135734/14 "2026-02-21T19:28:39Z")

</div>

No! It turns out I could not even make the packages run. I thought it was compilation issues but it was not. I am still trying.

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [February 21, 2026, 10:30pm UTC](https://discourse.julialang.org/t/ann-raymakie-the-new-pbrt-based-rendering-backend/135734/15 "2026-02-21T22:30:10Z")

</div>

I finally managed to correctly instantiate the packages and tried to run the black hole example. The result was:

```julia-auto
julia> Unhandled Task ERROR: InvalidIRError: compiling MethodInstance for Hikari.gpu_vp_finalize_film_kernel!(::KernelAbstractions.CompilerMetadata{KernelAbstractions.NDIteration.DynamicSize, KernelAbstractions.NDIteration.DynamicCheck, Nothing, CartesianIndices{1, Tuple{Base.OneTo{Int64}}}, KernelAbstractions.NDIteration.NDRange{1, KernelAbstractions.NDIteration.DynamicSize, KernelAbstractions.NDIteration.DynamicSize, CartesianIndices{1, Tuple{Base.OneTo{Int64}}}, CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}}, ::MtlDeviceMatrix{ColorTypes.RGB{Float32}, 1}, ::MtlDeviceVector{Float32, 1}, ::MtlDeviceVector{Float32, 1}, ::Int32, ::Int32) resulted in invalid LLVM IR
Reason: unsupported use of double value

```

---

<div class="post-metadata">

**Author:** ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)\
**Post date:** [February 21, 2026, 11:37pm UTC](https://discourse.julialang.org/t/ann-raymakie-the-new-pbrt-based-rendering-backend/135734/16 "2026-02-21T23:37:36Z")

</div>

> [@jules](#):
>
> So you managed to render something with Metal with the current state of the package?

Does a sphere count? 🙂

 ![Captura de Tela 2026-02-21 às 20.23.25](https://global.discourse-cdn.com/julialang/original/3X/0/b/0bef5e094ae744bc2924ac72d785624e73fc966f.png)

---

<div class="post-metadata">

**Author:** ![lazarusA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lazarusa/32/6571_2.png) [@lazarusA](https://discourse.julialang.org/u/lazarusA)\
**Post date:** [February 23, 2026, 8:17am UTC](https://discourse.julialang.org/t/ann-raymakie-the-new-pbrt-based-rendering-backend/135734/17 "2026-02-23T08:17:34Z")

</div>

Try to start easy, maybe with some basic examples from Raycore.jl first.

Edit: and probably the branch `sd/multitype-vec` which is the one used for the complicated demos.

---

<div class="post-metadata">

**Author:** ![empet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/empet/32/221303_2.png) [@empet](https://discourse.julialang.org/u/empet)\
**Post date:** [February 23, 2026, 2:34pm UTC](https://discourse.julialang.org/t/ann-raymakie-the-new-pbrt-based-rendering-backend/135734/18 "2026-02-23T14:34:06Z")

</div>

I’m sorry, accidentally I clicked on “Flag this post”. I cannot find how to remove it 🙂
