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)
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.
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
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?
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...
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.
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?
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.
"Terracing" refers to the geological feature where you get "steps" in sediment as seen here: 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.
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.
ah yes. the behavior for the normals would make more sense than the quantization given the context of the question
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.
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