WebVfx  0.4.4-44-ga54b093
 All Classes Namespaces Functions Variables Enumerations Enumerator Pages
examples/transition-shader-crosszoom.html

This is an example MLT transition implemented in HTML. It uses the WebVfx WebGL shader support framework to implement a 2D transition using GLSL. The rendered video can be viewed here demo/mlt/mlt_transition_shader_crosszoom_html

<html>
<head>
<style type="text/css">
body, html {
margin: 0;
width: 100%;
height: 100%;
}
#canvas {
width: 100%;
height: 100%;
}
</style>
<script type="text/javascript" src="qrc:/webvfx/scripts/shaderkit.js"></script>
<script type="text/javascript" src="qrc:/webvfx/scripts/easing.js"></script>
<script type="text/javascript">
function CrossZoom() {
this.renderer = new ShaderKit.Renderer(document.getElementById("canvas"));
this.shader = new ShaderKit.Shader(this.renderer,
ShaderKit.Shader.loadShader("crossZoom"));
// 0->1.0
var strength = webvfx.getNumberParameter("Strength");
// Mirrored sinusoidal loop. 0->strength then strength->0
this.easeStrength = new WebVfx.Easing.Sinusoidal(0, strength, 0.5);
this.easeDissolve = new WebVfx.Easing.Exponential(0, 1, 1);
// Linear interpolate center across center half of the image
this.easeCenter = new WebVfx.Easing.Linear(0.25, 0.5, 1);
}
CrossZoom.prototype.render = function (time) {
var shader = this.shader;
shader.updateUniform("sourceTex",
webvfx.getImage('sourceImage').toImageData());
shader.updateUniform("targetTex",
webvfx.getImage('targetImage').toImageData());
shader.updateUniform("strength", this.easeStrength.easeInOut(time));
shader.updateUniform("dissolve", this.easeDissolve.easeInOut(time));
shader.updateUniform("center", [this.easeCenter.ease(time), 0.5]);
this.renderer.render(shader);
}
function init() {
try {
resize();
var crossZoom = new CrossZoom();
webvfx.renderRequested.connect(crossZoom, CrossZoom.prototype.render);
webvfx.imageTypeMap = { "sourceImage" : webvfx.SourceImageType,
"targetImage" : webvfx.TargetImageType };
webvfx.readyRender(true);
} catch (e) {
console.warn(e);
webvfx.readyRender(false);
}
}
function resize() {
var canvas = document.getElementById("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
window.addEventListener("load", init, false);
window.addEventListener("resize", resize, false);
</script>
<!-- Based on https://github.com/evanw/glfx.js/blob/master/src/filters/blur/zoomblur.js -->
<script id="crossZoom" type="x-shader/x-fragment">
precision mediump float;
varying vec2 texCoord;
uniform sampler2D sourceTex;
uniform sampler2D targetTex;
uniform float dissolve;
uniform float strength;
uniform vec2 center;
/* random number between 0 and 1 */
float random(in vec3 scale, in float seed) {
/* use the fragment position for randomness */
return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);
}
vec3 crossFade(in vec2 uv) {
return mix(texture2D(sourceTex, uv).rgb,
texture2D(targetTex, uv).rgb,
dissolve);
}
void main() {
vec3 color = vec3(0.0);
float total = 0.0;
vec2 toCenter = center - texCoord;
/* randomize the lookup values to hide the fixed number of samples */
float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);
for (float t = 0.0; t <= 40.0; t++) {
float percent = (t + offset) / 40.0;
float weight = 4.0 * (percent - percent * percent);
color += crossFade(texCoord + toCenter * percent * strength) * weight;
total += weight;
}
gl_FragColor = vec4(color / total, 1.0);
}
</script>
</head>
<body>
<canvas id="canvas"></canvas>
</body>
</html>