![[raym.webp]] After years of writing code that runs behind APIs and dashboards, I wanted to get back to something visual and tactile. ==Raym== is a small playground I built to explore real-time terrain generation in ==C== with [Raylib](https://www.raylib.com/), using the classic [Marching Cubes](https://en.wikipedia.org/wiki/Marching_cubes) algorithm to turn a scalar field into a smooth polygon mesh you can walk around and reshape. # Motivations I love low-level graphics work. I had already played with OpenGL back in the [[A not so classic Chip8 emulator|Chip8 emulator days]], but this time I wanted to skip most of the boilerplate and focus on the _fun_ part: the algorithm, the feedback loop, the feeling of sculpting a world in real-time. Raylib turned out to be a great fit — it gets out of the way and lets you write straight C without ceremony. # Voxels, scalar fields, and marching cubes Under the hood, the world is a 3D grid of scalar values — a ==scalar field==. Each voxel stores a density, and the surface of the terrain is implicitly defined as the iso-surface where that density crosses a given threshold. The Marching Cubes algorithm walks through every cell of the grid, looks at the 8 corner values, and picks one of 256 possible triangulations from a lookup table. The triangle vertices are linearly interpolated between corners to produce a smooth surface — no staircasing, no blocky Minecraft look. ```c typedef struct { Vector3 position; float value; } VoxelCorner; // For each cell, compute a bitmask of which corners are "inside" // the surface, then look up the triangles from the edge table. int cube_index = 0; for (int i = 0; i < 8; i++) { if (corners[i].value < iso_level) cube_index |= (1 << i); } ``` The density field itself is seeded with ==3D Perlin noise== layered at multiple octaves, which gives nice rolling hills, overhangs, and caves more or less for free. # Interactive modification The part I found most satisfying is the editing loop. You can cast a ray from the camera, find where it hits the surface, and then _add_ or _subtract_ density around that point — essentially sculpting the terrain in real time. The marching cubes mesh for the affected chunks is rebuilt on the fly. A few tricks help keep it responsive: - the world is split into ==chunks==, so only the dirty ones get re-meshed; - normals are computed from the gradient of the scalar field rather than from triangle faces, which keeps shading smooth across chunk boundaries; - the brush applies a falloff curve so edits feel _soft_ rather than stamped. # What I learned Writing this in plain C was a deliberate choice. It forced me to think carefully about memory layout, chunk ownership, and the boundary conditions between neighbouring chunks — issues you can handwave away in higher-level languages. The Marching Cubes lookup table also has a special kind of elegance: a dense piece of data that encodes a surprisingly deep geometric truth. It’s the kind of project that doesn’t ship to production and doesn’t need to. It scratches the itch, keeps my graphics intuition sharp, and reminds me why I fell in love with programming in the first place. --- Back to [[Home]] · see also [[A not so classic Chip8 emulator]] · or browse my [[Resume]].