How to Build a 3D Minecraft Portfolio with CraftFolio
CraftFolio is a React component library that maps your professional data—projects, skills, and experience—directly into a 3D environment. Instead of scrolling through a list, users walk up to structures representing your repos or find "skill ores" scattered across the terrain.
The implementation is intentionally lightweight for the end user:
import { CraftFolio } from 'craftfolio';
function App() {
return (
<CraftFolio config={myPortfolioData} />
);
}The Technical Implementation
From a development perspective, the biggest hurdle with voxel engines is the draw call overhead. If you render every block as a separate mesh, your GPU will choke once you hit a few thousand voxels.
To keep this running at 60fps, I implemented instanced rendering. Rather than 10,000 individual draw calls, the engine uses a single geometry and a material, then passes a buffer of transforms to the GPU to render thousands of blocks in one go.
const blockGeometry = new THREE.BoxGeometry(1, 1, 1);
const blockMaterial = new THREE.MeshLambertMaterial({ map: textureAtlas });
const instancedMesh = new THREE.InstancedMesh(
blockGeometry,
blockMaterial,
MAX_BLOCKS
);
// Set position for each block instanceArchitecture Breakdown
The project is structured to separate the Three.js scene logic from the procedural generation:
- VoxelWorld.tsx: Handles the core Three.js scene, camera, and renderer.
- Terrain.tsx: Manages the procedural world generation.
- PlayerControls.tsx: Implements first-person WASD movement and mouse look.
- WorldGenerator.ts: Uses Perlin noise for terrain and handles the placement of structures.
- PhysicsEngine.ts: A lightweight AABB (Axis-Aligned Bounding Box) system for collision detection so the player doesn't walk through walls.
For those interested in a deep dive into the setup, the system includes a custom shader pipeline (
voxel.vert and voxel.frag) to achieve that specific pixelated lighting look without sacrificing performance. It also includes a responsive fallback that degrades to a 2D view for legacy devices.