HDRP Sort terrains or render / draw over terrain

How do I sort terrains in HDRP?

So what I want to do basically is the following:

I have a background terrain and multiple closeup terrains. I need to be able to draw the closeup terrains over the background terrains.
How can i achive this?

The background terrain is very low resolution because it includes all the smaller terrains

  • Tried the CustomPass component but couldn’t achive the desired effect without artifacts
  • Messed around with the TerrainLit shaders but i just can not find where could I include some code like:
    depth = (some big number or Infinite);

This one line could probably solve my problem but i am not that familiar with the GBuffer that the TerrainShader uses and all the HDRP shader stuff…

TLDR: On the second picture the background terrain is clearly visible on the closeup terrains that’s what has to be gone.

Without background terrain:


With background terrain:

I’d just use background meshes for this sort of thing. You can download the HDRP terrain sample to see how they did it in that project.

Just checked it out, the problem with that it basically renders it all the time, in our case you would be able to walk there so I have to disable the rendering of that part of the background terrain, and render only the specific closeup terrains near the player.

Also I got it working (sort of) with custom passes, but still have issues with the part where there is literally nothing between the camera and the background terrain so the background terrain gets rendered:

Btw these custom passes are making the transparent layers weird so this is not really a viable way of solving this issue…

From ground view:

Same spot from a slightly higher angle:

Btw if anyone interested in the custom pass settings:

You’d have to alter the terrain shader to do this effectively. You can nan any verts in the vertex shader to clip them out if they’re within a range you specify, with some code like:
if (all(1.0-saturate(abs(Position - _BoxPos) - abs(_BoxScale)))) discard;

        if (all(1.0-saturate(abs(Position - _BoxPos) - abs(_BoxScale)))) discard;

Where _BoxPos and _BoxScale are a box in world space and Position is your vert pos (interpolated or otherwise).

Failing this you can seriously abuse terrain holes to do a similar thing.

Hey @hippocoder

That’s exactly what I need.
But i just have no idea where to insert that into the TerrainLit shader…

My logic is that I make a pass before the other passes in the TerrainShader where I run your code and discard the particular vertices.
First of all I have no idea what are the return and input types

I also declared the properties (that’s the only thing I understand from HDRP shaders) every other thing is hidden by tons of includes

So far I made this (But it’s giving me errors):

            Pass
            {
                VertexDescriptionInputs Vert(VertexDescriptionInputs IN) {
                    if (all(1.0 - saturate(abs(Position - _BoxPos) - abs(_BoxScale)))) discard;
 
                    return IN;
                }
            
                #pragma Vert
            }

For structure etc…

I did mine in shadergraph (custom function node) so I’m not sure how to help or have enough time for manual edits.

Sadly I would have to recreate the whole TerrainShader for that, if nothing works out I will do that and use a custom node too, but it would be great to fully understand how these passes work with each other.

Done!

The solution was your code snippet inserted into the good position.
-You have to copy the ShaderPassDepthOnly.hlsl
-Modify the Frag shader of your copy of the ShaderPassDepthOnly.hlsl
-Change the includes to this file (in the passes)
-Define that you need the absolute world space calculated #define VARYINGS_NEED_POSITION_WS

Code in the Frag shader:

    float3 vertexPosWS = GetAbsolutePositionWS(posInput.positionWS);
    if (all(1.0 - saturate(abs(vertexPosWS - _PlayerPosition) - abs(_BoxSize))))
    {
        discard;
    }