When performing “deep zoom” into simple textured geometry (no fancy proceduralism or raymarching), it doesn’t take long before seeing big fat blurry texels. This post presents some thoughts on simple tileable texturing, inspired by slippy maps.
First, a demo. Press the zoom button to zoom to the east coast of Corsica in this quick-and-dirty map of Europe. This is not a slippy map. It’s just a simple WebGL app with two draw calls: one for the landmass mesh, and one for the water.
The demo draws inspiration from slippy maps to figure out how to scale and translate the texture coordinates. The shader that applies the water texture doubles the frequency of the texture coordinates every time the zoom level crosses a new integer threshold. Most of the math is done on the CPU, so the fragment shader is really simple:
The landmass shader works similarly, except that it cross-fades between two texture frequencies, thus avoiding the noticeable pop seen with the water texture:
When the demo is done zooming, you might see some precision problems with the water texture, but the landmass looks fine. That’s because the landmass shader uses
gl_FragCoord rather than baked-in mesh coordinates. Try toggling the FragCoord button to see the difference.
This demo was created with emscripten, and the source code can be found below. Apologies if it’s a bit funky; it uses one of my tiny graphics engines that are forever works in progress.