Search Unity

Question Help with UVs wrong at sharp angles

Discussion in 'General Graphics' started by willovertonuk, Nov 13, 2022.

  1. willovertonuk

    willovertonuk

    Joined:
    May 31, 2020
    Posts:
    4
    I am working on a voxel game and all is working well except for when a chunk mesh is viewed at an oblique angle:

    upload_2022-11-13_12-13-57.png

    If you notice there is pink at the top of the image where the mesh is only just visible.

    The pink comes from unused parts of my voxels texture atlas:
    upload_2022-11-13_12-15-51.png

    I can not figure out why the wrong parts of the texture are being drawn at tight angles, the mesh works fine if viewed from any other angle.

    I am using URP and the material for the voxels is a standard URP lit. I have point filtering enabled for the texture and have tried disabling anti aliasing, which did not help.

    Any pointers here would be incredibly helpful!
     
  2. willovertonuk

    willovertonuk

    Joined:
    May 31, 2020
    Posts:
    4
    An important note: This happens in scene view and during gameplay.

    Here is the same wall at slightly different angles:

    upload_2022-11-13_12-19-26.png upload_2022-11-13_12-19-37.png
     
  3. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    4,639
    Textures get blurry with all the different filtering and mipmapping that goes on. So that means some magenta color is going to bleed in, Since it's only at step angles you can increase the aniso filtering level of the texture and that might fix it, but it's good practice to add a gutter-space around each texture island. Make each island slightly bigger than what you are mapping to your model, so if the edges bleed, it will still be the same color, over all.
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Mipmapping is indeed the issue here. At extreme angles, the mipmap's resolution will eventually be 4x4 or smaller meaning that purple in the unused tiles will eventually start to bleed into the color being sampled.

    But anisotropic filtering won't actually make it any better. Especially since the author appears to be going for a point sampled look for the textures and for many graphics APIs you can't use point filtering and anisotropic filtering together.

    There are a few solutions to this problem.
    1. Disable mipmapping on the atlas texture.
      I do not recommend this solution as it'll make your textures look terrible in the distance, and can come with some performance loss. But it will fix the problem.
    2. Limit the number of mip maps in the asset.
      To do this requires creating a texture asset using a custom script and setting the number of mipmaps that asset has manually. With the correct mipcount set you won't have to worry about the mip map size getting below 8x8 meaning each tile will have at least a single pixel of its own in the smallest mip. But I don't recommend this option either just because it's kind of a pain to use.
      https://docs.unity3d.com/ScriptReference/Texture2D-ctor.html
    3. Limit the number of mip maps in the shader.
      Alternatively you can calculate the appropriate mip level in the shader and limit it there. But this is more expensive than the previous option, and takes a bit more shader knowledge to implement properly.
    4. Use texture arrays.
      This is the solution I actually think you should look into. The recent versions of Unity even let you import texture atlases as arrays making this much easier to implement. The main thing is you need to change your shader (and voxel mesh's UVs) to work with this. For the shader it's mostly a matter of using a custom shader graph that samples a texture 2D array instead of a texture 2D. But for the mesh it means you need to encode both the 2D UVs and the layer index in the vertex data and the shader has to know where to find that index. You can store it in another UV channel, or the vertex color, etc.
     
    Tartiflette likes this.