Weird artifacts in cg shader with lerp()

Hello there,

I’m making a shader that takes the height of the world and matches it with a certain texture. Between each defined height there is a blend zone that blends two textures with a lerp from 0 to 1.

The shader is working perfect except for 1 thing, the lerp function adds a weird line of artifacts at the edge of each blend zone, as you can see on the screenshot below:

28437-shader_artifacts_1.jpg

The weird thing is, this shader works perfectly with pragma target 2.0 but doesn’t with pragma target 3.0. Sadly I have to use target 3.0 because the 2.0 runs out of memory if I use more than 3 textures…

My question is, how can I resolve the artifacts in 3.0 or is it possible to make this shader in 2.0 with some optimization?

Any help is greatly appreciated, thank you :slight_smile:

Edit

I’ve applied the shader to a simple cube and noticed the artifacts only appear after a certain distance from the camera. Close to the camera everything looks ok and the blending is smooth… Does anyone have an idea what this could be? I think it might have something to do with LOD but don’t know how to fix this…

See screenshot below:

28459-shader_artifacts_2.jpg

The code for the shader is as follows:

Shader "Custom/TerrainHeight"
{
    Properties
    {
        _Color("Color",Color) = (1.0,1.0,1.0,1.0)
        _GroundHeight ("GroundHeight", Float) = 0
        _FadeDistance ("FadeDistance", Float) = 0.5
        _Height1 ("Height1", Float) = 2
        _Height2 ("Height2", Float) = 4
        _Height3 ("Height3", Float) = 6
        _Tex1("Tex1", 2D) = "white"{}
        _Tex2("Tex2", 2D) = "white"{}
        _Tex3("Tex3", 2D) = "white"{}
        _Tex4("Tex4", 2D) = "white"{}
    }
    SubShader
    {
    	Tags { "RenderType" = "Opaque" }
       
        CGPROGRAM
        #pragma surface surf Lambert
        #pragma target 3.0
       
        float _GroundHeight;
        float _FadeDistance;
        float _Height1;
        float _Height2;
        float _Height3;
        float4 _Color;
        sampler2D _Tex1;
        sampler2D _Tex2;
        sampler2D _Tex3;
        sampler2D _Tex4;
 
        struct Input
        {
            float3 customColor;
            float3 worldPos;
            float2 uv_Tex1;
            float2 uv_Tex2;
            float2 uv_Tex3;
            float2 uv_Tex4;
        };
 
        void surf (Input IN, inout SurfaceOutput o)
        {    
			o.Albedo = tex2D(_Tex1, IN.uv_Tex1).rgb;
 
            if(IN.worldPos.y > _GroundHeight && IN.worldPos.y < _Height1-_FadeDistance)
            {
            	o.Albedo = tex2D(_Tex1, IN.uv_Tex1).rgb;
            }
            else if(IN.worldPos.y >= _Height1-_FadeDistance && IN.worldPos.y <= _Height1)
            {
            	fixed4 tex1 = tex2D(_Tex1, IN.uv_Tex1);
            	fixed4 tex2 = tex2D(_Tex2, IN.uv_Tex2);
            	fixed4 output = lerp(tex1,tex2,(IN.worldPos.y-(_Height1-_FadeDistance))/_FadeDistance);
            	o.Albedo = output.rgb;
            }
            else if(IN.worldPos.y > _Height1 && IN.worldPos.y < _Height2-_FadeDistance)
            {
            	o.Albedo = tex2D(_Tex2, IN.uv_Tex2).rgb;
            }
            else if(IN.worldPos.y >= _Height2-_FadeDistance && IN.worldPos.y <= _Height2)
            {
            	fixed4 tex2 = tex2D(_Tex2, IN.uv_Tex2);
            	fixed4 tex3 = tex2D(_Tex3, IN.uv_Tex3);
            	fixed4 output = lerp(tex2,tex3,(IN.worldPos.y-(_Height2-_FadeDistance))/_FadeDistance);
            	o.Albedo = output.rgb;
            }
            else if(IN.worldPos.y > _Height2 && IN.worldPos.y < _Height3-_FadeDistance)
            {
            	o.Albedo = tex2D(_Tex3, IN.uv_Tex3).rgb;
            }
            else if(IN.worldPos.y >= _Height3-_FadeDistance && IN.worldPos.y <= _Height3)
            {
            	fixed4 tex3 = tex2D(_Tex3, IN.uv_Tex3);
            	fixed4 tex4 = tex2D(_Tex4, IN.uv_Tex4);
            	fixed4 output = lerp(tex3,tex4,(IN.worldPos.y-(_Height3-_FadeDistance)/_FadeDistance);
            	o.Albedo = output.rgb;
            }
            else if(IN.worldPos.y > _Height3)
            {
            	o.Albedo = tex2D(_Tex4, IN.uv_Tex4).rgb;
            }
            
            o.Albedo *= _Color.rgb;    
        }
        ENDCG
    }
    FallBack "Diffuse"
}

Your fade “t” value is between “0” and “_FadeDistance” and not between 0 and 1. You have to divide it by _FadeDistance.