Search Unity

Low-poly terrain

Discussion in 'World Building' started by Romaleks360, May 16, 2019.

  1. Romaleks360

    Romaleks360

    Joined:
    Sep 9, 2017
    Posts:
    72
    This topic was massively discussed before, but maybe there are some changes with these new terrain upgrades?
    So, what's the easiest way to make low-poly terrain since unity 2018.3? Should I write some custom shader? If so, can someone point me to some useful tutorials about terrain shaders?
    Also, look at this picture from the unity article. How can I achieve these hard edges (from the legacy terrain, though)
     
  2. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    I have a module to do this shipping for MicroSplat soon. That said, the common ways:

    1. Convert to mesh and hard edge the mesh
    2. Use a geometry shader (slow, not available on all platforms) to basically do the above in the shader

    The module I wrote does everything in the pixel shader to avoid these issues. Basically, it uses a per-pixel normal map, but adjusts the UV lookups so they align to triangle or quad edges only.
     
  3. wyattt_

    wyattt_

    Unity Technologies

    Joined:
    May 9, 2018
    Posts:
    424
    The behavior seen in the first image is probably due to quantization. There isn't a high enough precision available for that texture mask which gives it a "terracing" effect. You could write a shader that implements terracing or use an 8-bit texture mask instead of 16-bit
     
  4. Romaleks360

    Romaleks360

    Joined:
    Sep 9, 2017
    Posts:
    72
    I don't like the first approach because of losing all the terrain optimization, grass, trees, etc.
    Why is the unity terrain smooth? Can't we just recalculate normals in the terrain's mesh, maybe through basic vertex shader? Won't it be the easiest approach? Also, why it can be unsupported somewhere?
     
  5. Romaleks360

    Romaleks360

    Joined:
    Sep 9, 2017
    Posts:
    72
    What do you mean by "terracing"? What is "texture mask" in this context?

    I've tried to wrote some custom shader (for my second time) but had no success. I changed the dependency "BaseMapGenShader" with my custom shader (because I want vertex shader), but:
    1. It almost always turns purple
    2. I see no compiler errors for this shader, even if they should be
    3. Changes to the shader are applied to my terrain only after I switch the shader on the terrain material to some other shader and back

    What am I doing wrong? I want the basic "Show Normals" shader, so I copied DiffuseFirstPass and DiffuseBaseMapGen to my project. In the FirstPass I've just set the path for BaseMapGen to the copied one, but some slight changes in it make it purple.
    Also, this shader only draws after BaseMap distance property in terrain settings, so I guess it's not the shader I want to change. But I need only vertex shader to change normals, is it possible?

    // Upgrade NOTE: excluded shader from DX11; has structs without semantics (struct v2f members worldNormal)
    Just saw this line, and that's what I did - putting the worldNormal member in v2f, is it prohibited?

    I'm totally confused...
     
  6. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    No, for a hard edge you need multiple normals, so you can’t just make them hard in a vertex shader. To generate multiple normals you need to use a geometry shader to output a unique triangle for each triangle in the source mesh with its own normals. But geometry shaders are going away in modern APIs because they are very slow.
     
  7. Romaleks360

    Romaleks360

    Joined:
    Sep 9, 2017
    Posts:
    72
    Aww, I see...
    Can't imagine how this can be done in a pixel shader, so I guess I'll wait for your solution
    If it's not a secret, when will it be ready?
     
  8. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Already submitted; but what it does is sample the per pixel normal map at the same position across the whole face. Since the topology is known, you can quantize the uvs to align with triangles or quads.
     
  9. wyattt_

    wyattt_

    Unity Technologies

    Joined:
    May 9, 2018
    Posts:
    424
    "Terracing" refers to the geological feature where you get "steps" in sediment as seen here:
    terracing_1.jpg terracing_2.jpg

    And the texture mask is the actual brush texture being used. These store height values that are used to add or remove height from Terrain but when they are a low enough precision, and especially when the brush strength or opacity is very low, you end up getting floating-point values that won't fit in the number of bits provided by the texture format that is used for the brush mask and Terrain's heightmap, so those values are truncated and the extra precision is thrown away which produces results that resemble terracing.
     
  10. ChrisTchou

    ChrisTchou

    Unity Technologies

    Joined:
    Apr 26, 2017
    Posts:
    74
    If you're talking about the faceted look of the brush preview, rather than the terracing in the first image, then that is achieved by using actual triangle normals instead of the interpolated mesh normals.

    If you're handy with shaders, you can replace the normal calculation with something like:

    float3 dx = ddx(worldPosition);
    float3 dy = ddy(worldPosition);
    float3 worldNormal = normalize(cross(dy, dx));


    May have to negate the result, not sure which way it goes.
     
  11. wyattt_

    wyattt_

    Unity Technologies

    Joined:
    May 9, 2018
    Posts:
    424
    ah yes. the behavior for the normals would make more sense than the quantization given the context of the question
     
  12. ChrisTchou

    ChrisTchou

    Unity Technologies

    Joined:
    Apr 26, 2017
    Posts:
    74
    Note that using triangle normals on the Terrain will make the LOD swaps very obvious, as it depends on the triangles themselves. Jason Booth's approach would be better if you want it to maintain appearance over distance.
     
  13. Romaleks360

    Romaleks360

    Joined:
    Sep 9, 2017
    Posts:
    72
    Much thanks! But which shader do I need to fix? There are many default terrain shaders, I want to use some of them as a base and replace this normal calculation
    I tried to do it ~2 weeks ago and ran into some problems described in the post below