0

My application fades between various media and text layers by adjusting their alpha values. However, when using a linear crossfade the brightness appears to "dip" halfway through and then fade back up. After some searching I found this answer that explains the issue, however the suggested solution, fading only one layer at a time, won't work for me since most of the layers I use already contain transparency.

Here's an example of the issue I'm having, in HTML/CSS (code below because SO requires it.

<style>
body, html {
  width: 100%;
  height: 100%;
  margin: 0;
  background-color: black;
}

.example {
  position: absolute;
  width: 100%;
  height: 100%;
  opacity: 0;
}

#example1 {
    background-color: red;
    animation: 1s linear 0s fade infinite alternate;
}

#example2 {
    background-color: red;
    animation: 1s linear 1s fade infinite alternate;
}

@keyframes fade {
  from {opacity: 0;}
  to {opacity: 1;}
}
</style>


<div id="example1" class="example"></div>
<div id="example2" class="example"></div>

The two divs should fade their opacities back in forth, resulting in a solid red image the entire time. Instead, it appears to dip in brightness.

What is the algorithm or formula for creating a smooth crossfade using alpha? I'm using OpenGL, if that's relevant. (The HTML/CSS snippet was just the easiest way of demonstrating the issue).

Community
  • 1
  • 1
Hunter Smith
  • 148
  • 1
  • 9
  • So how do you display transparent regions? That's the color you need to blend to. Or yet better. Also blend the alpha channel. – Nico Schertler Jul 21 '16 at 20:26
  • The transparent areas have alpha set to 0. I'm only adjusting the alpha channel, not any of the others. – Hunter Smith Jul 21 '16 at 20:54
  • It seems, you might just want to use `GL_CONSTANT_ALPHA` and `GL_ONE_MINUS_CONSTANT_ALPHA` for the blending function. And specify the fading time with `glBlendColor`. – Nico Schertler Jul 21 '16 at 20:59

2 Answers2

2

Sorry, but it's not possible.

First off, the equation you want is defined here. I'll copy it here in other terms:

outputColor = overAlpha * overColor + (1 - overAlpha) * underColor

If I understand your question correctly, you're looking for a periodic function f(t) for your alpha transition such that:

1 = f(t - 1) + (1 - f(t)) * f(t - 1) = f(t - 1) + f(t) - f(t - 1) * f(t)

The only function that satisfies that equation, at least according to wolfram alpha is the constant 1. And that won't work if you want it to be zero at the beginning, and have it loop infinitely.

Unless you don't want a periodic function, and you just want your fades to look kinda nice. The equation linked above.

Community
  • 1
  • 1
Larry B.
  • 753
  • 6
  • 21
  • Thanks for the explanation, I ended up using a cubic bezier timing function like CSS uses for animations, it looks good enough for my purposes. – Hunter Smith Jul 22 '16 at 17:10
0

There is some good discussion of this topic at this other question.

It's true that there is no perfect solution, other than a step function, but you can mitigate the effects somewhat. The important thing is to have easing functions that cross at a relatively "high" point, rather than at 0.5. See graphs at this answer.

jwd
  • 10,837
  • 3
  • 43
  • 67