Search Unity

Quad decal on uneven terrain

Discussion in 'Shaders' started by VictorKs, Nov 3, 2019.

  1. VictorKs

    VictorKs

    Joined:
    Jun 2, 2013
    Posts:
    242
    How can I make a quad follow terrain shape? Is there a gpu solution? Maybe sampling terrain heightmap and transforming decal vertices?

    I've read about projectors but I've never worked with them but I believe they may be too heavy performance wise.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    The legacy projectors work by re-rendering the entire mesh that's being cast upon. For terrain this is obviously bad since the entire terrain is getting re-rendered in this case, regardless of how big the projector is. A single footstep or fake cloud shadows, both re-render the entire terrain mesh.

    The "best" solution is to use deferred decals, which use the depth texture and a projection matrix (or just a box) to project a texture onto the world position derived from the depth texture. This works well if you're already doing deferred rendering or on a PC where the depth texture is most likely already being generated.

    On mobile ... there's not really a good GPU option.

    If you just need a single projected shape, then using a custom shader on the terrain that adds a single offset texture is a good option. If you need several projected, then having a render texture that you render them all into, and then sample that single render texture in the custom terrain shader is a good option.

    Or just put a quad roughly above the terrain using a c# script. GetInterpolatedHeight() is pretty fast.
     
    VictorKs likes this.
  3. VictorKs

    VictorKs

    Joined:
    Jun 2, 2013
    Posts:
    242
    Thanks a lot for explaining my options, I finally went with simple quads because my terrain is forward rendered.
     
  4. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    There's also a "hacky" approach for the forward render path that Easy Decals do. Re-projecting mesh on top (similar to deffered rendering), and baking results into a mesh.

    Works pretty well even on mobile. (Baking takes some processing power, but after that its just a mesh)