I have two RGBA colors in linear [0..1] space, src and dst and I want to alpha blender src over/under dst n times. Of course, I could call the respective operation n times using the result from the previous one (which is what I am currently doing), but I want to optimize it into a single operation. I think just calculating the correct alpha on src should be sufficient, but I may be wrong. Here's what I currently use:
public static final Color alphaOver(Color dst, Color src) {
float src1A = 1 - src.a;
float outA = src.a + dst.a * src1A;
if (outA == 0)
return Color.TRANSPARENT;
return new Color(
outA,
(src.r * src.a + dst.r * dst.a * src1A) / outA,
(src.g * src.a + dst.g * dst.a * src1A) / outA,
(src.b * src.a + dst.b * dst.a * src1A) / outA);
}
public static final Color alphaUnder(Color dst, Color src) {
return alphaOver(src, dst);
}
public static final Color alphaOver(Color dst, Color src, int times) {
Color ret = dst;
for (int i = 0; i < times; i++)
ret = alphaOver(ret, src);
return ret;
}
public static final Color alphaUnder(Color dst, Color src, int times) {
Color ret = dst;
for (int i = 0; i < times; i++)
ret = alphaUnder(ret, src);
return ret;
}
How can I optimize the last two functions?
srcof the next one? As I understand it, I would put it intodstinstead. This lines up with some quick tests of the final equation with blacksrc, whitedstand an a>0. Overlaying black over white should darken the color but+ dstprevents this. – piegames Sep 07 '18 at 20:43dstis the correct thing to do here. If you imagine doingnseparate blends on top of each other, thesrcwould be the same for all, and result of each blend would be the following blend'sdst. I think you should be able to simplify the result to a single blend using alpha of1 - (1 - a)^nthough. (Try defining a new variableb = 1 - a, and repeating the derivation you used for the first part of the answer.) – Nathan Reed Sep 08 '18 at 02:37dst := (1 - b)*src + b*dst, and then rewrite that assrc + b*(dst - src). Then it works out similarly to your original derivation. :) – Nathan Reed Sep 08 '18 at 05:48srcin that sum, to avoid multiplicating withsrcn times and reduce it to once at the end? Because if so, this becomes a geometric series which can be optimized even further. – piegames Sep 08 '18 at 08:09