Skip to content

Instantly share code, notes, and snippets.

@robinhouston
Last active January 7, 2016 00:18
Show Gist options
  • Save robinhouston/37434d5f7af32e968b2e to your computer and use it in GitHub Desktop.
Save robinhouston/37434d5f7af32e968b2e to your computer and use it in GitHub Desktop.
Cubes!
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Cubes!</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 mediump mat3 uTransform;
uniform mediump vec2 uCentre;
void main() {
mediump vec3 b = mod(uTransform * vec3(gl_FragCoord.xy - uCentre, 0), 20.0);
gl_FragColor = vec4(smoothstep(8.5, 9.5, b) * (1.0 - smoothstep(10.5, 11.5, b)), 1);
}
</script>
</head>
<body>
<script>
var dpr = window.devicePixelRatio || 1.0;
if (dpr != 1 && dpr != 2) dpr = 1;
var canvas, gl, prog, uTransform, uCentre;
function getText(selector) {
var el = document.querySelector(selector), 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.viewport(0, 0, canvas.width, canvas.height);
}
function init() {
canvas = document.createElement("canvas");
gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
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);
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(phi, theta) {
var cos_phi = Math.cos(phi),
sin_phi = Math.sin(phi),
cos_theta = Math.cos(theta),
sin_theta = Math.sin(theta);
return [
cos_theta, 0, -sin_theta,
-sin_phi*sin_theta, cos_phi, -sin_phi*cos_theta,
cos_phi*sin_theta, sin_phi, cos_phi*cos_theta
];
}
var initial_timestamp;
function drawFrame(timestamp) {
if (!initial_timestamp) initial_timestamp = timestamp;
var d = (timestamp - initial_timestamp) / 1e4;
gl.uniformMatrix3fv(uTransform, false, rotationMatrix(Math.atan2(1, Math.sqrt(2)) + d, Math.atan(1) + d));
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