Use a clipping mask to hide some part of the Unity terrain

Hi,
I would like to use a mask to cut holes in the Unity terrain, is it even possible and if yes, how to do it ?
The idea is to generate this kind of texture (image 1) with a script, and then to use this texture in the terrain shader in order to discard the pixels where there is roads (yellow and red lines).

This way I would be able to hide the terrain under my roads (just like image 2)
Roads are procedurally generated so the mask should be updated each time the road network is modified.

Why would you want to go through the hassle of making the terrain invisible under the road in the first place?

Because I want the road to be slightly lower than the terrain, and the sidewalk to be at the exact same level as the terrain (just like here in Cities Skylines). Also this would prevent the terrain from poking through roads in some cases when the terrain is not flat.7265422--876844--Screenshot_31.png

Hi! Just saw this, would something like the tool featured in this video work?

I already saw this video. I think I did the same thing as he did in the video but it did not work in my case. Idk why.

But I managed to generate by script the texture to use as a clipping mask in the terrain shader. Now I need to use this texture in the terrain shader in order to hide the terrain where there is red pixels. So I made this function in my terrain script :

    public static void UpdateClippingMask()
    {
        Texture2D texture = Singleton<OrthoCamera>.instance.Capture();
        terrain.materialTemplate.SetTexture("_ClipMask", texture);
    }

But now I don’t know what to do with this texture in the terrain shader (both the texture and the terrain have a size of 512) 7266307--876988--Screenshot_29.jpg

I’m not the most familiar with shaders, but the gist of it would be this:

  • Create a new Shader using the shader graph
  • Take the A (alpha) value from your _MainTex RGBA value (which is the texture you’re putting it on)
  • Subtract your texture’s R value from that
  • Plug it back into the _MainTex’s output

You might want to check out the shader forum for help if you need more clarification.

Something like this ? Changing the value of o.Alpha does not seem to have any effect

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_Control) * _Color;
            fixed4 clipMask = tex2D (_ClipMask, IN.uv_Control);
            o.Albedo = _MainColor;
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a - clipMask.r;
        }

My best guess is that you didn’t set the Tags correctly, but I could be wrong since I can’t see the whole script. I don’t know enough about HSLS to help you too much though, I would recommend using Unity’s built in Shader Graph tool to create this, as writing your own shader which is affected by lighting is a headache.

I believe looking through this video you can find all the things you need to make your own shader for this specific thing.

https://www.youtube.com/watch?v=taMp1g1pBeE

I think I may not need ShaderGraph, all I had to do is to use the clip function in the shader of the terrain :

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_Control) * _Color;
            fixed4 clipMask = tex2D (_ClipMask, IN.uv_Control);
            o.Albedo = _MainColor;
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
            clip(-clipMask.r);
        }

But now there’s still one problem : it seems like there is no texture filtering on the clipping mask so the shape of the hole is jagged : 7269091--877585--Screenshot_77.jpg
instead the hole should be like this : 7269091--877588--Screenshot_33.png

Here’s a screenshot with the wireframe : 7269091--877591--Screenshot_78.png