Search Unity

Need a faster terrain shader

Discussion in 'Shaders' started by mrtkhosravi, Sep 16, 2017.

  1. mrtkhosravi

    mrtkhosravi

    Joined:
    Nov 9, 2014
    Posts:
    198
    I want to render a terrain with multitexturing. There is a pack of like 8 texture that can be vertex painted on terrain mesh. The weight of each textures for a particular vertex is stored in a collection of alpha maps. We store the 8 albedo and 8 normalmap textures in a texture array. In the shader we sample alphamaps and multiply albedo and normal maps by the corresponding alphamap component.

    albedo+ = alphamp.x * texArray.Sample(uv1); //uv for the first texture
    albedo+ = alphamp.y * texArray.Sample(uv2);//uv for the second texture
    ....


    This is done for 8 texture. Same thing happens for normalmaps. This works but it kills the memory bandwidth and the framrate drops dramatically. Also I want to use advanced height based blending like figure 1 and this strategy has no easy way to determine the most prominent texture in the fragment.

    000877.png

    And another thing is I'll probably multi blend to reduce the tiling visiblity so a a texture will be sampled once with regular uv and once with uv * 4 and then I'll blend these to valuse by a factor. The total number of samples will be 8 * 3. And with triplanar sampling the toll goes up to 8 * 3 * 3 = 72.

    Is there a faster and more flexible strategy to render the terrain?

    The whole process of creating mesh, alphamaps, and the software environment is managed by us so there is no restriction in that regard. Everything that is faster works for us.
     
  2. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Use microsplat, it's honestly the best terrain one can achieve in Unity for performance and so forth. If using assets is out then I can't help and I apologise.
     
    jbooth and mrtkhosravi like this.
  3. mrtkhosravi

    mrtkhosravi

    Joined:
    Nov 9, 2014
    Posts:
    198
    That's a big endorsement coming from you. I'll check it out.
     
    Harry1960 likes this.
  4. gecko

    gecko

    Joined:
    Aug 10, 2006
    Posts:
    2,241
    +1 for MicroSplat: super easy to use, plus lots of effects and amazing performance.
     
  5. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Actually, your count would be 96 or 144 depending on how you pack your textures, with 2 samples for your control maps. MicroSplat will do the same thing in as little as 18 samples per pixel, but with 16 textures instead of 8. (pack Diffuse/Height/Normal/Smoothness/AO into 2 texture arrays with triplanar texturing and distance resampling).

    I have an idea of how to reduce this further (roughly half), but I need like a week alone somewhere with a whiteboard and no distractions to work out the math. Or maybe I'll do it on the plane to Unite..
     
    Last edited: Sep 20, 2017
    mrtkhosravi, Martin_H and hippocoder like this.
  6. Scheitler

    Scheitler

    Joined:
    Jul 25, 2017
    Posts:
    20
    That is a lot of what you want to include into your shader as you will probably never render all 8 textures in one fragment. This solution might require a custom terrain but I want to throw it in the hat for you.

    You would need a tiled based terrain engine which would be smart enough to detect which tiles include which set of textures and it would paint a splat map and assing the textures accoridngly. Your shader would be limited to say 3 or 4 textures but as you can patch them next to each other it wouldn't be vissible. The pro side is that you have no limit on how many textures you use on the terrain in total.

    This technique was used long ago in RTS games or more recently in basically any game with large terrains that don't use megatextures. There was an article of a racing game with a huge map but I can't find it anymore. (If somebody knows it).
     
    Last edited: Sep 20, 2017
    mrtkhosravi likes this.
  7. mrtkhosravi

    mrtkhosravi

    Joined:
    Nov 9, 2014
    Posts:
    198
    That's very nice. Thanks for the info.
     
  8. mrtkhosravi

    mrtkhosravi

    Joined:
    Nov 9, 2014
    Posts:
    198
    That's a good idea. But it either needs a completely new terrain system or limits the way artists can work on the terrain. I could not imagine someone could create a better version than unity terrain. Unity terrain's editing features and API are horrible but when it comes to runtime performance and memory management, it's ahead of any custom terrain system you could imagine.
     
  9. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    Oh my god, no. Unity Terrain is horrible. If Unity would give us access to the heightmap collider it uses for physics, the whole system could be replaced with something much more efficient easily.

    Unity terrain draws the terrain once for each set of 4 textures on it. That means if you have 16 textures, it draws the terrain 4 times. It stores the weights for each set of 4 textures in another texture - so if you have 16 textures, you have four giant textures storing those weights. In MegaSplat, I draw up to 256 textures in a single pass with a single control texture. To do that in Unity's tech, you would need to draw the terrain 64 times with 64 control textures. Not to mention Unity terrain doesn't really even work with 16 textures correctly, since you can't blend a full PBR workflow across multiple passes like that. And that's just the texturing part of it, the rest of it is just about as broken.
     
  10. Scheitler

    Scheitler

    Joined:
    Jul 25, 2017
    Posts:
    20
    Can you explain in short how you do this? Isn't it a similar technique as I have described above by limiting the maximum textures per area? Or am I missing something?
    EDIT: I think I have an idea. I have to look into texture arrays, this is neat stuff.
    So you can use this tile system I mentioned without changing the mesh or material data, that is great!

    Unity terrain is actually pretty basic. I know that terrain creation is not easy with advanced techniques and it works fine for most use cases. But individual games in my view require individual terrain systems. For instance you can't create a spherical terrian, so you would need your own system for that. There are many different terrain algorithms out there and each could be implemented in Unity. But on the other hand of course this would be a lot of extra work if you need the vegetation system and the like.
     
    Last edited: Sep 21, 2017
  11. mrtkhosravi

    mrtkhosravi

    Joined:
    Nov 9, 2014
    Posts:
    198
    Well, I am developing a terrain engine package like GAIA, MapMagic,... so these problems occurred to me also. At a time I went for total replacement of terrain engine but failed. So I made a terrain system for editing purposes which is pure mesh + tessellation based and rely on unity terrains for runtime. I am a huge fan of unity terrains at runtime. With the LOD, lightmapping, trees, vegetation, physx, memory management, no HW requirement, support on any platform, ... I mean come on.

    On the second issue I totally agree. The terrain default shader can be very slow with additional textures and that's where awesome packages like yours shine. In this particular matter I did manage to create a fast, simple shader as a basic solution. I am not interested in supporting more feature-rich shaders right now so when the product is ready maybe we could find a way to integrate and endorse each other's packages.
     
  12. mrtkhosravi

    mrtkhosravi

    Joined:
    Nov 9, 2014
    Posts:
    198
    I understand your point. The thing is for 99 percent of games a faster solution is better than more complete and slow. Yes for a galaxy simulation you need you own solution but in general using terrain unity as a flat solution should be perfectly fine. At first I did not have a positive view of unity terrains but as time went I realized it is a very painless work. If you can forgive some minor annoying details and use supplementary packages like Jason's work, It really works fast and seamlessly on any platform and any hardware. This is why I respect it.
     
  13. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,461
    In theory it's quite simple and well talked about in my development videos and documentation; the file format for a terrain or mesh at each control point is basically 2 texture indexes into the texture array and a blend weight between them. But like many things, the devil is in the details of how you actually make that work, because interpolation fights against you in this case.