WebGL Masking
Masking content using the `FUNC_REVERSE_SUBTRACT` blend equation.
HTML
<script src="https://rawgithub.com/toji/gl-matrix/master/dist/gl-matrix-min.js"></script>
<script src="https://rawgithub.com/soulwire/sketch.js/master/js/sketch.min.js"></script>
<label>
<input id="mask-cb" type="checkbox" checked>Mask
</label>
CSS
html, body {
font-family: Courier;
font-size: 13px;
background: #ccc;
overlay: hidden;
margin: 0;
}
JavaScript
var GLU = (function () {
var unit = 0;
function defaults(target, source) {
for (var key in source)
if (!target.hasOwnProperty(key))
target[key] = source[key];
return target;
}
function shader(gl, source, type) {
var shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
throw gl.getShaderInfoLog(shader);
return shader;
}
function program(gl, vertexSource, fragmentSource, attributes, uniforms) {
var vs = shader(gl, vertexSource, gl.VERTEX_SHADER);
var fs = shader(gl, fragmentSource, gl.FRAGMENT_SHADER);
var program = gl.createProgram();
gl.attachShader(program, vs);
gl.attachShader(program, fs);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS))
throw gl.getProgramInfoLog(program);
if (attributes) for (var i = 0; i < attributes.length; i++)
program[attributes[i]] = gl.getAttribLocation(program, attributes[i]);
if (uniforms) for (var i = 0; i < uniforms.length; i++)
program[uniforms[i]] = gl.getUniformLocation(program, uniforms[i]);
gl.useProgram(program);
return program;
}
function vbo(gl, index, data, options) {
options = defaults(options || {}, {
type: gl.STATIC_DRAW,
size: 3
});
var vbo = gl.createBuffer();
vbo.bind = function () {
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
gl.vertexAttribPointer(index, options.size, gl.FLOAT, false, 0, 0);
};
vbo.bind();
gl.bufferData(gl.ARRAY_BUFFER, data, options.type);
gl.enableVertexAttribArray(index);
return vbo;
}
return {
program: program,
shader: shader,
vbo: vbo
};
})();
var gl = Sketch.create({
...