The Sniper Scope filter I’ve produced I developed from scratch by writing a fragment shader using OpenGL Shader Language (GLSL) and Javascript using a “lens formula” algorithm.
It is quite fiddly doing this as debugging a shader program is like pulling hens’ teeth and optimising the code to make it run faster is quite tortuous e.g to optmise the following code to run twice as fast on the parallel processing GPU:
vec2 new_xy = rr < SD ? xy * (R - hr) / sqrt(R * R - rr * rr) : xy;
return getFromColor(SC.xy + new_xy);
I had to come up with:
float rr_lt_SD = when_lt(rr, SD);
float RR_gt_rr = when_gt(R , rr);
float sqrt_arg = not(RR_gt_rr) * 1.0 + RR_gt_rr * (R * R - rr * rr); // prevent sqrt of -ve number error
vec4 colr = getFromColor(SC.xy + not(rr_lt_SD) * xy + rr_lt_SD * xy * (R - hr) * inversesqrt(sqrt_arg));
Now that the code is complete I have very easily incorporated it the “transitions framework” I put together (see: GL Transitions made using Elusien's GL transitions overlay generator). I am now creating the QML front-end to enable it to be used as a strightforward Shotcut filter with all the keyframe bells and whistles, but this is not so simple.