Skip to content

Instantly share code, notes, and snippets.

@robinhouston
Created December 29, 2015 00:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robinhouston/c460b56c79639a0d6b58 to your computer and use it in GitHub Desktop.
Save robinhouston/c460b56c79639a0d6b58 to your computer and use it in GitHub Desktop.
More Moiré
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Moiré patterns</title>
<style>
html { overflow: hidden; }
html, body, canvas { height: 100%; margin: 0; }
</style>
<script id="vertex-shader" type="x-shader">
attribute vec2 aPos;
void main() {
gl_Position = vec4(aPos, 0, 1);
}
</script>
<script id="fragment-shader" type="x-shader">
uniform sampler2D uTexture;
uniform mediump mat2 uTransform;
uniform mediump vec2 uCentre;
const mediump float SCALE = 40.0;
void main() {
mediump vec4 a, b;
mediump vec2 p = gl_FragCoord.xy - uCentre;
a = texture2D(uTexture, p / SCALE);
b = texture2D(uTexture, (uTransform * p) / SCALE);
gl_FragColor = a * b;
}
</script>
</head>
<body>
<script>
var dpr = window.devicePixelRatio || 1.0;
if (dpr != 1 && dpr != 2) dpr = 1;
function getText(selector) {
var el = document.querySelector(selector);
var t = "";
for (var c = el.firstChild; c; c = c.nextSibling) {
t += c.textContent;
}
return t;
}
function makeShader(shader_type, selector) {
var shader = gl.createShader(shader_type);
gl.shaderSource(shader, getText(selector));
gl.compileShader(shader);
return shader;
}
function setSize() {
canvas.width = document.body.clientWidth * dpr;
canvas.height = document.body.clientHeight * dpr;
gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
gl.viewport(0, 0, canvas.width, canvas.height);
}
function makeTexture() {
var texture_canvas = document.createElement("canvas");
texture_canvas.width = 32 * dpr;
texture_canvas.height = 32 * dpr;
var texture_cx = texture_canvas.getContext("2d");
texture_cx.fillStyle = "white";
texture_cx.fillRect(0, 0, 32 * dpr, 32 * dpr);
texture_cx.fillStyle = "#225";
texture_cx.fillRect(0, 0, 16 * dpr, 16 * dpr);
texture_cx.fillStyle = "#522";
texture_cx.fillRect(16 * dpr, 16 * dpr, 16 * dpr, 16 * dpr);
return texture_canvas;
}
var canvas, gl, prog, uTransform, uCentre;
function init() {
canvas = document.createElement("canvas");
document.body.appendChild(canvas);
setSize();
prog = gl.createProgram();
var vertex_shader = makeShader(gl.VERTEX_SHADER, "#vertex-shader");
var fragment_shader = makeShader(gl.FRAGMENT_SHADER, "#fragment-shader");
gl.attachShader(prog, vertex_shader);
gl.attachShader(prog, fragment_shader);
gl.linkProgram(prog);
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, makeTexture());
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ -1,-1, 1,-1, -1,1, 1,1 ]), gl.STATIC_DRAW);
var aPos = gl.getAttribLocation(prog, "aPos");
gl.enableVertexAttribArray(aPos);
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0);
gl.useProgram(prog);
uTransform = gl.getUniformLocation(prog, "uTransform");
uCentre = gl.getUniformLocation(prog, "uCentre");
}
function rotationMatrix(theta) {
var s = Math.sin(theta), c = Math.cos(theta);
var scale_factor = 1.0;
return [ c * scale_factor, s * scale_factor, -s * scale_factor, c * scale_factor ];
}
var initial_timestamp;
function drawFrame(timestamp) {
if (!initial_timestamp) initial_timestamp = timestamp;
var dt = timestamp - initial_timestamp;
var theta = 1e-4 * dt;
gl.uniformMatrix2fv(uTransform, false, rotationMatrix(theta));
gl.uniform2f(uCentre, canvas.width/2, canvas.height/2);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
requestAnimationFrame(drawFrame);
}
window.onresize = setSize;
init();
requestAnimationFrame(drawFrame);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment