OpenShot/libopenshot

Bug Fix: Alpha Mask / Wipe Transition

xotmatrix opened this issue · 4 comments

I'd only started using OpenShot today but it soon become clear that the wipe transitions were not performing correctly. I believe eight or more years ago, when ImageMagick dependencies were removed from OpenShot, the reimplementer of this feature got the order of operations mixed up. Having built such a system myself, I recognized this sort of error. However, being unfamiliar with OpenShot and unable to build it for myself, I can only hope that I have correctly located the source of the problem.

OpenSpot_Mask cpp_regression

This video demonstrates the problem. The first two transitions were rendered with OpenShot using the clock_right_to_left mask. The first is set to the default 3.0 contrast value. The second is set to very high contrast to show that the wipe does not actually progress. The next two transitions implement OpenShot's code in a shader with some small corrections. The wipe progresses as expected.

https://www.youtube.com/watch?v=rdR2LbTWA-o

I'm sorry I can't build this project and submit a proper pull request but I can show you how to fix it in a way that performs correctly. It looks virtually the same for the default 3.0 contrast value. At maximum contrast 20.0 the wipe edge is sharp.

// Adjust the contrast
float factor = (259 * (contrast_value + 255)) / (255 * (259 - contrast_value));
gray_value = constrain((factor * (gray_value - 128)) + 128);
// Adjust the brightness
gray_value += (255 * brightness_value);
// Constrain the value from 0 to 255
gray_value = constrain(gray_value);
// Calculate the % change in alpha
float alpha_percent = float(constrain(A - gray_value)) / 255.0;

    // Adjust the brightness
    gray_value += (255 * brightness_value);
    
    // Adjust the contrast
    float factor = (20 / (20 - contrast_value));
    gray_value = (factor * (gray_value - 128) + 128);
    
    // Calculate the % change in alpha
    float alpha_percent = float(constrain(A - gray_value)) / 255.0;

This HTML5/WebGL demonstration shows the corrected code in operation with several OpenShot alpha masks. It can be interacted with in a variety of ways.

https://xotmatrix.github.io/demos/gradient-mask-transition/

Note: Some of the alpha mask images in openshot-qt/src/transitions/extra/ are low-resolution and heavily compressed and should be remastered to look their best.

Thanks @xotmatrix! Good catch! This works well, except for values 20.0 and above, which makes the image completely transparent (I think)... haven't dug into this very deeply yet.

Ahhh, found it. 20.0 causes a divide by error / infinity error. I'll add a small constraint around this to prevent it.

Oh, of course. I should have seen that. Glad it works. 👍