I’ve been adventuring myself in scripting shaders for unity, followed some tutorials, made some on my own and finally tried to adventure into making a terrain shader.
So I’ve looked into this tutorial :
Looked the builtin shaders…
And found this article on Gamasutra:
And tried to make a new terrain shader.
But I’m having trouble with the AddPass shader, it’s not working. Tried a lot of things and still didn’t work. It seems like it’s falling back and when I remove the fallback it just paints all the textures from the first pass all mixed up.
Here’s a screenshot:
Is there a way to fix these so I can have more than 4 textures in my terrain?
Here are the shaders (did not apply normal maps yet):
FirstPass shader:
Shader "Raed Wulf/Terrain/BlendTexture" {
Properties{
//control splat map
[HideInInspector] _Control("Control (RGBA)", 2D) = "red" {}
//textures Alpha is height
[HideInInspector] _Splat3("Layer 3 (A)", 2D) = "white" {}
[HideInInspector] _Splat2("Layer 2 (B)", 2D) = "white" {}
[HideInInspector] _Splat1("Layer 1 (G)", 2D) = "white" {}
[HideInInspector] _Splat0("Layer 0 (R)", 2D) = "white" {}
//normal maps
[HideInInspector] _Normal3("Normal 3 (A)", 2D) = "bump" {}
[HideInInspector] _Normal2("Normal 2 (B)", 2D) = "bump" {}
[HideInInspector] _Normal1("Normal 1 (G)", 2D) = "bump" {}
[HideInInspector] _Normal0("Normal 0 (R)", 2D) = "bump" {}
// used in fallback on old cards & base map
[HideInInspector] _MainTex("BaseMap (RGB)", 2D) = "white" {}
[HideInInspector] _Color("Main Color", Color) = (1,1,1,1)
}
SubShader{
Tags{
"SplatCount" = "4"
"Queue" = "Geometry-100"
"RenderType" = "Opaque"
}
CGPROGRAM
#pragma surface surf Lambert exclude_path:forward
#pragma multi_compile_fog
#pragma target 3.0
// needs more than 8 texcoords
#pragma exclude_renderers gles
#include "UnityPBSLighting.cginc"
// Access the Shaderlab properties
uniform sampler2D _Control;
uniform sampler2D _Splat0,_Splat1,_Splat2,_Splat3;
// Surface shader input structure
struct Input {
float2 uv_Control : TEXCOORD0;
float2 uv_Splat0 : TEXCOORD1;
float2 uv_Splat1 : TEXCOORD2;
float2 uv_Splat2 : TEXCOORD3;
float2 uv_Splat3 : TEXCOORD4;
};
float4 blend(float4 texA, float aA, float4 texB, float aB)
{
float depth = 0.1;
float ma = max(texA.a + aA, texB.a + aB) - depth;
float b1 = max(texA.a + aA - ma, 0.0);
float b2 = max(texB.a + aB - ma, 0.0);
return (texA * b1 + texB * b2) / (b1 + b2);
}
// Surface Shader function
void surf(Input IN, inout SurfaceOutput o) {
fixed4 tex0 = tex2D(_Splat0, IN.uv_Splat0);
fixed4 tex1 = tex2D(_Splat1, IN.uv_Splat1);
fixed4 tex2 = tex2D(_Splat2, IN.uv_Splat2);
fixed4 tex3 = tex2D(_Splat3, IN.uv_Splat3);
fixed4 splat_control = tex2D(_Control, IN.uv_Control);
fixed4 col;
col = blend(tex0, splat_control.r, tex1, splat_control.g);
col = blend(col, splat_control.r + splat_control.g, tex2, splat_control.b);
col = blend(col, splat_control.r + splat_control.g + splat_control.b, tex3, splat_control.a);
o.Albedo = col.rgb;
o.Alpha = col.a;
}
ENDCG
}
Dependency "AddPassShader" = "Hidden/Raed Wulf/Terrain/BlendTexture-AddPass"
Dependency "BaseMapShader" = "Diffuse"
Fallback "Nature/Terrain/Diffuse"
}
AddPass Shader:
Shader "Hidden/Raed Wulf/Terrain/BlendTexture-AddPass" {
Properties{
//control splat map
[HideInInspector] _Control("Control (RGBA)", 2D) = "red" {}
//textures Alpha is height
[HideInInspector] _Splat3("Layer 3 (A)", 2D) = "white" {}
[HideInInspector] _Splat2("Layer 2 (B)", 2D) = "white" {}
[HideInInspector] _Splat1("Layer 1 (G)", 2D) = "white" {}
[HideInInspector] _Splat0("Layer 0 (R)", 2D) = "white" {}
//normal maps
[HideInInspector] _Normal3("Normal 3 (A)", 2D) = "bump" {}
[HideInInspector] _Normal2("Normal 2 (B)", 2D) = "bump" {}
[HideInInspector] _Normal1("Normal 1 (G)", 2D) = "bump" {}
[HideInInspector] _Normal0("Normal 0 (R)", 2D) = "bump" {}
// used in fallback on old cards & base map
[HideInInspector] _MainTex("BaseMap (RGB)", 2D) = "white" {}
[HideInInspector] _Color("Main Color", Color) = (1,1,1,1)
}
SubShader{
Tags{
"SplatCount" = "4"
"Queue" = "Geometry-99"
"IgnoreProjector" = "True"
"RenderType" = "Opaque"
}
CGPROGRAM
#pragma surface surf Lambert exclude_path:forward decal:add
#pragma multi_compile_fog
#pragma target 3.0
// needs more than 8 texcoords
#pragma exclude_renderers gles
#include "UnityPBSLighting.cginc"
// Access the Shaderlab properties
uniform sampler2D _Control;
uniform sampler2D _Splat0,_Splat1,_Splat2,_Splat3;
// Surface shader input structure
struct Input {
float2 uv_Control : TEXCOORD0;
float2 uv_Splat0 : TEXCOORD1;
float2 uv_Splat1 : TEXCOORD2;
float2 uv_Splat2 : TEXCOORD3;
float2 uv_Splat3 : TEXCOORD4;
};
float4 blend(float4 texA, float aA, float4 texB, float aB)
{
float depth = 0.1;
float ma = max(texA.a + aA, texB.a + aB) - depth;
float b1 = max(texA.a + aA - ma, 0.0);
float b2 = max(texB.a + aB - ma, 0.0);
return (texA * b1 + texB * b2) / (b1 + b2);
}
// Surface Shader function
void surf(Input IN, inout SurfaceOutput o) {
fixed4 tex0 = tex2D(_Splat0, IN.uv_Splat0);
fixed4 tex1 = tex2D(_Splat1, IN.uv_Splat1);
fixed4 tex2 = tex2D(_Splat2, IN.uv_Splat2);
fixed4 tex3 = tex2D(_Splat3, IN.uv_Splat3);
fixed4 splat_control = tex2D(_Control, IN.uv_Control);
fixed4 col;
col = blend(tex0, splat_control.r, tex1, splat_control.g);
col = blend(col, splat_control.r + splat_control.g, tex2, splat_control.b);
col = blend(col, splat_control.r + splat_control.g + splat_control.b, tex3, splat_control.a);
o.Albedo = col.rgb;
o.Alpha = 0.0;
}
ENDCG
}
Fallback "Hidden/TerrainEngine/Splatmap/Diffuse-AddPass"
//Fallback off
}
Thanks in Advanced!