A shader that reduces vertex count

Hi,

I am working on a golf project and have a very highres detailed mesh of the terrain with thousands of vertices.
Now I am looking for a shader that reduces the vertices that are far away from the camera:

I already have extensively tested the DX11 Tesselation shaders delivered with Unity but they do not fit into my
workflow: I need a shader that works vice versa to the tessalation shaders:

Standard shaders have a lowres mesh and add vertices.
I have a highres mesh and need vertices deleted.

Anyone heard of a shader that does this?

It’s probably possible in DX11, but I have no experience with that. Most DX11 geometry processing is indeed aimed at increasing the detail, since that offers the most performance gain.

The traditional way of doing something like that is to convert the terrain into a height map and using that as input to a shader that puts a tesselated plane at the right height. By centering the plane around the camera and reducing the tesselation further away, this offers an “easy” way to render a large terrain with varying detail. Extra bonus is that it only needs shader model 3 to do so.

No, shaders can not do that.

Typically shaders don’t change the vertex count at all (vertex shader runs for each vertex, and that’s it). With DX11 tessellation/geometry shaders it is possible to make more vertices - but not to reduce their count in any meaningful way.

I’d suggest optimizing the vertex count offline in some 3D app (like Maya or 3dsmax), and importing into Unity as LODs. And then using these lower detail models when far away, see Unity - Manual: LOD Group

i never thought about that… and i wouldn’t know how to realize something like that in unity. I mean once stuff “hits the shader” the the struct containing the arrays has already been passed to the gpu… so they would be cycled through anyways.

Have you considered LODs and Occlusion culling? I know LODs will bloat your distro but in my experience it’s well worth it.
If you got the Pro version that functionality is already implemented; if you got the free version you could use the OC that’s offered there… or if you’re interested in a pure LOD solution, that doesn’t need any pre-calculations, for the free version you could wait until mine is through the store approval process.

lol got beaten to it by @Aras … by 20 minutes… daaaamn you eeemails.

Thanks guys!
As it seems there´s no shaderbased solution for my idea.

Until now I had my terrainmesh split into 4x5 tiles, each tile with 4 LODs, means 20 LOD packages - all in 3dsmax.
Each tile has a 2048px texture.
This works, but it´s very unconvenient when it comes to changes in the topology:
All 4 LODs have to be updated so it quickly comes to inaccuracies…

Ok, didn’t know it was completely impossible to reduce the vertex/triangle count. Haven’t done any geometry/tessellation shader writing yet. But, makes sense.

The downside of using static lod models is the potential for gaps between parts with different detail levels.

The downside of the sliding terrain approach is the potential for the terrain to appear to move or pop. Another downside is the limitation to a 2.5D approach without overhangs, but that should not be much of an issue for a golf terrain.

I assume with the inaccuracies you mean discrepancies on the borders of 2 tiles at different LODs?
When creating the LODs which way did you go: ‘ProOptimizer’ or ‘manual removal of loops’ ?

edit: just saw… greets from Neuss :stuck_out_tongue:

Exactly, I mean discrepancies on the borders of 2 tiles at different LODs.

Creating my LODs I start with a plane 4x5 segments, each segment with a separate Material ID.
Add a first EditPoly that tesselates the 20 base-polys so that I get my LOD3.
Add a second EditPoly that again tesselates the polys so that I get my LOD2.

Add a Displace Modifier to get height from a prerendered heightmap:
(The original heightmesh delivered from my client was extremely tesselated, unusable, so I rendered a heightmap from that.)
Add an EditPoly on top from where I detach the 20 LOD packages.
A lot of work!

here’s and idea:
start with the highest poly mesh:

10: displace it (“it” being mesh)

20: (a) = create a refference of (mesh)
30: add a proOptimizer to the ref (a)
40: set it to 50%
goto 20 using (a) for (mesh)

That way when you update the source mesh all LODs update, you just need to write a little 1line maxScript to update the modifiers. The updating will take a minute or so but will be nicely automated. Additional benefit is that at a reduction rate like this you get a pretty smooth transition. Additionally your approach potentially wastes a lot of “mesh” on ~flat areas whereas the highest ammount of details is retained when using the proOptimize modifier.

Additional tips and clarifications:

LODs should be reduced successively in complexity. For Example:
– LOD0 has 1000 tris
– LOD1 has 500 tris
– LOD2 has 250 tris
– LOD3 has 125 tris

While you can theoretically use as many LODs as you want you should keep in
mind they have to be kept in memory and on the storage medium, therefore it’s
advised to stay between 2 and 6 LODs depending on LOD0’s complexity.

Lower level LODs should use separate materials utilizing simpler shaders and less
effect-maps. They should however use the same textures (MipMapping will reduce
them automatically) For Example:
– LOD0 has Material001 with BumpedSpecular shader
– LOD1 has Material002 with Specular shader
– LOD2 has Material003 with Diffuse shader
– LOD3 has Material003 with Diffuse shader

edit: totally forgot to mention that the proOptimize mod has a property to “protect borders”

Thanks a lot!

That’s also what I meant with gaps. If you already have a height map I would seriously consider doing the displacement in realtime in Unity instead of in max.

This image kind of illustrates the idea of the tesselation reduction in the distance:

Thanks, but I need 100% control on the mesh which is impossible with UnityTerrain…