
Mini Minecraft
Developed a 3D voxel game engine in a team of three using OpenGL, C++, GLSL. I personally implemented shadow mapping with Percentage Closer Filtering, procedural terrain generation and biome blending with various noise functions, texturing, and animation.
Highlights Video

Shadowmapping
I implemented shadow mapping by writing to a shadow map texture and sampling it later to determine where shadows should be created. I stored the orthographic depth from the sun’s position.
To improve the shadow mapping, I focused on:
-
Increasing the texture image size and using a higher decimal approximation for the z-value
-
Integrating the sun's movement with the player and day-night cycle, alongside teammates’ implementations.
-
Applying Percentage Closer Filtering to blur the shadow edges:

Clear Edges (Single sampling)
Blurred Edges (Percentage Closer Filtering)
Biomes/Terrain Generation
I implemented a system to blend a 3x3 grid of biomes, with each biome blending smoothly with its 4 closest neighbors based on its position on the grid. I used Perlin noise to control the transitions between biomes and performed remapping to ensure a more even distribution. Each biome is uniquely textured based on height.
Some biomes I implemented are:
-
Mountain
-
Grassland
-
Desert
-
Steep Canyon
-
Snow Pitfall
Additionally, I created floating islands by curving out the islands and their bottom layers using Perlin noise, then generating biomes on the top layer.

Texture / Texture Animation
To implement texture mapping for the blocks, I organized block data and their corresponding texture coordinates (256x256) in a map. These texture coordinates were then passed to the shader, where I utilized texelFetch to accurately sample the texture at the specified coordinates.
For animated blocks, such as lava or water, I applied an offset to the texture coordinates in the fragment shader. This offset dynamically shifts by 1 to 16 pixels over time, creating the desired animation effect.
A time variable, incremented with each call to tick(), was used to drive these animations.






