Shader to show change in elevation on a tile based grid mesh

Hi,

I am new to shaders and I think I’m missing something…

I have a mesh that represents a game map, it is tile based and each tile has 9 vertices and 8 triangles. Each tile was originally 4 vertices and 2 triangles but I up’d it to try and help with the shader (to no avail…). The next tile shares the joining vertices with the previous tile.

The elevation of each tile can be set as -1, 0, 1, 2, 3 or 4, this is the y height of the vertices. If a tile is at a different elevation to the next tile then the next tile is on a slope between the elevations. I’ve attached an image showing the tiles.

I want to create a shader that can set a different texture for each elevation level and also a texture for slopes. I’ve tried using input.worldPos and input.worldNorma in void surf but not getting the results I expected. Whatever I try, I end up getting two textures over the top of each other (attached image).

I tried to use the normal value to set the slope as a different texture. This didn’t work and the texture only changed when the _n was set to 1, then the whole mesh changed texture (flat and slope).

       void surf (Input IN, inout SurfaceOutputStandard o)
        {
            // _n is a float value between -1 and 1 that I used as a normal limit
            // Tex is a sampler2D texture
            // _b is a float value between 0 and 1 for brightness

            if (IN.worldNormal.y > _n)
            {
                c = tex2D(_AngleTex, IN.uv_AngleTex);
                c *= _b4;
                o.Albedo = c;
            }
            else
            {
                c = tex2D(_MainTex, IN.uv_MainTex);
                c *= _b1;
                o.Albedo = c;
            }
}

I tried if the input.worldPos.y was the same as an elevation level set as the flat texture, if not set as slope. I thought that the vertex on the slope would be the slope texture as the y position is not equal to an elevation level. This resulted in any elevation level above 0 being both textures but the slope being the slope texture.

if (IN.worldPos.y == 0 || IN.worldPos.y == 1 || IN.worldPos.y == 2 || IN.worldPos.y == 3 || IN.worldPos.y == 4)
            {
                c = tex2D(_MainTex, IN.uv_MainTex);
                c *= _b1;
                o.Albedo = c;
            }
            else
            {
                c = tex2D(_AngleTex, IN.uv_AngleTex);
                c *= _b4;
                o.Albedo = c;
            }

I tried just setting the different levels to different textures, but this also resulted in two textures overlapping on anything above 0.

if ((int)IN.worldPos.y - IN.worldPos.y != 0)
            {
                c = tex2D(_AngleTex, IN.uv_AngleTex);
                c *= _b4;
                o.Albedo = c;
            }
            else
            {
                if (IN.worldPos.y > 3.5)
                {
                    c = tex2D(_TopTex, IN.uv_TopTex);
                    c *= _b3;
                    o.Albedo = c;
                }
                else if (IN.worldPos.y <= 3.5 && IN.worldPos.y > 1.5)
                {
                    c = tex2D(_RaisedTex, IN.uv_RaisedTex);
                    c *= _b2;
                    o.Albedo = c;
                }
                else // if (IN.worldPos.y <= 1.5)
                {
                    c = tex2D(_MainTex, IN.uv_MainTex);
                    c *= _b1;
                    o.Albedo = c;
                }
               
            }

How can I create a shader to texture each level of elevation a different texture and also texture the slopes a different texture? Is a shader the right way to go? Would creating submeshes be another way to go? The elevation changes during runtime so setting submeshes would be a bit annoying.

8225289--1074390--2textures.PNG

I ended up giving up on the shader. I used a tiled texture and shared vertices on the tiles. I check if the tile is on a slope and the elevation and set the uvs to suit an area of the tiled texture.

I quite like the result and also reduced the vertices count to 4 per tile. The most annoying part was updating the shared vertices’ positions but it wasn’t too bad…