Unity custom terrain shader - height-based blending + triplanar projection + single pass

edited in Projects
image

Introduction

I've been working on this custom terrain shading system for Unity 5.5 to improve two aspects of the built-in Unity terrain: texture stretching on vertical terrain, and overly simplistic linear blending between textures.

This is used in our game, INFINITE

Open source?

I'm thinking of possibly going open source with this, if it will help anyone else and if there is enough demand for this. Right now, it's not in any state to pass on to anyone, because the tooling isn't polished enough and the shader makes some hard-coded assumptions, like using 8 splat maps.

Please let me know your thoughts on this.

Background, and why a custom shader

There are some tools on the Unity Asset Store that is far more advanced - specifically RTP 3.3.

However, for 3 reasons I finally decided to create this from scratch, instead of using RTP:
- I had some some technical issues with RTP in Unity 5.5 that I ultimately was unable to resolve.
- RTP is very complex - probably too complex for what I needed for INFINITE.
- We use a custom lava shader on a plane that blends seamlessly into the terrain at its edge. This fake terrain edge has to exactly match the actual terrain look. The custom RTP shader would never exactly match that visually.

Technical / details

This shader can render the terrain with 8 splat maps in a single pass. It does this by taking the Unity terrain textures and packing them into various atlases and combined maps. So overall, the sampler count is reduced enough so that the terrain can be rendered in a single pass.

For the shader to function, you need not only the regular colour map and normal map, but also a height map. Optionally, you can add smoothness maps as well (usually placed in the colour map's alpha channel for the standard Unity terrain shader.) I'm using materials from gametextures.com, which includes everything that is required.

image

Height-based blending:

image

The overall blending is still controlled by Unity's splat blending maps, but the blending now also takes into account the relative height of any given pixel. The height based blending is based on a fairly simple approach of applying both a power and a multiplier to the height value to determine the blend strength relative to other textures.

image

Triplanar projection:

image

This gets rid of any stretching by projecting the texture on 3 planes. Not much else to say about it really.

Known issues

- Performance concerns. Optimisation is needed, although I'm still getting 90fps in INFINITE without any optimisations.
- Atlas rendering breaks at lower MIP levels. Will need to manually pick the MIP level.
- The system needs to work with a variable number of terrain textures, not just 8.
- The tools need some work.



Comments

  • I mean, we'd totally use it. Provided it doesn't cause performance degradation as with RTP (too heavy to use on the Vive right now). It looks really nice!
    Thanked by 1mgeorgedeveloper
  • Wow, it looks amazing, great work! (also saw the texturing work, effects and overall art in the gameplay trailer and it looks superb!)

    I'm jealous, I'd really love to try your shader, lol. I'm mostly a designer/writer and a bit of an artist, almost always working alone, and getting technology is the most difficult for me. I know some c#, and I've been coding my game for the past six moths or so (in spare time from day job). But lately I notice I spend more time coding than writing or designing or doing the art for my game... then I also remember I know nothing about shader programming (plus I've no time to learn it, since I also have to do everything else in my project). So a lot of important tech is out of my reach. And I'm sure it's the same for a lot of people starting out. I really wish Unity would actually have some features like this built-in, like part of the defaults (seeing how practically anyone using terrains needs a triplanar shader with height blending...), but seeing how they don't, people like me can only depend on the generosity of knowledgeable people like you.

    I really hope you decided on making this effect open source. I don't mind if it's not perfect (and I'm sure others would say the same). That would just help a ton of people. Hopefully when I actually make some money from a project or something, I can at least drop by to make you a donation. And who knows, maybe others would do the same too.

    Anyway, take care and I hope your game did well.
  • YES... please share...!
    Thanked by 1mgeorgedeveloper
  • @Alverik @UberGeoff @jackshiels

    Thanks for the feedback!

    Yes, I will probably give this out for free in the form of open source or a free Asset Store package.

    My only problem right now is timing. Before I can release this, I need to improve the Unity UI aspects first (I won't explain here, but it's definately needed). It would also not hurt to deal with some performance / other small issues first too.

    However, I cannot get to this until our game is out, because I'm now in a permanent kind of panicked crunch mode to get the game done for several platforms. I'm looking at a mid September date probably.

    So maybe 3 months down the line, Unity has something simple-to-use like this built in. If not, I will send this thing out.

    I will keep you posted here :)
    Thanked by 2dammit Alverik
  • edited
    Cool :) Will wait with bated breath! And good luck with the release!
  • edited
    Some minor upgrades made to the custom shader. Better results and also a bit faster.

    image

    farflunggames.com/download/ID-terrain-shader-upgrade.png
    Thanked by 2Alverik UberGeoff
  • Superb! (And, as usual, love the color and detail.)
  • edited
    Hi all, the shader system has now been extended to apply to meshes, with smooth blending between terrain and meshes as well:

    image
    Thanked by 1Alverik
  • Wow, that's seriously great stuff! Mesh blending looks amazing :)
    Thanked by 1[Deleted User]
  • Holy cow this is beautiful stuff :O
    Thanked by 1Alverik
  • Here is another trick that I layer over the custom shader stuff.

    In summary... use some terrain height maps (let's say, dunes or some eroded rocky surface) as brushes to shape Unity's terrain surface. Then, use matching normal maps to project deferred decals onto the terrain. I'm using Dynamic Decals from the Unity Asset Store (with some modifications):

    https://twitter.com/infingame/status/992362463336288256

    (Sorry for the twitter link, it's just more convenient than uploading the same three images elsewhere right now)
  • All your images in this thread are broken for me.
  • edited
    @critic correct - sorry. We just did a website migration. Let me see if I can get all those fixed.

    (they're quite dated, but I will also drop a few new ones here today)

    Update:

    Fixed!

    But I'm also uploading some recent images/results now.
  • Some updated screenshots with explanatory descriptions:

    image
    image
    image
    image
    Thanked by 2critic jamotaylor
  • edited
    I'm still hoping to open source both the custom terrain stuff and the mesh blending stuff, but it will need some more work to make it more end-user friendly, and I'm not much motivated to polish it to that level unless someone else wants to manage the open source side of it, with me being a contributor doing dev on it. Thoughts?

    (Note - by end-user, I mean developers making games in Unity)
  • I'm also hoping you end up open sourcing this.

    Have you had a look at the new scriptable render pipeline? Maybe even the Lightweight render pipeline?

    Does this mean that terrain rendering/etc. is less of a black-box now?
  • gl33mer said:
    I'm also hoping you end up open sourcing this.

    Have you had a look at the new scriptable render pipeline? Maybe even the Lightweight render pipeline?

    Does this mean that terrain rendering/etc. is less of a black-box now?
    I haven't looked at SRP in detail yet - but I'm pretty sure the same old clunky terrible terrain system is exactly as before. I think the new scriptible pipelines just come with new variations of the shaders. The core data is the same as before.





  • I'm not certain but I think the transfer of the old terrain shader, etc. is part of a wip. The render pipeline being scriptable, I assume we'll have more control....but I also haven't gotten to it.

Sign In or Register to comment.