MadcoreTom

I plan to write something about voxels here. For now, it's just an opportunity to play with this toy I made. 55kb, minified but not size-optimised

WebGL and Web Component

What did I do to get this working?

Arc Ball rotation

Here I'm using the library gl-matrix. Don't write one yourself, you'll make a mistake.

Write what arc ball rotation is

See also OpenGL Programming: Modern OpenGL Tutorial _Arcball

For each 2d movement of the mouse:

/**
 * Updates the temporary rotation matrix
 */
mouseDrag(start: vec2, end: vec2) {
    const a = this.mouseToVec3(start);
    const b = this.mouseToVec3(end);
    const rotAngle = 2 * Math.acos(Math.min(1.0, vec3.dot(a, b)));
    const rotAxis = vec3.normalize(vec3.create(), vec3.cross(vec3.create(), a, b)); // Normalize may be redundant
    mat4.fromRotation(this.tempRotation, rotAngle, rotAxis);
}

/**
 * Converts a mouse position on screen (-1 to 1) to a 3d point on a unit sphere
 */
private mouseToVec3(mouse: vec2): vec3 {
    const lenSq = mouse[0] * mouse[0] + mouse[1] * mouse[1];
    const v: vec3 = [
        -mouse[0],
        -mouse[1],
        0,
    ];
    if (lenSq <= 1) {
        v[2] = Math.sqrt(1 - lenSq);
    } else {
        vec3.normalize(v, v);
    }
    return v;
}

When you release the mouse

/**
 * Applies the temporary rotation matrix, and clears it
 */
mouseUp() {
    mat4.multiply(this.rotation, this.tempRotation, this.rotation)
    mat4.identity(this.tempRotation);
}

How I render

// ... scaling ect
mat4.multiply(m,m,this.tempRotation);
mat4.multiply(m,m,this.rotation);
// ...
// render my mesh

Voxel lighting

TODO

For each voxel, calculating average of neighbours

For each vertex, sampling +/- 0.5 offsets in the same plane as the face, offset 0.5 in the direction of the face's normal.