HOW WANDER IS BUILT · LAYER 5 OF 7
Camera, frustum and the one shader.
Wander draws with one terrain shader, one sky shader and one sprite shader, and no textures on the ground. The camera is a perspective matrix and a view matrix from the walker's position, yaw and pitch. Every chunk has a bounding box; six planes from the projection-view matrix cull the boxes that are out of view, and the rest are drawn nearest first. The terrain shader does the weather: the sun's direction and strength, an ambient term, up to four lamps (headlights, street lights, fireballs), a sway on leaves and reeds that grows with the wind, the season's leaf colour, snow above the snow line, cloud shadows drifting from a little value noise, a wet sheen, fog by distance and an aerial haze that pales the far ridges toward the sky. Water is a moving triangle wave in the vertex colour. Emissive faces ignore the sun. The sky is a gradient with the horizon lifted by the pitch, and stars hashed from the pixel at night.
const gl = canvas.getContext("webgl"), G = WanderGL; // gl.js: the WebGL client
const proj = G.perspective(new Float32Array(16), 70*Math.PI/180, canvas.width/canvas.height, 0.1, 3000);
const view = G.view(new Float32Array(16), cam.x, cam.y, cam.z, cam.yaw, cam.pitch);
const planes = G.frustumPlanes(G.mul(new Float32Array(16), proj, view));
for (const mesh of meshes){ // one uploaded mesh per chunk part, with its bounds
if (!G.boxVisible(planes, mesh.bounds)) continue; // six plane tests against the corner furthest along each normal
gl.useProgram(terrain); gl.uniformMatrix4fv(uProj, false, proj); gl.uniformMatrix4fv(uView, false, view);
gl.uniform3f(uSun, sun.x, sun.y, sun.z); gl.uniform1f(uSunStrength, sun.strength); gl.uniform1f(uWind, wx.wind); gl.uniform1f(uCloud, wx.cloud);
gl.bindBuffer(gl.ARRAY_BUFFER, mesh.vbo); /* aPos, aNor, aCol, aFlag at stride 40 */ gl.drawElements(gl.TRIANGLES, mesh.count, gl.UNSIGNED_SHORT, 0);
}
// the weather's numbers come from the almanac: wx = WanderLaw.weatherAt(hour), three bits on their own exact clocksThe shaders are in wander/gl.js, in full; the sky, the sun's path and the almanac are the RangeBlends pages' own (bank.js, law.js). The weather clock is on cards/clocks.md.
← A chunk is a mesh A world has people →
How Wander is built · by Lars Rocha · every layer stands on a law in sitoolz, written twice and checked against one fixture.