Macrae Smith
Key Features
3D procedural world
Biomes and Vegetation
Player Physics Controls
Flowing Water and Lava
Voxel Lighting
TNT and explosion
Simple Miner
Description
Referencing the game Minecraft, I developed a 3D procedural voxel world. I implemented a multi-threaded Job System to handle chunk loading. And added interesting features like flowing water, voxel lighting, and TNT.
Duration: August - December 2025
Technology:
My custom C++ engine
D3D11
HLSL
Multi-Threaded Chunk Generation


Minecraft’s core technical challenge is managing an effectively infinite world. For Simple Miner, I implemented a chunk-based streaming system that loads and unloads world data within a configurable radius around the player. Only spatially relevant data is resident in memory, keeping CPU and memory usage predictable.
The world is partitioned into fixed-size chunks. Because chunk generation is CPU-intensive and heavily procedural, it runs on a multithreaded job system.
Each frame, the main thread performs a flood fill outward from the player’s current chunk to determine the required working set. Missing chunks are scheduled as jobs and dispatched to worker threads. Terrain generation, noise evaluation, and mesh data construction occur entirely off the main thread.
Once a chunk finishes generation, it transitions back to the main thread for integration into the active world, where Update() and Render() are handled. Chunk state transitions are explicitly managed to guarantee thread safety and prevent race conditions during streaming.

Minecraft’s core technical challenge is managing an effectively infinite world. For Simple Miner, I implemented a chunk-based streaming system that loads and unloads world data within a configurable radius around the player. Only spatially relevant data is resident in memory, keeping CPU and memory usage predictable.
The world is partitioned into fixed-size chunks. Because chunk generation is CPU-intensive and heavily procedural, it runs on a multithreaded job system.
Each frame, the main thread performs a flood fill outward from the player’s current chunk to determine the required working set. Missing chunks are scheduled as jobs and dispatched to worker threads. Terrain generation, noise evaluation, and mesh data construction occur entirely off the main thread.
Once a chunk finishes generation, it transitions back to the main thread for integration into the active world, where Update() and Render() are handled. Chunk state transitions are explicitly managed to guarantee thread safety and prevent race conditions during streaming.
Procedural Generation


I built a fully procedural 3D terrain system using layered Perlin, Fractal, Ridged, and domain-warped noise. Different noise stacks are responsible for distinct terrain features, allowing me to control large-scale landforms separately from fine surface detail.
The generation pipeline is structured around three primary noise groups: terrain shaping, caves, and climate. Terrain shaping defines the macro structure of the world, cave noise carves volumetric voids directly into the density field, and climate noise drives biome and material variation.
By separating these concerns, I can tune terrain silhouette, subterranean complexity, and biome distribution independently while still producing a cohesive world.

I built a fully procedural 3D terrain system using layered Perlin, Fractal, Ridged, and domain-warped noise. Different noise stacks are responsible for distinct terrain features, allowing me to control large-scale landforms separately from fine surface detail.
The generation pipeline is structured around three primary noise groups: terrain shaping, caves, and climate. Terrain shaping defines the macro structure of the world, cave noise carves volumetric voids directly into the density field, and climate noise drives biome and material variation.
By separating these concerns, I can tune terrain silhouette, subterranean complexity, and biome distribution independently while still producing a cohesive world.
Terrain Shaping


Base Terrain Layer
The foundation of the world is a 3D density field driven by layered noise. This produces natural overhangs and complex rock formations. A squashing curve is applied to the density function to bias values toward continuity, preventing floating landmasses while preserving vertical variation.
Continentalness
Large-scale 2D noise modulates the base layer to introduce broad elevation offsets. This pass defines macro landmass distribution, forming wide oceans and massive island chains with smooth transitions.
Erosion
A secondary, higher-frequency 2D noise pass subtracts into the continental shapes to carve rivers, canyons, and inlets. This breaks up large landmasses and adds believable geological variation.
Peaks and Valleys
A final 2D noise layer introduces rapid elevation changes. By amplifying local height differentials, this pass creates sharp mountain ranges and deep pits, increasing vertical drama without disrupting overall terrain cohesion.
Once the four of these come together by adding or subtracting from the base terrain height, the result is an interesting and dynamic world with varying features to explore.

Base Terrain Layer
The foundation of the world is a 3D density field driven by layered noise. This produces natural overhangs and complex rock formations. A squashing curve is applied to the density function to bias values toward continuity, preventing floating landmasses while preserving vertical variation.
Continentalness
Large-scale 2D noise modulates the base layer to introduce broad elevation offsets. This pass defines macro landmass distribution, forming wide oceans and massive island chains with smooth transitions.
Erosion
A secondary, higher-frequency 2D noise pass subtracts into the continental shapes to carve rivers, canyons, and inlets. This breaks up large landmasses and adds believable geological variation.
Peaks and Valleys
A final 2D noise layer introduces rapid elevation changes. By amplifying local height differentials, this pass creates sharp mountain ranges and deep pits, increasing vertical drama without disrupting overall terrain cohesion.
Once the four of these come together by adding or subtracting from the base terrain height, the result is an interesting and dynamic world with varying features to explore.
Underground Caves


