secret to terrain shader

Hi

Since unity 4.x you can have your own material assigned to the base terrain. This is great because I can just drag my own in there.

The problem is that once you hit the base distance, it flips to the default replacement shader.

In my case, I see the near terrain looking fine with my shader but the distant terrain is just blank, as if it failed to use any material.

What’s the trick/secret to get the terrain to either continue using my material after the base distance or use another one (maybe regular diffuse) instead of switching to black?

I suspect it depends how you’re sending the textures to your shader. So long as you’re using the same property name for the texture as the original terrain shader uses, it should hopefully pick them up.

Yep and it picks them up in the near distance but it seems it automatically switches to a different shader when far away and it is not picking the base texture for that one

You must pass _MainTex for basemap as well.

I do
this is my shader, it works fine on near distance, then it goes black on far… i don’t know what step i’m missing for the terrain to replace the far one correctly:

Shader “Blend 2 Textures”
{
Properties {
_Blend (“Blend”, Range (0.001, 1) ) = 0.5
_MainTex (“BaseMap (RGB)”, 2D) = “white” {}
_Texture2 (“Texture 2”, 2D) = “”

}
SubShader {
Tags { “RenderType”=“Opaque” }
// LOD 150
Cull Back

CGPROGRAM
#pragma surface surf Lambert halfasview approxview

sampler2D _MainTex;
sampler2D _Texture2;
fixed _Blend;

struct Input {
float2 uv_MainTex;
float2 uv_Texture2;
};

void surf (Input IN, inout SurfaceOutput o) {
fixed4 c1 = tex2D(_MainTex, IN.uv_MainTex);
fixed4 c2 = tex2D(_Texture2, IN.uv_Texture2);
o.Albedo = (c1.rgb * (1-_Blend)) + (c2.rgb * (_Blend));
o.Alpha = c1.a * c2.a;
}
ENDCG
}

Fallback “Diffuse”
}

for what i can see, it looks as if the maintex is completely ignored, even on close up.

Hi,

Unity uses a different shader for rendering the basemap (low res terrain). However you can supply your own shader by setting it as a dependency in the first-pass shader. For example, in my terrain shaders I require a custom AddPass and Basemap so add these lines to the bottom of the shader (I place them just above the fallback directive)

Dependency “AddPassShader” = “MyShaders/Terrain/Editor/AddPass”
Dependency “BaseMapShader” = “MyShaders/Terrain/Editor/BaseMap”

However, if you just want your one shader to always be used then you could simply set the basemap distance - in the terrain inspector - to very far away so the basemap version of the terrain is never rendered.