Rendering to intermediate buffers in shaders

Godot Version

4.3

Question

I’m trying to implement the technique used by Sébastien Hillaire’s “A Scalable and Production Ready Sky and Atmosphere Rendering Technique” (see links below). The method involves rendering 2D and 3D LUTs to use as part of the next step of the computation. Is there a way to achieve this in Godot?

Basically, I need to write a shader that can generate a texture (2D and 3D). Then another shader that can take that texture as an input. Ideally all this should stay in GPU memory without having to move data to/from the CPU.

I saw posts about rendering to a ViewportTexture as an intermediate buffer. But that is very clunky to set up, presumably needs to move data back to the CPU, and I don’t see how you could use this workaround for 3D/higher dimensional textures.

Links

The paper is on the author’s website. He also provides an example implementation in this GitHub repo, and someone else implemented it in ShaderToy here. (The relevant part for this question is probably easiest to see on ShaderToy: look at the “channels” - multiple tabs in the code editor on the website).

You can run compute shaders written in glsl, which lets you write to a buffer you create yourself.

You might also want to take a look at the new Rendering Effects that were implemented in 4.3, which lets you run compute shaders at various rendering stages and gives you access to some render data (like screen and depth textures, camera projection, etc). Here is a video with the developer talking through an example, and here is the repo with the sun ray effect.

1 Like

Thanks @tayacan ! I’ll have to look into the rendering effects API in more detail when I get the time, lots of new stuff there.

About the compute shader idea – how would I get the buffer from the compute shader into a fragment shader? Would it have to go through the CPU and into a texture uniform?