When you build up a color (or a coordinate) through a big pile of adjustments you can
end up writing col = mix(col, target, x) over and over. These helpers do the assignment
in place with fewer terms. Reads as one short verb instead of an equation.
// admix: push the FIRST argument toward the second
// x=0 does nothing, x=1 fully replaces a with b
void admix(inout float a, in float b, in float x) { a = mix(a, b, x); }
void admix(inout vec2 a, in vec2 b, in float x) { a = mix(a, b, x); }
void admix(inout vec3 a, in vec3 b, in float x) { a = mix(a, b, x); }
void admix(inout vec4 a, in vec4 b, in float x) { a = mix(a, b, x); }
// abmix: push the SECOND argument toward the first
// x=0 does nothing, x=1 fully replaces b with a
void abmix(in float a, inout float b, in float x) { b = mix(b, a, x); }
void abmix(in vec2 a, inout vec2 b, in float x) { b = mix(b, a, x); }
void abmix(in vec3 a, inout vec3 b, in float x) { b = mix(b, a, x); }
void abmix(in vec4 a, inout vec4 b, in float x) { b = mix(b, a, x); }
admix mutates whichever value is your accumulator; abmix is the mirror image,
for when the variable you want to keep is the target rather than the source.
Usage
vec3 col = base;
admix(col, vec3(1.0, 0.3, 0.1), glow); // warm it up
admix(col, vec3(0.0), vignette); // darken toward the edges
admix(col, neon, _pulse(uv.x, 0.5, 0.1)); // blend a band in
// abmix keeps `canvas` as the running result while reading a fresh sample
abmix(sample, canvas, feedbackAmount);
Notes
- These are sugar, not magic. They compile to the same
mixyou’d write by hand. The win is fewer places to misspell the variable when a step gets long. - Use
admixby default; reach forabmixonly when flipping the argument order reads more naturally at the call site.