From: Steinar H. Gunderson Date: Thu, 27 Mar 2014 00:38:43 +0000 (+0100) Subject: Add a inverse flag to LumaMixEffect. X-Git-Tag: 1.1~14 X-Git-Url: https://git.sesse.net/?p=movit;a=commitdiff_plain;h=bbbf278f6f2847010a7c41caafa08d36d2099794 Add a inverse flag to LumaMixEffect. This is mainly a convenience so that you can change e.g. a left-to-right wipe into a right-to-left wipe without having to add a separate inverting effect to the luma. Suggested by Dan Dennedy. --- diff --git a/luma_mix_effect.cpp b/luma_mix_effect.cpp index e34d87f..92c599e 100644 --- a/luma_mix_effect.cpp +++ b/luma_mix_effect.cpp @@ -7,10 +7,11 @@ using namespace std; namespace movit { LumaMixEffect::LumaMixEffect() - : transition_width(1.0f), progress(0.5f) + : transition_width(1.0f), progress(0.5f), inverse(0) { register_float("transition_width", &transition_width); register_float("progress", &progress); + register_int("inverse", &inverse); } string LumaMixEffect::output_fragment_shader() @@ -22,6 +23,7 @@ void LumaMixEffect::set_gl_state(GLuint glsl_program_num, const string &prefix, { Effect::set_gl_state(glsl_program_num, prefix, sampler_num); set_uniform_float(glsl_program_num, prefix, "progress_mul_w_plus_one", progress * (transition_width + 1.0)); + set_uniform_int(glsl_program_num, prefix, "inverse", inverse); } } // namespace movit diff --git a/luma_mix_effect.frag b/luma_mix_effect.frag index bf0833e..709d192 100644 --- a/luma_mix_effect.frag +++ b/luma_mix_effect.frag @@ -1,4 +1,5 @@ uniform float PREFIX(progress_mul_w_plus_one); +uniform bool PREFIX(inverse); vec4 FUNCNAME(vec2 tc) { vec4 first = INPUT1(tc); @@ -36,8 +37,11 @@ vec4 FUNCNAME(vec2 tc) { // So clearly, it should move (w+1) units to the right, and apart from that // just stay a simple mapping. float w = PREFIX(transition_width); - float luma = INPUT3(tc).x * w; - float m = clamp((luma - w) + PREFIX(progress_mul_w_plus_one), 0.0, 1.0); + float luma = INPUT3(tc).x; + if (PREFIX(inverse)) { + luma = 1.0f - luma; + } + float m = clamp((luma * w - w) + PREFIX(progress_mul_w_plus_one), 0.0, 1.0); return mix(first, second, m); } diff --git a/luma_mix_effect.h b/luma_mix_effect.h index 8bd3c50..ce890df 100644 --- a/luma_mix_effect.h +++ b/luma_mix_effect.h @@ -2,8 +2,10 @@ #define _MOVIT_LUMA_MIX_EFFECT_H 1 // Fade between two images based on a third monochrome one; lighter pixels -// will be faded before darker pixels. This allows a wide range of different -// video wipes implemented using a single effect. +// will be faded before darker pixels (unless the inverse flag is set, +// in which case darker pixels will be faded before lighter pixels). +// This allows a wide range of different video wipes implemented using +// a single effect. // // Note that despite the name, the third input's _red_ channel is what's used // for transitions; there is no luma calculation done. If you need that, @@ -28,6 +30,7 @@ public: private: float transition_width, progress; + int inverse; // 0 or 1. }; } // namespace movit diff --git a/luma_mix_effect_test.cpp b/luma_mix_effect_test.cpp index 618b733..07829cc 100644 --- a/luma_mix_effect_test.cpp +++ b/luma_mix_effect_test.cpp @@ -96,4 +96,44 @@ TEST(LumaMixEffectTest, SoftWipeHalfWayThrough) { expect_equal(expected_data, out_data, 2, 2); } +TEST(LumaMixEffectTest, Inverse) { + float data_a[] = { + 0.0f, 0.25f, + 0.75f, 1.0f, + }; + float data_b[] = { + 1.0f, 0.5f, + 0.65f, 0.6f, + }; + float data_luma[] = { + 0.0f, 0.25f, + 0.5f, 0.75f, + }; + + EffectChainTester tester(data_a, 2, 2, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR); + Effect *input1 = tester.get_chain()->last_added_effect(); + Effect *input2 = tester.add_input(data_b, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR); + Effect *input3 = tester.add_input(data_luma, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR); + + Effect *luma_mix_effect = tester.get_chain()->add_effect(new LumaMixEffect(), input1, input2, input3); + ASSERT_TRUE(luma_mix_effect->set_float("transition_width", 100000.0f)); + ASSERT_TRUE(luma_mix_effect->set_int("inverse", 1)); + + // Inverse is not the same as reverse, so progress=0 should behave identically + // as HardWipe, ie. everything should be from A. + float out_data[4]; + ASSERT_TRUE(luma_mix_effect->set_float("progress", 0.0f)); + tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR); + expect_equal(data_a, out_data, 2, 2); + + // Lower two from A, the rest from B. + float expected_data_049[] = { + 1.0f, 0.5f, + 0.75f, 1.0f, + }; + ASSERT_TRUE(luma_mix_effect->set_float("progress", 0.49f)); + tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR); + expect_equal(expected_data_049, out_data, 2, 2); +} + } // namespace movit