One of the most compelling parts of Minecraft is its dense, interconnected cave systems. To achieve a similar sense of scale and exploration, I extended my density-based terrain pipeline with additional volumetric noise passes dedicated to subterranean generation.
Cheese Caves
Large-scale 3D noise, biased toward lower world elevations, subtracts directly from the density field to form expansive air pockets and cavern chambers. This creates massive underground voids while maintaining structural continuity above.
Spaghetti Tunnels
Domain-warped ridged noise generates long, winding tunnels that stitch the larger caverns together. The warping introduces natural curvature and variation, preventing linear repetition. In some cases, these tunnels intersect the surface, forming cracks and vertical shafts that organically connect the overworld to the cave network.

One of the most compelling parts of Minecraft is its dense, interconnected cave systems. To achieve a similar sense of scale and exploration, I extended my density-based terrain pipeline with additional volumetric noise passes dedicated to subterranean generation.
Cheese Caves
Large-scale 3D noise, biased toward lower world elevations, subtracts directly from the density field to form expansive air pockets and cavern chambers. This creates massive underground voids while maintaining structural continuity above.
Spaghetti Tunnels
Domain-warped ridged noise generates long, winding tunnels that stitch the larger caverns together. The warping introduces natural curvature and variation, preventing linear repetition. In some cases, these tunnels intersect the surface, forming cracks and vertical shafts that organically connect the overworld to the cave network.
Climate


Temperature and Humidity
Large-scale 2D climate noise drives biome distribution across the world. Temperature and humidity values are sampled per position and blended with terrain elevation to determine biome classification. This allows for smooth transitions between lush plains, arid deserts, frozen oceans, and barren peaks.
Vegetation
Vegetation placement is derived from the same climate field, ensuring ecological consistency. Each biome defines its own spawn rules and density curves, resulting in distinct tree and foliage distributions that reflect local conditions.
Waterfalls
Waterfalls are generated procedurally by evaluating terrain slope and climate data. Steep gradients combined with valid water sources produce flowing cascades that integrate naturally into cliffs and mountain faces, adding motion and visual contrast to the landscape.

Temperature and Humidity
Large-scale 2D climate noise drives biome distribution across the world. Temperature and humidity values are sampled per position and blended with terrain elevation to determine biome classification. This allows for smooth transitions between lush plains, arid deserts, frozen oceans, and barren peaks.
Vegetation
Vegetation placement is derived from the same climate field, ensuring ecological consistency. Each biome defines its own spawn rules and density curves, resulting in distinct tree and foliage distributions that reflect local conditions.
Waterfalls
Waterfalls are generated procedurally by evaluating terrain slope and climate data. Steep gradients combined with valid water sources produce flowing cascades that integrate naturally into cliffs and mountain faces, adding motion and visual contrast to the landscape.
Voxel Lighting


To support dynamic day and night cycles, I implemented a voxel-based lighting system. Light propagation uses a flood fill algorithm seeded from emissive sources and skylight.
Each block face stores a light value representing the accumulated contribution from neighboring voxels. During rendering, this value is sampled in the shader to determine final light intensity and color.

When geometry changes or a block becomes occluded, the lighting system recalculates propagation locally. Light removal and re-spread are handled dynamically, allowing the world to respond in real time as players modify the environment.
To support dynamic day and night cycles, I implemented a voxel-based lighting system. Light propagation uses a flood fill algorithm seeded from emissive sources and skylight.
Each block face stores a light value representing the accumulated contribution from neighboring voxels. During rendering, this value is sampled in the shader to determine final light intensity and color.
Liquid Flood Fill


To make the world feel more alive, I implemented a voxel-based liquid simulation. It uses a flood fill approach similar to the lighting system, but prioritizes gravity and downward propagation. Flow strength is reflected visually by adjusting block height, giving the surface a sense of motion and direction.
The system runs in two stages. During chunk generation on worker threads, liquid sources initialize and propagate within the chunk’s bounds. Once the chunk becomes active, it evaluates neighboring chunks to allow cross-boundary flow and spillover.
By separating generation-time filling from runtime interaction, the system supports both deterministic world creation and dynamic, continuous flow across chunk borders.

To make the world feel more alive, I implemented a voxel-based liquid simulation. It uses a flood fill approach similar to the lighting system, but prioritizes gravity and downward propagation. Flow strength is reflected visually by adjusting block height, giving the surface a sense of motion and direction.
The system runs in two stages. During chunk generation on worker threads, liquid sources initialize and propagate within the chunk’s bounds. Once the chunk becomes active, it evaluates neighboring chunks to allow cross-boundary flow and spillover.
By separating generation-time filling from runtime interaction, the system supports both deterministic world creation and dynamic, continuous flow across chunk borders.
TNT


No voxel world feels complete without destruction. I implemented an explosion system that gathers blocks within a configurable radius and converts them to air in a single operation.
All affected neighbors are queued for lighting and liquid recalculation, ensuring the world updates consistently after terrain modification.
Explosions also interact with the entity physics system. Removed blocks can spawn dynamic entities with applied impulse forces, allowing chain reactions and cascading blasts that propagate naturally through the environment.

No voxel world feels complete without destruction. I implemented an explosion system that gathers blocks within a configurable radius and converts them to air in a single operation.
All affected neighbors are queued for lighting and liquid recalculation, ensuring the world updates consistently after terrain modification.
Explosions also interact with the entity physics system. Removed blocks can spawn dynamic entities with applied impulse forces, allowing chain reactions and cascading blasts that propagate naturally through the environment.