0

I have a very simple request from GLSL 330:

if (colorOut.r <= 1.0 && colorOut.r > 0.7)
{
    colorOut.r=*color_1.r;
}

I have over 40 compares like this.

However, this is creating a world of trouble for me, as I've been told AND, NOT, etc statements take a lot of video memory, and I'm developing a plugin for After Effects, and people who happen to use them don't have strong GPUs (for the most part -- I have done a survey and most of them use mobile version of mid-end GPUs). so I thought I'd ask you guys if there's a possible alternative to using AND or even if, because I've been told fragment shaders don't like if in the main branch at all.

Thanks.

Major Despard
  • 95
  • 2
  • 11
  • 2
    You say "AND, NOT etc statements take a lot of video memory". This isn't correct, simple boolean operations don't need any significant amount of memory (if you have many of them, they can take measurable amounts of computing time, but not VRAM). Divergence in your execution paths, like your if statements, can cause significant slowdown when the path that will be taken is not predictable and therefore caching etc can't be utilized efficiently. See [this question](https://stackoverflow.com/questions/9820319/why-is-a-cpu-branch-instruction-slow) (most of it holds for GPU aswell). – AlbertM Feb 28 '19 at 09:09

1 Answers1

0

A multiplexing scenario like yours you can use branchless programming. You could for example use something like this. The boolean operators are "approximated".

colorOut.r = mix(colorOut.r, (colorOut.r*color_1.r), 
    ( clamp(pow(1-colorOut.r, 20), 0, 1)
    * clamp(pow(colorOut.r-0.7, 20), 0, 1) ) );

Note that a ternary usually doesn't cause that much problems and this should be easy on resources, since it doesn't causes diverging branches:

colorOut.r = mix(colorOut.r, (colorOut.r*color_1.r), 
    ( colorOut.r <= 1 && colorOut.r > 0.7 ? 1 : 0 );
datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • So ternary is ok? Good to hear. Thanks. – Major Despard Feb 28 '19 at 08:56
  • @MajorDespard: What matters is, that your program doesn't diverge "too much". Multiplexing between two different calculations usually doesn't diverge, since either calculation comfortably fits into a register. It would be a whole different story, if you'd make different function calls, fetch from different texture locations, and so in. – datenwolf Feb 28 '19 at 09:09