Created
April 5, 2015 19:52
-
-
Save gre/f3efcede1d084f324568 to your computer and use it in GitHub Desktop.
wip refactoring of glsl-transition
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var baboon = require("baboon-image"); | |
var lena = require("lena"); | |
var createTexture = require("gl-texture2d"); | |
var createTransition = require("./glsl-transition"); | |
// from "glsl-transitions" | |
var CubeTransition = { | |
"id" : "ee15128c2b87d0e74dee", | |
"name" : "cube", | |
"owner" : "gre", | |
"glsl" : "#ifdef GL_ES\nprecision highp float;\n#endif\nuniform sampler2D from, to;\nuniform float progress;\nuniform vec2 resolution;\n\nuniform float persp;\nuniform float unzoom;\nuniform float reflection;\nuniform float floating;\n\nvec2 project (vec2 p) {\n return p * vec2(1.0, -1.2) + vec2(0.0, -floating/100.);\n}\n\nbool inBounds (vec2 p) {\n return all(lessThan(vec2(0.0), p)) && all(lessThan(p, vec2(1.0)));\n}\n\nvec4 bgColor (vec2 p, vec2 pfr, vec2 pto) {\n vec4 c = vec4(0.0, 0.0, 0.0, 1.0);\n pfr = project(pfr);\n if (inBounds(pfr)) {\n c += mix(vec4(0.0), texture2D(from, pfr), reflection * mix(1.0, 0.0, pfr.y));\n }\n pto = project(pto);\n if (inBounds(pto)) {\n c += mix(vec4(0.0), texture2D(to, pto), reflection * mix(1.0, 0.0, pto.y));\n }\n return c;\n}\n\n// p : the position\n// persp : the perspective in [ 0, 1 ]\n// center : the xcenter in [0, 1] \\ 0.5 excluded\nvec2 xskew (vec2 p, float persp, float center) {\n float x = mix(p.x, 1.0-p.x, center);\n return (\n (\n vec2( x, (p.y - 0.5*(1.0-persp) * x) / (1.0+(persp-1.0)*x) )\n - vec2(0.5-distance(center, 0.5), 0.0)\n )\n * vec2(0.5 / distance(center, 0.5) * (center<0.5 ? 1.0 : -1.0), 1.0)\n + vec2(center<0.5 ? 0.0 : 1.0, 0.0)\n );\n}\n\nvoid main() {\n vec2 op = gl_FragCoord.xy / resolution.xy;\n float uz = unzoom * 2.0*(0.5-distance(0.5, progress));\n vec2 p = -uz*0.5+(1.0+uz) * op;\n vec2 fromP = xskew(\n (p - vec2(progress, 0.0)) / vec2(1.0-progress, 1.0),\n 1.0-mix(progress, 0.0, persp),\n 0.0\n );\n vec2 toP = xskew(\n p / vec2(progress, 1.0),\n mix(pow(progress, 2.0), 1.0, persp),\n 1.0\n );\n if (inBounds(fromP)) {\n gl_FragColor = texture2D(from, fromP);\n }\n else if (inBounds(toP)) {\n gl_FragColor = texture2D(to, toP);\n }\n else {\n gl_FragColor = bgColor(op, fromP, toP);\n }\n}", | |
"uniforms" : { | |
"persp" : 0.7, | |
"unzoom" : 0.3, | |
"reflection" : 0.4, | |
"floating" : 3.0 | |
} | |
}; | |
var transition; | |
var from, to; | |
var shell = require("gl-now")(); | |
shell.on("gl-init", function() { | |
var gl = shell.gl; | |
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); | |
transition = createTransition(gl, CubeTransition.glsl); | |
to = createTexture(gl, baboon.transpose(1, 0)); | |
from = createTexture(gl, lena.transpose(1, 0)); | |
}); | |
shell.on("gl-render", function () { | |
transition.render((Date.now() / 1000) % 1, from, to, CubeTransition.uniforms); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var createShader = require("gl-shader"); | |
var vertexShader = 'attribute vec2 position; void main() { gl_Position = vec4(2.0*position-1.0, 0.0, 1.0);}'; | |
/** | |
* A GLSL Transition is a fragment shader that MUST have 4 uniforms: | |
* uniform sampler2D from, to; | |
* uniform float progress; | |
* uniform vec2 resolution; | |
* | |
* A GLSL Transition draws a transition between from and to textures | |
* when progress moves between 0 and 1. | |
* | |
* A GLSL Transition is allowed (and encouraged) to have extra uniforms. | |
*/ | |
function GlslTransition (gl, fragmentShader) { | |
this.gl = gl; | |
this.shader = createShader(gl, vertexShader, fragmentShader); | |
this.buffer = gl.createBuffer(); | |
} | |
GlslTransition.prototype = { | |
dispose: function () { | |
this.shader.dispose(); | |
this.gl.deleteBuffer(this.buffer); | |
this.gl = null; | |
this.shader = null; | |
this.buffer = null; | |
}, | |
render: function (progress, from, to, extraUniforms) { | |
var gl = this.gl; | |
var shader = this.shader; | |
var unit = 0; | |
shader.bind(); | |
this._checkViewport(); | |
shader.uniforms.progress = progress; | |
shader.uniforms.from = from.bind(unit++); | |
shader.uniforms.to = to.bind(unit++); | |
for (var key in extraUniforms) { | |
var value = extraUniforms[key]; | |
if (value && value.bind) { | |
shader.uniforms[key] = value.bind(unit++); | |
} | |
else if (shader.uniforms[key] !== value) { | |
shader.uniforms[key] = value; | |
} | |
} | |
gl.drawArrays(gl.TRIANGLES, 0, 6); | |
}, | |
_checkViewport: function () { | |
var gl = this.gl; | |
var canvas = gl.canvas; | |
var w = canvas.width, h = canvas.height; | |
if (this._w!==w || this._h!==h) { | |
this._syncViewport(w, h); | |
this._w = w; | |
this._h = h; | |
} | |
}, | |
_syncViewport: function (w, h) { | |
var gl = this.gl; | |
var shader = this.shader; | |
var buffer = this.buffer; | |
var x1 = 0, x2 = w, y1 = 0, y2 = h; | |
shader.uniforms.resolution = new Float32Array([ w, h ]); | |
gl.bindBuffer(gl.ARRAY_BUFFER, buffer); | |
shader.attributes.position.pointer(); | |
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ | |
x1, y1, | |
x2, y1, | |
x1, y2, | |
x1, y2, | |
x2, y1, | |
x2, y2 | |
]), gl.STATIC_DRAW); | |
gl.viewport(x1, y1, x2, y2); | |
} | |
}; | |
module.exports = function createTransition (gl, fragmentShader) { | |
return new GlslTransition(gl, fragmentShader); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment