Search code examples
unity-game-engineshaderuv-mapping

Atlas UV map vs. Local UV map


I want glow on my sprites using the UV coordinates, but the problem is, if the sprite originates from an atlas created by Unity's sprite packer, then the UV aren't normalized from 0 to 1, but from and to two arbitrary values. How do I normalize UV data for a single sprite that resides in an atlas? Am I required to parse additional information into the shader or should I already have the necessary information to do this process? The image below describes the situation:

enter image description here

The hand to the left is a sprite not from an atlas. The hand on the right is a sprite from an atlas. I want the right hand to look the same as the hand on the left.

I am not that familiar with shaders yet, so I am reliant to using shaderforge. I am using the following shaderforge layout: enter image description here


Solution

  • You probably already know this, but the fundamental problem is the output of your "UV Coords" node. The other nodes in your shader are expecting normalized UVs ranging from 0 to 1, but that's not what you're getting when you use the texture atlas.

    I can think of two ways to solve that. They're both viable, so I'd recommend trying whichever one fits more cleanly into your workflow.

    Add a second UV channel

    It's easy to treat UV0 as the only UV channel, but for certain techniques it can be helpful to add multiple UV coords to each vertex.

    As an example, lightmapping is a popular feature where each model has its own individual textures (diffuse/normal/etc), but each scene has a pre-baked lightmap texture that is shared between multiple models -- sort of like an atlas for lighting information. UVs for these will not match, so the lightmap UVs are stored on a second channel (UV1).

    In a similar fashion, you could use UV0 for atlas UVs and UV1 for local UVs. That gives you clean input on the [0,1] range that you can use for that multiply effect.

    Add material params

    You could scale and offset the UVs so that they are normalized.

    1. Before rendering, find the min and max values for the mesh's UV coords
    2. Pass those values in as material parameters
    3. Add shader nodes to scale and offset the input UV, such that the range is normalized

    For example, you could add min to each UV (offset), then divide by max - min (scale).