• Advertisement
Sign in to follow this  

Avoiding seams in mega textures (texture atlases)?

This topic is 425 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Advertisement

You need to waste a bit of memory including extra/duplicated border regions around each texture (or texture block) within the atlas / mega-texture. The border needs to be as wide as the filter - so for bilinear filtering, you need a 1px border... However, if mip-mapping is enabled (it should be!) then you need 1px at the smallest mip level, which turns into 2px at the next level, 4px at the next level, then 8px, etc... So if you have 4 mip levels, you need an 8px border region at the high res mip level.

Share this post


Link to post
Share on other sites

You need to waste a bit of memory including extra/duplicated border regions around each texture (or texture block) within the atlas / mega-texture. The border needs to be as wide as the filter - so for bilinear filtering, you need a 1px border... However, if mip-mapping is enabled (it should be!) then you need 1px at the smallest mip level, which turns into 2px at the next level, 4px at the next level, then 8px, etc... So if you have 4 mip levels, you need an 8px border region at the high res mip level.

Interesting...So if your smallest mip-map level was 1x1, then that means your border size for a 256x256 texture would be 256px.

It would seem picking a larger size for the smallest mip-map level would result in a much smaller border at larger texture sizes.  Whats the smallest mip-map size recommended on modern hardware?

Share this post


Link to post
Share on other sites
Yep.
You need what you need :)
If a 256 texture is ever small/distant enough that it will only cover 1 screen pixel, then you need that 1px mipmap level. If you don't have it, then you suffer a performance penalty and a quality penalty (flickering).

You can analyse your scenes and discover which mip levels are actually used (e.g. output the mip level to a render target :) ) -- many games already do this to find any textures that are needlessly high res! Megatexture systems also often do this on the fly so they know which data to stream in.

Another option is to write your own trilinear filtering in the shader and implement mipmapping yourself. If you store all the mips in the same level of an atlas / Megatexture and fetch/filter them youself, then you can get away with a 1px border on every mip level.

Share this post


Link to post
Share on other sites

Another option is to write your own trilinear filtering in the shader and implement mipmapping yourself. If you store all the mips in the same level of an atlas / Megatexture and fetch/filter them youself, then you can get away with a 1px border on every mip level.

I've actually tried filtering textures in the pixel shader before and the performance wasn't as good as what the driver natively does.  That's partially were the original question stemmed from.  I was curious how mega-textures handled things.  I guess like you said, you need what you need.  Thank you for your insight.

Share this post


Link to post
Share on other sites

Another thing to look out for with a texture atlas and filtering:

If you tile your atlas textures, such as for example on a terrain, you may get a "fun surprise" from the fact that where your texture coordinates wrap around, there is a steep jump in the derivatives, so the wrong mipmap is being selected, and even with borders, it doesn't look right. Mirrored tiling would do away with the problem, but I forgot what the solution was if you didn't want mirrored tiling...

Luckily, there's array textures nowadays. Such a blessing.

Share this post


Link to post
Share on other sites

and fetch/filter them youself, then you can get away with a 1px border on every mip level.

can't you also write the shader to not blend in the border when generating / sampling mips? 

Share this post


Link to post
Share on other sites

and fetch/filter them youself, then you can get away with a 1px border on every mip level.

can't you also write the shader to not blend in the border when generating / sampling mips?

Yeah, you could do a whole bunch of point samples / texel loads and implement all filtering yourself. However, that requires 4 loads for bilinear filtering and 8 loads for trilinear filtering. With the 1px border, it's 1 load for bilinear filtering and 2 loads for trilinear filtering.

Share this post


Link to post
Share on other sites

The explained solutions were mostly for texture atlases. Mega textures work slightly different.

1. There is no hardware mip mapping, this would break quite a bit of the tech. It actually avoids these issues by handling mip filtering by the pixel shader.

2. The tiles always ( on every mip level) work the same and the border size depends solely on the filtering you use (bilinear, anisotropic,..), 1 pixel for bilinear.

3. The Mips don't include the border, the mips are only generated based on the border-less base texture. Then you divide each level into equally sized tiles, e.g. 126x126 and add the 1 pixel border.

4. While the border might sound problematic, the alternative would be to always load the surrounding 8 tiles into the texture as well, to filter properly cross border, that would be 9x the memory usage.

5. please don't mix atlas textures and mega textures. Atlas is the idea of fitting a lot of textures into one. Mega texture is actually the opposite, to have one big textures (no borders, a triangle could map it completely). The tiling is only a solution to low level memory organization. On modern hardware, you could use Partially Resident Textures (PRT), that can solve a lot of the Mega texture issues. Texture Atlases would still have bleeding issues etc.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement