This came about from my latest programming hiccup, which was related to depth buffering. I originally thought I could simply stack my tile meshes (rectangular boxes) together as-is, but when I tried it on a scrolling level, I was seeing seams flickering in and out, along the tile boundaries. It was hard to get a screenshot, but here is one I caught while inspecting the normal render buffer (or render target for D3D folks):
The teal-coloured line on the left is what I was crying about! Teal represents normals pointing left; I store normals in RGB, mapping the range [-1,1] to the range [0,1], use a right-handed coordinate system and camera facing down negative Z. So it seems like the left face of those particular tile meshes were bleeding through. Note that I had back-face culling turned off at the time. After some searching, reading & head-scratching, I figured out the cause...
I naively assumed the front (camera-facing) faces would cover up the left/right faces behind. But this would only be correct most of the time. When depth sampling (which presumably happens at the centre of each pixel) hit the exact edge of a left face, that face would receive a depth value equal to what the front-face would later get - and so begins the gruesome z-fight between left-face and front-face over that one pixel. :)
To confirm this theory, I put in some quick hacks in my vertex shader to snap all vertex positions (after transformation to clip space) to the closest pixel corner. For a grid of axis-aligned meshes like my scene, this ensured no pixels were ever centred over the edge of any left faces. This did fix the seams, but is not a good, general solution (only works for axis-aligned boxes).
It makes complete sense now... but not immediately obvious to me in the beginning!
Learning my lesson, I now weld tile meshes together - any overlapping/shared faces are hidden. My tile meshes group their triangles into sections (one section for each face) and I can selectively turn off sections for a particular mesh instance. For now, the tile generator just handles all that cumbersome work of turning off the appropriate face if there is a neighbouring tile. But I plan on retro-fitting more content-creation goodness later.
Here's a video of the latest build with some scrolling action (and no seams!). The generator is being used for the floating islands:
