Triplanar shaders and texture atlases

Hello!

I’m working on a Marching Cubes based terrain generation system. Recently I’ve been using UV maps and a texture atlas to texture the meshes. UV maps were generated based on data from the blocks of the mesh, so any block of the terrain could have a different texture. This was fine as it did its job, but in a poor quality.

The problem with this solution is that some “stretched” triangles had stretched textures as well and at texture changes (e.g.: a sand block next to a grass block) there was a hard seam without blending.

The solution I’m thinking of is to combine a triplanar shader with texture atlases. However I simply just can’t seem to find a way to use a texture atlas alongside a triplanar shader. I don’t know how could I use a texture atlas without UV maps.

I’m not really good at shader programming, this is the reason I’m posting here.

If you know a way to use a triplanar shader with texture atlases or any way to add texture blending to the old UV based solution, please share it with me.

Thanks in advance.

There’s three ways to go about doing triplanar mapping with an atlas.

One is to store the UVs for all 3 axis on the mesh itself. So just like you were already doing before with the UVs limiting the texture to the appropriate region of the atlas, you’re still doing that, just for all 3 directions. Then use the normal to blend between them like you would with any other triplanar shader. This is the “simplest” option, but not necessarily the one I would recommend. Like the method you’re already using it requires each “cube” to be it’s own mesh and you can’t reuse vertices at all.

The next option is to store the index of the atlas tile you want rather than the actual tile UVs. Then figure out the offset and scale to put the texture at that tile within the atlas. Look up flip book animation shaders for examples. Then you use world or object space UVs, limited to 0.0 to 0.999… with frac(), and then scaled and offset to the tile you want. The tile index could be stored in the mesh UVs, but this option would let you use greedy meshing. However you’ll get some odd aliasing issues between tiles when using frac().

The last option is the same as above, but use a texture array instead of an atlas, then you don’t have to scale the UVs or otherwise try to figure out the part of the atlas for your texture, just pass the index straight into the texture array sample function.

1 Like