Use Discard for Alpha Test

by Gregg Tavares

HTML

<canvas></canvas>
<script type='x-shader/x-vertex'>
  attribute vec3 a_vertex;
  uniform mat4 u_matrix;
  uniform vec2 u_canvas;

  void main() {
    gl_Position = u_matrix * vec4(a_vertex, 1.0);
    gl_PointSize = 1.0 / gl_Position.w * u_canvas.y / 100.0;
  }
</script>
<script type='x-shader/x-fragment'>
  precision mediump float;
  uniform sampler2D u_sampler;

  void main() {
    float alphaThreshold = 0.1;
    vec4 color = texture2D(u_sampler, gl_PointCoord);
    if (color.a <= alphaThreshold) {
      discard;
    }
    gl_FragColor = color;
  }
</script>

CSS

* {
  padding: 0;
  margin: 0;
}

html, body, canvas {
  width: 100%;
  height: 100%;
}

canvas {
  display: block;
  background: #000;
}

JavaScript

var mat4 = {
  create: function () {
    return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
  },
  translate: function(v) {
    return [1, 0, 0, v[0] || 0, 0, 1, 0, v[1] || 0, 0, 0, 1, v[2] || 0, 0, 0, 0, 1];
  },
  scale: function(v) {
    return [v[0] || 1, 0, 0, 0, 0, v[1] || 1, 0, 0, 0, 0, v[2] || 1, 0, 0, 0, 0, 1];
  },
  rotate: function(r, v) {
    var s = Math.sin(r), c = Math.cos(r), C = 1 - c;
    return [
      C * v[0] * v[0] + c, C * v[0] * v[1] - s * v[2], C * v[0] * v[2] + s * v[1], 0,
      C * v[1] * v[0] + s * v[2], C * v[1] * v[1] + c, C * v[1] * v[2] - s * v[0], 0,
      C * v[2] * v[0] - s * v[1], C * v[2] * v[1] + s * v[0], C * v[2] * v[2] + c, 0,
      0, 0, 0, 1
    ];
  },
  perspective: function(fov, aspect, near, far) { 
    fov = Math.tan(fov * Math.PI / 360);
    return [
      1 / (aspect * fov), 0, 0, 0,
      0, 1 / fov, 0, 0,
      0, 0, -(near + far) / (near - far), 2 * far * near / (near - far),
      0, 0, 1, 0
    ];
  },
  xM: function (a, b) {
    return [
      a[ 0] * b[0] + a[ 1] * b[4] + a[ 2] * b[ 8] + a[ 3] * b[12],
      a[ 0] * b[1] + a[ 1] * b[5] + a[ 2] * b[ 9] + a[ 3] * b[13],
      a[ 0] * b[2] + a[ 1] * b[6] + a[ 2] * b[10] + a[ 3] * b[14],
      a[ 0] * b[3] + a[ 1] * b[7] + a[ 2] * b[11] + a[ 3] * b[15],
      a[ 4] * b[0] + a[ 5] * b[4] + a[ 6] * b[ 8] + a[ 7] * b[12],
      a[ 4] * b[1] + a[ 5] * b[5] + a[ 6] * b[ 9] + a[ 7] * b[13],
      a[ 4] * b[2] + a[ 5] * b[6] + a[ 6] * b[10] + a[ 7] * b[14],
      a[ 4] * b[3] + a[ 5] * b[7] + a[ 6] * b[11] + a[ 7] * b[15],
      a[ 8] * b[0] + a[ 9] * b[4] + a[10] * b[ 8] + a[11] * b[12],
      a[ 8] * b[1] + a[ 9] * b[5] + a[10] * b[ 9] + a[11] * b[13],
      a[ 8] * b[2] + a[ 9] * b[6] + a[10] * b[10] + a[11] * b[14],
      a[ 8] * b[3] + a[ 9] * b[7] + a[10] * b[11] + a[11] * b[15],
      a[12] * b[0] + a[13] * b[4] + a[14] * b[ 8] + a[15] * b[12],
      a[12] * b[1] + a[13] * b[5] + a[14] * b[ 9] + a[15] * b[13],
      a[12] * b[2] + a[13] * b[6] + a[14] *...