1shaders
1shaders
Combining Shaders
How and when to combine shaders into a single pass.
XOR
APR 19, 2025
5 5 Share
Howdy folks,
Hope you are doing well! Previously, I wrote about setting up “multi-pass”
shaders as a way of layering shaders together (or repeating a shader
multiple times):
PDFmyURL converts web pages and even full websites to PDF easily and quickly.
GM Shaders Mini: Recursive shaders
Today's mini tutorial is about recursive shader effects as a way of layering multiple passes
of shaders together.
This is commonly used for blurring because it can be more efficient to apply
a large blur in separate passes (for example, instead of a 9x9 Gaussian
blur, you can do a 9x1 blur and 1x9 blur, 2*N samples instead of N^2).
However, multipass effects have downsides. They are more difficult to
implement, requiring surfaces/canvases, additional draw calls, and more
video memory usage. They will complicate your draw pipeline process, and
in some cases, are unfeasible. The alternative is to combine two shaders
together. So, when is it worth it to combine shaders?
Uniforms and Inputs: When combining shaders, you’ll need all the
uniforms from both of the shaders. While the limits are pretty high,
shaders do have limits, especially when it comes to having lots of large
textures or uniform arrays. You also want to make sure the shader
inputs and outputs match (attributes and varyings in old-school GLSL).
The good news is that sometimes you can reduce shader complexity by
reusing uniforms for both effects (like resolution or time).
If you’ve made it past that, then you’re probably ready to start combining!
void main()
{
PDFmyURL converts web pages and even full websites to PDF easily and quickly.
vec2 uv = v_vTexcoord;
return col;
}
PDFmyURL converts web pages and even full websites to PDF easily and quickly.
Uniforms and macros can be directly referenced in the function, so they do
not need to be added as arguments. This is a fairly light-weight function. It
doesn’t require a bunch of texture samples, for-loops, branching, or lots of
math. Now let’s say you want to combine it with this chromatic aberration
shader:
Following a similar process, we end up with this function for radial CA:
PDFmyURL converts web pages and even full websites to PDF easily and quickly.
//Chromatic blur intensity
#define BLUR 0.05
//Chromatic constrast
#define CONTRAST 2.0
//Must be an even number
#define SAMPLES 20.0
PDFmyURL converts web pages and even full websites to PDF easily and quickly.
return sqrt(clamp(color_sum / weight_sum, 0.0, 1.0));
}
Now that we have both shaders as functions, we can put them together in
one fragment shader. While we’re doing that, we should combine the
uniforms, macros, functions, and shader inputs. This is a good time to
remove any redundancies you find along the way and share functions and
uniforms if possible.
Order of Effects
Now is the point where you can actually combine the two functions as
needed. In this case, I want to apply the desaturation first and then apply
the chromatic aberration. To do this, I need to replace the texture2D in the
“chromatic” function with my “saturation” function. If I wanted to apply
the chromatic aberration first and desaturate after, I would put the
chromatic function inside the saturation function. This way would be
faster because it wouldn’t require executing the saturation function within a
for-loop, but we don’t want to desaturate after applying a color effect.
Newsletter Update
Just a heads-up, the cost for paid subscriptions is going up to $8/mo or
$80/yr soon. This will help me keep a consistent schedule and take fewer
contracts. If you’ve ever wanted to join, now is the last chance to get it for
$50/yr!
PDFmyURL converts web pages and even full websites to PDF easily and quickly.
Subscribe for more tutorials
Conclusion
Thankfully, the process for combining shaders is intuitive most of the time.
It can be summed up be turning your shaders into functions and feeding
one function into another as needed. The inner function is applied first. It’s
preferable to do the most samples first because shader costs can
compound quickly.
Inputs - Vertex formats, uniforms, and varying will have to match up.
PDFmyURL converts web pages and even full websites to PDF easily and quickly.
Extras
Here are my 3 examples of one-pass blur shaders
1 Pass Blur - A simple, cheap disk blur based on the golden angle.
That’s all for today. Thank you for reading and have a great night!
-Xor
Subscribe to GM Shaders
By Xor · Launched 2 years ago
A series of mini shader tutorials for game developers and beyond!
5 Likes
5 5 Share
PDFmyURL converts web pages and even full websites to PDF easily and quickly.
Discussion about this post
Comments Restacks
Write a comment...
Hanprogramer 4d
Liked by Xor
Thank you for the tutorial! My question is, is there any tool I can use to parse GLSL codes
to do this automatically?
LIKE (1) REPLY SHARE
1 reply by Xor
design4use 3d
Let's say I wanted to combine two shaders with both moving elements, one in the
background that does moving color gradients, and one in the foreground that applies a
circular ripple/shockwave effect on top of it.
How would you approach this conceptually? The mental challenge for me is that both are
moving unlike a static photo background texture which I can just read.
LIKE REPLY SHARE
3 more comments...
PDFmyURL converts web pages and even full websites to PDF easily and quickly.
Top Latest Discussions
See all
PDFmyURL converts web pages and even full websites to PDF easily and quickly.
© 2025 Xor ∙ Privacy ∙ Terms ∙ Collection notice
PDFmyURL converts web pages and even full websites to PDF easily and quickly.