Hello, (WebGL) Cube!

A rotating cube using WebGL.

by mvgician

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.8.1/gl-matrix-min.js"></script>

CSS

body {
  padding: 0;
  margin: 0;
}

canvas {
  display: block;
}

JavaScript

// canvas stuff
const canvas = document.createElement('canvas')
document.body.appendChild(canvas)
// create a "renderer" (grab the WebGL context)
const gl = canvas.getContext('webgl')
gl.canvas.width = window.innerWidth
gl.canvas.height = window.innerHeight
let aspect = gl.canvas.clientWidth / gl.canvas.clientHeight
gl.viewport(0, 0, gl.canvas.clientWidth, gl.canvas.clientHeight)

// create a "camera" (a view and a projection matrix)
const fov = (45 * Math.PI) / 180 // in radians
const near = 1
const far = 100

const eye = vec3.fromValues(0, 0, 3)
const target = vec3.fromValues(0, 0, 0)
const up = vec3.fromValues(0, 1, 0)

// create matrices
const viewMatrix = mat4.create()
const projectionMatrix = mat4.create()
const quaternion = quat.create()
const rotationMatrix = mat4.create()
const modelViewMatrix = mat4.create()
const modelMatrix = mat4.create()
const normalMatrix = mat4.create()

// perspective matrix
mat4.perspective(projectionMatrix, fov, aspect, near, far)
// view matrix
mat4.lookAt(viewMatrix, eye, target, up)
// rotation matrix
const xRotation = 180 / Math.PI * 0.005
const yRotation = 180 / Math.PI * 0.01
const zRotation = 180 / Math.PI * 0.001
quat.fromEuler(quaternion, xRotation, yRotation, zRotation)
mat4.fromQuat(rotationMatrix, quaternion)

// cube stuff
// thanks mozilla for the vertices, normals and indices
// https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL
// each cube face has four vertices
const positions = [
  // front face
  -0.5, -0.5, 0.5,
  0.5, -0.5, 0.5,
  0.5, 0.5, 0.5,
  -0.5, 0.5, 0.5,
  // back face
  -0.5, -0.5, -0.5,
  -0.5, 0.5, -0.5,
  0.5, 0.5, -0.5,
  0.5, -0.5, -0.5,
  // top face
  -0.5, 0.5, -0.5,
  -0.5, 0.5, 0.5,
  0.5, 0.5, 0.5,
  0.5, 0.5, -0.5,
  // bottom face
  -0.5, -0.5, -0.5,
  0.5, -0.5, -0.5,
  0.5, -0.5, 0.5,
  -0.5, -0.5, 0.5,
  // right face
  0.5, -0.5, -0.5,
  0.5, 0.5, -0.5,
  0.5, 0.5, 0.5,
  0.5, -0.5, 0.5,
  // left face
  -0.5, -0.5, -0.5,
  -0.5,...