↰ Geodesic Polyhedrons

Rendering Points with WebGL

WebGL rendered sphere, points calculated in JS

Last time, I rendered points using HTML5's 2D canvas API. Profiling showed that the number of points I could render was limited by the performance of this drawing API - here I swap it out with WebGL.

I've used WebGL via three.js and Kinc (specifically the Wasm/WebGL backend), but never directly. WebGL 2 Fundamentals is my primary guide.

Above I do a very minimal migration to Web GL 2 - all (camera/projection) transformations are still done in JS on the CPU (as opposed to in a vertex shader on the GPU), GL_POINTS is used to specify how the vertices are rasterised, and (because we compute transformations in JS) we recalculate the vertex buffer every frame.

This simplicity is reflected in the minimal shaders. The only noteworthy code is the uniform vec4 pixelColor. I use this to set the point colour when the browsers dark mode is toggled. I could compile the fragment shader dynamically so the colour is a constant - I do want to experiment with more dynamic shader compilation, but not today.

Vertex Shader
#version 300 es

in vec2 pos;

void main() {
  gl_Position = vec4(pos, 0, 1);
}
Fragment Shader
#version 300 es
precision highp float;

uniform vec4 pixelColor;
out vec4 outColor;

void main() {
  outColor = pixelColor;
}

Point Projection in the vertex shader

WebGL rendered sphere, points calculated in vertex shader

Next, I naturally moved the multiplication of the camera/projection matrix and the vertices to the vertex shader.

Vertex Shader, now accepting a transformation matrix
#version 300 es

in vec3 pos;
uniform mat4 mat;

void main() {
  gl_Position = vec4(pos, 1.0) * mat;
}

I was stumped on this for awhile as I had incorrectly setup the matrix in the vertex shader - it wasn't marked as a uniform mat4 even though my JS was looking for one.

Debugging WebGL in general is frustrating. On native platforms, renderdoc is a fantastic tool for digging into graphics calls across a frame, and I couldn't find anything nearly as good for WebGL. Spectre JS was something, but doesn't seem to show any buffer or uniform data. WebGL-Inspector looks like it has everything I was after, but unfortunately seems to have been abadoned. I might give it more of a go if I run into issues in the future.

Aside

The author of webgl fundamentals operates a fascinating site, vertexshaderart, which is to vertex shaders what shadertoy is to fragment shaders. There are some amazing shaders to browse. Using a vertex shader to compute vertex positions, based on based data like the vertex index, sounds like a challenging, low performance approach, but generating the points with a non-recursive (and ideally non-iterative) algorithm sounds interesting.