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

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 Desolation

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 Desolation.
- 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 Desolation 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 1Alverik
  • Superb! (And, as usual, love the color and detail.)
Sign In or Register to comment.