Overlaying colors in glsl top

Hello,
I have 3 full colour channels/layers generated in glsl top. I’m trying to output them one on top of another without them being transparent / multiplied. I think it should be pretty simple but can’t get my head around it for some reason. Here is a picture of what I have and what I want.
Currently I’m doing:
colour = colour1 + colour2 + colour3;
fragColor = TDOutputSwizzle(vec4(colour, 0));

Thanks!

Hi @Dinka,

when adding colors you are “mixing” them. As in Red plus Green will result in Yellow.
Instead what you want is replace them.
How do you determine the color for the pixel in the GLSL TOP? Might be helpful to post the full shader…

Cheers
Markus

Thanks Markus

I input shape colors as vectors into GLSL TOP. I undestand that at the moment I’m just adding them but somehow can’t work out what I need to do in order for the shapes not to mix but be layered on top of each other…

This is what I’m have now

uniform vec4 rectHeightIn;
uniform vec4 rectWidthIn;

uniform vec3 fullColourRIn;
uniform vec3 fullColourGIn;
uniform vec3 fullColourBIn;

float rect(in vec2 st, in vec2 size){
  size = 0.25 - size * 0.25;
  vec2 uv = smoothstep(size, size, st*(1.0-st));
  return uv.x*uv.y;
}

out vec4 fragColor;

void main()
{
  vec2 st = vUV.st;
  vec3 color;

  vec3 fullColourR = fullColourRIn;
  vec3 fullColourG = fullColourGIn;
  vec3 fullColourB = fullColourBIn;
    
  color.r += rect (st, vec2(rectWidthIn.r, rectHeightIn.r));
  color.g += rect (st, vec2(rectWidthIn.g, rectHeightIn.g));
  color.b += rect (st, vec2(rectWidthIn.b, rectHeightIn.b));

  fullColourR *= color.r;
  fullColourG *= color.g;
  fullColourB *= color.b;

  vec3 fullColour = fullColourR + fullColourG + fullColourB;

  fragColor = TDOutputSwizzle(vec4(fullColour, 0));
}

Thanks

Hi @Dinka,

for clarity, I renamed a few of the uniforms. But mainly to your question - a standard alpha compositing function would look like this:

cO = cS * aS + cB * aB * (1 - aS)

where

  • cO: output color
  • cS, aS: color and alpha of source
  • cB, aB: color and alpha of backdrop

you now have to apply this function once for each layer in your composition to get to the final result.

uniform vec4 uRectHeightIn;
uniform vec4 uRectWidthIn;

uniform vec4 uColorRect1;
uniform vec4 uColorRect2;
uniform vec4 uColorRect3;

float rect(in vec2 st, in vec2 size){
  size = 0.25 - size * 0.25;
  vec2 uv = smoothstep(size, size, st*(1.0-st));
  return uv.x*uv.y;
}

out vec4 fragColor;

void main()
{
  vec3 rects = vec3(0.0);
  vec4 color = vec4(0.0);

  // calculate the 3 rectangles here and store in the rects vector  
  rects = vec3(
      rect(vUV.st, vec2(uRectWidthIn.r, uRectHeightIn.r)), 
      rect(vUV.st, vec2(uRectWidthIn.g, uRectHeightIn.g)), 
      rect(vUV.st, vec2(uRectWidthIn.b, uRectHeightIn.b))
      );

  // alpha compositing has to be done in layers
  // cO = cS * aS + cB * aB * (1 - aS)
  // cO: output color
  // cS, aS: color and alpha of source
  // cB, aB: color and alpha of backdrop

  // first calculate the color and then alpha, do this for all 3 rectangles
  color.rgb = uColorRect1.rgb * uColorRect1.a * rects.r + color.rgb * color.a * (1 - uColorRect1.a * rects.r);
  color.a = min(rects.r + color.a, 1.0);

  color.rgb = uColorRect2.rgb * uColorRect2.a * rects.g + color.rgb * color.a * (1 - uColorRect2.a * rects.g);
  color.a = min(rects.g + color.a, 1.0);

  color.rgb = uColorRect3.rgb * uColorRect3.a * rects.b + color.rgb * color.a * (1 - uColorRect3.a * rects.b);
  color.a = min(rects.b + color.a, 1.0);

  fragColor = TDOutputSwizzle(color);
}

Of course you could also use the Rectangle TOP and not do any coding as the Output page of the Rectangle TOP allows for specifying the compositing function of the input. :slight_smile:

Hope this makes sense
Markus

Thanks so much Markus, this is brilliant.
I have a lot more processing going on in glsl so need to keep it there. Just couldn’t solve this last stem with overlapping colours properly!
Thank you!

1 Like