The Voxel Sphere Algorithm: From Math to Minecraft Layers

If you've ever tried to build a sphere in Minecraft, you know the pain. You start with a circle, stack layers, and hope it looks round. But a sphere isn't a stack of circles — it's a continuous surface approximated in a blocky grid. Get the layers wrong, and your sphere looks like a squashed potato.
I built a free, browser-based Minecraft Sphere Generator that creates perfect voxel spheres with layer‑by‑layer blueprints. The tool is used by thousands of Minecraft builders, server owners, and content creators. But behind that simple interface is an elegant geometric algorithm that solves a surprisingly hard problem: how do you represent a mathematically perfect sphere in a discrete 3D grid of blocks?
This article dives into the math, the code, and the engineering decisions behind it.
The Problem: A Sphere in a Block World A sphere is defined by the equation:
text x² + y² + z² = r² In continuous space, every point on the sphere satisfies this equation. But Minecraft doesn't have continuous space — it has blocks. Each block occupies one unit of volume, centred on integer coordinates.
The challenge is: for a given radius, which blocks should be filled?
The naive approach is to iterate over every block in the bounding cube and check if its centre is within the sphere:
javascript for (let x = -r; x <= r; x++) { for (let y = -r; y <= r; y++) { for (let z = -r; z <= r; z++) { if (xx + yy + zz <= rr) { // place block } } } } This works, but it creates a solid sphere. And it's inefficient if you only need the surface.
The Voxelisation Algorithm
To build a surface sphere (hollow), you need to identify which blocks are on the surface and which are inside. Here's where the algorithm gets interesting.
Instead of checking each block individually, we can iterate by layers.
Step 1: Iterate Over Layers :
A sphere's layers are horizontal slices. At each height y, the cross-section is a circle with radius text layerRadius = sqrt(r² - y²)
Step 2: Generate a Circle for Each Layer
For each circle, we need to generate all blocks that lie on its perimeter. This is the same problem as drawing a circle on a grid, but in 3D.
A circle of radius layerRadius centered at (0, y, 0) is defined by:
text x² + z² = layerRadius² For each x from -layerRadius to layerRadius, we calculate z = sqrt(layerRadius² - x²). This gives us the boundary.
However, this approach only gives us the outermost blocks of the circle. To fill the circle completely (for a solid sphere), we'd also fill all z values between -z and z.
Step 3: The Two‑Pass Approach
For a hollow sphere, we need to find the blocks that are on the surface, not inside. A block is on the surface if:
It is within the sphere (distance ≤ radius).
At least one of its six neighbours is outside the sphere.
This is the classic surface extraction algorithm. The final implementation follows this logic in a single pass:
javascript function isOnSurface(x, y, z, radius) { const dist = xx + yy + zz; const rSq = radius * radius; // Inside the sphere if (dist > rSq) return false; // Check all 6 neighbours const neighbours = [ [1,0,0], [-1,0,0], [0,1,0], [0,-1,0], [0,0,1], [0,0,-1] ]; for (const [dx, dy, dz] of neighbours) { const nx = x + dx; const ny = y + dy; const nz = z + dz; const ndist = nxnx + nyny + nznz; if (ndist > rSq) return true; } return false; } This ensures that only the outer layer of blocks is selected.
Hollow vs. Solid Spheres
The tool supports both hollow and solid spheres.
For a solid sphere, the algorithm checks if the block's centre is within the sphere:
javascript function isInside(x, y, z, radius) { return xx + yy + z*z <= radius * radius; } For a hollow sphere, it uses the surface extraction method above. This produces a shell with an air interior — perfect for arenas, domes, or building interiors.
The hollow approach requires more careful handling of edge cases at low radii. At radius = 1, the sphere is just a single block. At radius = 2, it's a small cluster. The algorithm must handle these gracefully without producing gaps or solid blobs.
The Layer‑by‑Layer Blueprint
The generator's killer feature is the layer‑by‑layer blueprint. For each horizontal layer y, it shows the exact blocks to place from the top down.
To generate this, the algorithm:
Iterates y from -radius to radius
For each y, calculates the layerRadius
Generates all blocks on the surface of that layer
Displays the layer as a 2D grid
This layer‑by‑layer view is what makes the tool practical for builders. You can follow the blueprint layer by layer, placing blocks exactly where they need to go.
The layer slider in the tool lets you cycle through each layer, showing the exact pattern for that height.
Performance Optimisation
A naive implementation for a 64‑block radius sphere would check (128³) ≈ 2 million blocks. That's fine for a one‑time generation, but the tool needs to be interactive — users adjust the radius and see the sphere update in real‑time.
To achieve this, I made two key optimisations:
Symmetry Exploitation
- A sphere is symmetric across all three axes. So instead of calculating all blocks, we only calculate one octant and mirror it:
javascript function generateOctant(radius) { const blocks = []; for (let x = 0; x <= radius; x++) { for (let y = 0; y <= radius; y++) { for (let z = 0; z <= radius; z++) { if (xx + yy + zz <= radiusradius) { blocks.push([x, y, z]); } } } } return blocks; } This mirrors the octant across all eight axes to produce the full sphere. This reduces the calculation space by a factor of 8.
Distance‑Based Layer Calculation
- Instead of scanning the entire 3D space, the layer‑by‑layer view only calculates the blocks for the current layer. This makes the slider interaction instantaneous.
A Practical Example: Building a Sphere Generator
Here's a simplified implementation of the core algorithm in plain JavaScript, suitable for a browser‑based tool:
javascript function generateSphere(radius, hollow = true) { const blocks = []; const rSq = radius * radius;
for (let x = -radius; x <= radius; x++) { for (let y = -radius; y <= radius; y++) { for (let z = -radius; z <= radius; z++) { const dist = x*x + y*y + z*z; if (dist > rSq) continue;
if (hollow) {
// Check if any neighbour is outside
const neighbours = [
[1,0,0], [-1,0,0], [0,1,0],
[0,-1,0], [0,0,1], [0,0,-1]
];
let onSurface = false;
for (const [dx, dy, dz] of neighbours) {
const nx = x + dx, ny = y + dy, nz = z + dz;
const ndist = nx*nx + ny*ny + nz*nz;
if (ndist > rSq) { onSurface = true; break; }
}
if (!onSurface) continue;
}
blocks.push({x, y, z});
}
}
} return blocks; } This function returns an array of block positions. For a hollow sphere, it returns only the surface blocks. For a solid sphere, it returns all blocks inside.
Lessons Learned
Building this tool taught me a few things that apply far beyond Minecraft:
Discrete geometry is harder than continuous geometry. A sphere is simple in math, but implementing it in a block grid requires careful handling of edge cases and visual smoothness.
Performance matters for user experience. The sphere needs to be generated fast enough to feel instantaneous. Without optimisation, the user would wait for a second or two on every radius change.
Layer‑by‑layer visualisation is a game‑changer for usability. A list of coordinates isn't useful for a builder. Showing a blueprint is. The same principle applies to any tool — present data in the way it's most useful to the user.
Symmetry simplifies everything. Using the octant approach cuts complexity by a factor of 8, making the tool interactive and responsive.
Where to See It in Action
If you want to explore this algorithm in a live tool, check out the Minecraft Sphere Generator I built. It includes everything described here — real‑time 3D preview, layer‑by‑layer blueprints, hollow/solid toggle, block material selection, and command export for Minecraft.
The tool is completely free and runs in your browser. No sign‑up required. You can play with the sphere generation and see the algorithm in action.
Final Thoughts
The voxel sphere algorithm is a beautiful example of how a simple mathematical idea — the sphere equation — translates into a practical tool for thousands of players. It's a reminder that behind every great tool is a solid algorithm, and behind every algorithm is a thoughtful design.
Whether you're building a game, a graphics tool, or a creative app, the same principles apply: understand the geometry, optimise for performance, and present the output in a way that empowers your users.



