Search Unity

Tiled Terrain edges seem to be bleeding shadows

Discussion in 'World Building' started by pdhr, Jul 5, 2019.

  1. pdhr

    pdhr

    Joined:
    May 13, 2019
    Posts:
    6
    I have a tiled terrain that is generated on runtime. The diffuse texture of each terrain tile is a real-world top-down camera image, so I want the visuals to have as little automated tampering as possible.

    However, on the very edge of each terrain tile, there is one very small strip of more shadowy area, as can be seen below. It seems to be shadow bleeding, from what little information I could find. But might be something else?
    What causes this and how do I fix this?

    Do note the image below is already about as zoomed in as I could get it.
    Thanks!

    upload_2019-7-5_16-16-39.png
     
  2. bazztard24

    bazztard24

    Joined:
    Jan 17, 2015
    Posts:
    4
    I dont know if the same, but i saw a similar problem (with solution) on a sebastian lague's tutorial: min 8:50
     
    pdhr and Phoenix116 like this.
  3. yoiang

    yoiang

    Joined:
    Jun 3, 2019
    Posts:
    1
    @pdhr I'm having the same issue, and it only happened recently where my terrains where moving in a way they weren't before (vertically and horizontally as opposed to just horizontally). I've futzed with shadow settings with no effect :/
     
  4. pdhr

    pdhr

    Joined:
    May 13, 2019
    Posts:
    6
    @bazztard24 Thanks for linking that! I didn't think of it being in the (way I imported the) texture being used. I just thought it had to be because of the terrain / lighting.

    Applying the settings in the video fixes the band of shading. It was probably just the wrapping of the texture.
     
  5. ChrisTchou

    ChrisTchou

    Unity Technologies

    Joined:
    Apr 26, 2017
    Posts:
    65
    Yes, this looks like a texture wrapping issue, with the texture set to black-border or wrap, instead of clamp.
    Is this using a custom shader? By default in a custom shader, the texture coordinates will stretch edge-to-edge, pulling in half a pixel of border region like this. We fixed this in the default Terrain shaders by adjusting the texture coordinates so they stretch pixel-center to pixel-center, so it never samples from border regions.
     
  6. ChrisTchou

    ChrisTchou

    Unity Technologies

    Joined:
    Apr 26, 2017
    Posts:
    65
    If you want to do the same adjustment to a custom shader, you can modify the texture coordinates used to sample your texture:

    float2 stretchedUV = (originalUV * (_MyTexture_TexelSize.zw - 1.0f) + 0.5f) * _MyTexture_TexelSize.xy;
    float4 color = tex2D(_MyTexture, stretchedUV);

    This stretches the texture by half a pixel along each edge.
     
  7. pdhr

    pdhr

    Joined:
    May 13, 2019
    Posts:
    6
    Thansk for your reply @ChrisTchou! Setting it to clamp fixed that seam. I was using the default terrain, so default shader.

    However, I now have a different issue, and I hope you can help with that.
    I set the terrain texture from a script. This worked fine (as you can see in the image above) while I was on Unity 2018.3 I believe.
    However, somewhere since updating to 2019.1 or 2019.2, it no longer sets the texture, instead I get the grey checkerboard. However, the texture is loaded into the terrain layer, and I can then 'paint' it with the brush, but it should be set automatically like before.

    Do you have any idea what changed or how to fix this? I am currently on 2019.2.1f1.

    See the code below where I set it:

    Code (CSharp):
    1.  
    2.         {
    3.             for (int j = 0; j < 2; ++j) //config.NumElevationTileRows
    4.             {
    5.                 for (int i = 0; i < 2; ++i) //config.NumElevationTileColumns
    6.                 {
    7.                     id = i + j * (config.NumElevationTileColumns);
    8.                     TerrainData data = new TerrainData();
    9.                     tiles[id] = Terrain.CreateTerrainGameObject(data);
    10.  
    11.                     tiles[id].name = String.Format("Terrain_{0}x{1}", i, j);
    12.                     tiles[id].tag = "Terrain";
    13.                     tiles[id].layer = TerrainUtils.LayerTerrain;
    14.                     tiles[id].transform.position = center_offset + new Vector3((float)config.GetStartPositionX(id), 0, (float)config.GetStartPositionZ(id));
    15.                     tiles[id].transform.SetParent(terrainRoot.transform);
    16.                     tiles[id].isStatic = true;
    17.  
    18.                     tiles[id].GetComponent<Terrain>().drawInstanced = true;
    19.                     SetElevationFromTileFile(config, tiles[id], (config.NumElevationTileRows - j - 1) * config.NumElevationTileColumns + i);
    20.                     tiles[id].GetComponent<Terrain>().heightmapPixelError = heightmapPixelError;
    21.                     SetTerrainImagery(config, data, id);
    22.                     tiles[id].GetComponent<Terrain>().Flush();
    23.                 }
    24.                 Debug.LogFormat("Processed tile row {0}", j);
    25.             }
    26.         }
    27.  
    28.         private static void SetTerrainImagery(TileConfiguration config, TerrainData terrainData, int id)
    29.         {
    30.             // Initialise terrainLayer
    31.             float tilesize = (float)config.ElevationTileDimension;
    32.             TerrainLayer[] terrainLayers = new TerrainLayer[1];
    33.             terrainLayers[0] = new TerrainLayer();
    34.             terrainLayers[0].tileOffset = new Vector2();
    35.             terrainLayers[0].tileSize = new Vector2(tilesize, tilesize);
    36.  
    37.             // Set Ortho
    38.             Texture2D ortho = (Texture2D)(AssetDatabase.LoadAssetAtPath(String.Format("{0}\\{1}.png", TerrainUtils.ImageryPath, id), typeof(Texture2D)));
    39.             ortho.filterMode = FilterMode.Bilinear;
    40.             ortho.wrapMode = TextureWrapMode.Clamp;
    41.            
    42.             terrainLayers[0].diffuseTexture = ortho;
    43.  
    44.             // Assign terrainLayer to Terrain
    45.             terrainData.terrainLayers = terrainLayers;
    46.         }
    See this image for what I mean:
    upload_2019-8-22_17-37-9.png
     
  8. pdhr

    pdhr

    Joined:
    May 13, 2019
    Posts:
    6
    Since I'm unsure whether this will be picked up properly, I made a separate thread here for my last question.