Search Unity

Using normal map on TileMap

Discussion in '2D' started by MayoNinjaGames, Apr 24, 2019.

  1. MayoNinjaGames

    MayoNinjaGames

    Joined:
    Nov 7, 2018
    Posts:
    31
    Hi! So I've been trying to get into normal maps. I can get them to work fine on regular objects, but I'm having some trouble making them work on my TileMap. I have 5 different spritesheets thats spread around on different layers. I've tried making it work, but I only found this 2D-TechDemos, but when I try use the shader that comes with all the normal maps just comes and go and is put on the wrong tiles.

    Anyone got this working? :)
     
  2. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    The shader used in 2D-TechDemos requires that the normal map texture matches the sprite texture exactly in terms of UVs. Also, due to this, all of the Tiles used need to be on that same Sprite texture (and the same normal map texture).

    We are working on a system that decouples this dependency for the TilemapRenderer.
     
    MayoNinjaGames likes this.
  3. MayoNinjaGames

    MayoNinjaGames

    Joined:
    Nov 7, 2018
    Posts:
    31
    Ok, thanks for the reply! Love to see that the developers are so active on the forums! Guess I'll just use normal mapping on my regular objects for now and wait for this feature to be released! :)
     
  4. Lo-renzo

    Lo-renzo

    Joined:
    Apr 8, 2018
    Posts:
    1,513
    Isometric tilemaps + Chunk + Overdraw creates over-bright blotches where the overdraw exists. Is there a way to address this either with the shader or tilemap setting? It's extremely time consuming to produce isometric assets that don't result in any overdraw. Example of what I'm experiencing with exaggerated overdraw:
     
  5. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    Would it be possible to share what your Tiles look like individually? The mesh outline of the Tile Sprite can be edited in the Sprite Editor and possibly be tightened up by having it be set to render as a Tight Mesh and have the overlaps cut out?
     
  6. Lo-renzo

    Lo-renzo

    Joined:
    Apr 8, 2018
    Posts:
    1,513
    Thank you, I'll try that out.

    Using: standard sprite diffuse material (the TechDemos normal shader does the same thing).

    Before applying CustomOutline and turning off exaggerated overdraw:
    WithoutCustomOutline.PNG



    Here's the sprite on from the spritesheet tightened up w/ Custom Outline:

    CustomOutline.PNG


    Result with tightened up CustomOutline: NarrowingOutline.PNG



    For demonstration, spikey-shaped Custom Outline: CustomOutlineSpikedShape.PNG


    Result with spikey shape - note how only the second spike produces over-bright area, not the first spike.
    SpikedShapeResult.PNG

    Problem as far as I understand it
    Tilemaps + Chunk mode + normal/diffuse + it's hard/impossible to have zero overdraw when making isometric art to my knowledge. I tried for quite a while to get the Custom Outline shape right, but it would always produce artifacts somewhere. The tilemaps seem to multiply the power of the normal map where overdraw exists, though I'm not totally sure what's the issue. Even if there was a good workflow for dimetric or true isometric tight meshes (I'm use true isometric here), many isometric tiles would benefit from being able to draw into a neighboring tile without creating these over-bright lines.

    Some questions
    Could there be some kind of shader solution? A tilemap setting? Why do these bright lines appear w/ chunk but not individual mode? Could there be a setting to tell the tilemap, when chunking, to not combine the power of the lighting in areas of overdraw, but rather only write what's on top according to the Sort Order (Top-Right, Top-Left, Bottom-Left, Bottom-Right)?
     
    Last edited: May 4, 2019
  7. SisyphusStudio

    SisyphusStudio

    Joined:
    Nov 24, 2018
    Posts:
    9
  8. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    For Chunk mode, the vertices of the Tiles are statically batched together and will be rendered together as a whole including the application of the lights. When that happens, these overlapping pixels will be blended together as shown in your screenshots. For Individual mode, each of the Tiles has its own render pass for the lights, so it will not have this behaviour.

    Could you try the following with shader you are using? You can add the "noforwardadd" option to your shader (https://docs.unity3d.com/Manual/SL-SurfaceShaders.html), for example, with the Unity Sprites-Diffuse shader, change:

    Code (CSharp):
    1.  
    2. #pragma surface surf Lambert vertex:vert nofog nolightmap nodynlightmap keepalpha noinstancing
    3.  
    to

    Code (CSharp):
    1.  
    2. #pragma surface surf Lambert vertex:vert nofog nolightmap nodynlightmap keepalpha noinstancing noforwardadd
    3.  
    and apply this shader for your Tilemap?
     
    Lo-renzo likes this.
  9. Lo-renzo

    Lo-renzo

    Joined:
    Apr 8, 2018
    Posts:
    1,513
    Wonderful! It works like a charm. Thank you so much!
     
  10. Lo-renzo

    Lo-renzo

    Joined:
    Apr 8, 2018
    Posts:
    1,513
    Is there a way to get chunked tilemaps with normals to respect X-Mirroring?
    Code (CSharp):
    1.    
    2. class MirrorableTile : TileBase
    3. {
    4.     public bool mirrorX = true;
    5.     public override void GetTileData(Vector3Int placementCell, ITilemap tilemap, ref TileData tileData)
    6.     {
    7.         // other stuff
    8.         tileData.transform = !this.mirrorX ? Matrix4x4.identity : Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(-1f, 1f, 1f));
    9.     }
    10. }
    The lighting from normals get inverted for me if mirrored w/ chunked tilemap :(
     
  11. ChuanXin

    ChuanXin

    Unity Technologies

    Joined:
    Apr 7, 2015
    Posts:
    1,068
    You could try updating your MirrorableTile such that it inverts the Z in addition to the X:

    Code (CSharp):
    1.  
    2. tileData.transform = !this.mirrorX ? Matrix4x4.identity : Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(-1f, 1f, -1f));
    3.