A real-time procedurally generated infinite terrain renderer built with WebGPU and TypeScript, featuring dynamic water, Phong lighting, and distance-based fog. All terrain generation happens in the vertex shader, avoiding CPU-to-GPU data transfers.
The terrain mesh is a flat 800×800 grid of vertices spanning 16×16 units, generated on the CPU. Adjacent vertices are connected into triangles, producing approximately 1.27 million triangles. The actual height displacement is applied in the vertex shader.
Terrain height uses fractal Perlin noise (5 octaves) computed in the vertex shader. Each octave doubles the frequency while reducing amplitude by 70%, creating both large-scale features and fine detail. Height values map to biome colors: water, sand, grass, stone, and snow, with smooth interpolation between adjacent biomes.
Surface normals are computed using finite differences—sampling heights at small offsets and taking the cross product of the resulting tangent vectors. The fragment shader applies Phong diffuse lighting using a fixed directional light source.
Rather than moving the camera through terrain, the camera stays fixed at the origin while terrain coordinates are offset by the camera's logical position before sampling noise. This creates infinite terrain without regenerating geometry—the same mesh samples different regions of the procedural noise as the player moves.
Distance-based fog blends distant terrain into the sky color using smoothstep interpolation. Terrain beyond 8 units fades completely into the background, creating depth perception and hiding mesh edges.
Areas below the water threshold render as animated waves instead of terrain. Waves are generated by summing multiple sine functions with varying frequencies and time-based phase shifts. Water normals are computed dynamically, giving realistic lighting that shifts with wave motion.