Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Texture atlases simply impossible to use with good results? (Mipmaps)

Discussion in 'General Graphics' started by bloomingdedalus, Feb 15, 2015.

  1. bloomingdedalus

    bloomingdedalus

    Joined:
    Aug 13, 2012
    Posts:
    139
    It seems no matter which way I turn I'm running into a hitch for using texture atlases in shaders. This one seems to be the final straw.

    They work fine as long as mipmaps are completely disabled - except textures look terrible with mipmaps disabled. When I have unity generate the mipmaps, there's inevitably huge bleeding between the textures in the atlas. Finally I found a way to create my own mipmaps and I thought my problem was solved!!!

    After a few hours of putting together a mipmapped texture atlas in Gimp I import it in...

    "Error: Invalid number of mip maps. Expected 13 found 9"

    *smashes computer* - *buys new one* - *continues post*...

    It wants me to reduce my texture atlas to one pixel no matter what...

    So, essentially I'm stuck with utterly hideous sampling of unmipmapped textures if I want to continue using a texture atlas...

    Anyone know how to make Unity ignore certain mipmap levels? I know there's an option in DX9 to set the minimum mipmap resolution to higher than one pixel, but I don't think Unity exposes this...

    Is there a way to go ahead and give it blank lower resolution mipmaps and cap the sample resolution in the shader or otherwise? There must be a hack for this!

    That's the point of programming! There's always supposed to be a hack to do what you want to do other than design a graphics engine from the ground up...

    Sigh... so close and yet so far: http://stackoverflow.com/questions/3423758/creating-and-using-my-own-mipmap-of-a-texture-atlas
     
    Last edited: Feb 15, 2015
  2. imaginaryhuman

    imaginaryhuman

    Joined:
    Mar 21, 2010
    Posts:
    5,834
    You have to make the number of mipmap levels it asks for, even down to the 1x1. Changes are those tiny ones won't get used so why would you care what 1 pixel in the far distance looks like?

    Also you need more spaces between objects in the texture so that when they mipmap you don't get bleeding. If you think about it, at each mipmap level, the texture size is cut in half, which means 2 pixels become 1. So after 2 levels of reduction, you already have 4 pixels represented by just 1 pixel. So for a 1024 texture, after just reductions of 512, 256 and 128 and 64, you're already representing 16 pixels width and height with a single pixel. That means you have to have 16 pixels between your sprites in the main texture if you want to avoid any bleeding, right?
     
  3. bloomingdedalus

    bloomingdedalus

    Joined:
    Aug 13, 2012
    Posts:
    139
    I was making my own mipmaps to avoid bleeding. Gimp has a dds exporter (format that allows you to author mip maps)... now if I can only find a way to point sample a dds file in unity rather than bi-linear, I'd be set...
     
  4. bloomingdedalus

    bloomingdedalus

    Joined:
    Aug 13, 2012
    Posts:
    139
    ANSWER:

    For anyone looking for something like this, you can hack your shaders' mip maps by sampling textures with a minimum derivative...

    e.g:

    dx = ddx(uv.xy);
    dy = ddy(uv.xy);

    float4 HaxdMipMapColor = tex2D(_WhatevsTex, uv.xy, min(float2(.001,.001), dx)), min(float2(.001,.001), dy));

    It's not perfect, but it's better than no mip-maps and better than reducing your texture atlas to one pixel.

    Here's some photos of the frustrations I was having as I've seen a lot of other people having the same frustrations attempting to implement texture atlases with people saying the problems were caused by texture bleeding which is not the source of the fundamental artifact that many people encounter: http://i.imgur.com/DP5vraQ.jpg
     
    Last edited: Feb 15, 2015
  5. Dolkar

    Dolkar

    Joined:
    Jun 8, 2013
    Posts:
    576
    To my knowledge, this shouldn't be a problem at all as long as your tiles have power-of-two sizes and are also aligned to power-of-two pixels. This will cause the mips to get generated from just that single tile. If you also clamp the coordinates to the center of the edge pixels of each tile (instead of the border), you eliminate bleeding from bilinear filtering as well, meaning you won't need spaces between your tiles at all!
     
  6. bloomingdedalus

    bloomingdedalus

    Joined:
    Aug 13, 2012
    Posts:
    139
    I'll try refining the clamp of the coordinates like you said, to centers of pixels. I was feeling pretty lazy (in that writing shaders presents so many bigger problems for my little brain than simply a slight floating UV drift) and wrote the shader to generalize the atlas UVs.

    However, even doing that is going to eventually result in bilinear bleeding unless you know of a way to get the mipmap level which will be sampled in order to adjust the clamp of the UV...

    Regardless, a mip map level of 1x1 pixels is obviously completely unacceptable for a texture atlas and I'll have to limit it somehow, so I'm going to stick with my hacking the fragment shader derivative mipmap limiter as it seems to produce tolerable results for what I'm aiming for and I already need to do this as the tiling method I chose seems to be producing derivative artifacts so I need to pass in the fragment derivatives anyway...