- Home /
Why wont the normals of my addpass terrain shader blend with the first pass?
So I've been deving a custom shader for Unity for quite some time now and have recently discovered a major bug with the blending between the Add pass and the First pass but it only applies in foreward rendering. I think the attached images will make the problem clear.
Deffered rendering (blending is fine)
Forward rendering (blending is buggy)
I am already certain that the problem is in the normals and not the albedo as I have experimented with disabling the normals of the shader and the problem disappears.
I will provide a truncated version of the shader and a demo scene which still exibits the same bug in forward rendering.
Shader "Custom/Terrain Shader Test First" {
Properties {
[HideInInspector] _Control ("Control (RGB)", 2D) = "red" {}
[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" {}
[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" {}
[HideInInspector] [Gamma] _Metallic0 ("Metallic 0", Range(0.0, 1.0)) = 0.0
[HideInInspector] [Gamma] _Metallic1 ("Metallic 1", Range(0.0, 1.0)) = 0.0
[HideInInspector] [Gamma] _Metallic2 ("Metallic 2", Range(0.0, 1.0)) = 0.0
[HideInInspector] [Gamma] _Metallic3 ("Metallic 3", Range(0.0, 1.0)) = 0.0
[HideInInspector] _Smoothness0 ("Smoothness 0", Range(0.0, 1.0)) = 1.0
[HideInInspector] _Smoothness1 ("Smoothness 1", Range(0.0, 1.0)) = 1.0
[HideInInspector] _Smoothness2 ("Smoothness 2", Range(0.0, 1.0)) = 1.0
[HideInInspector] _Smoothness3 ("Smoothness 3", Range(0.0, 1.0)) = 1.0
}
SubShader {
Tags {
"SplatCount" = "4"
"Queue" = "Geometry-100"
"RenderType" = "Opaque"
}
LOD 200
CGPROGRAM
#pragma surface surf Standard vertex:SplatmapVert fullforwardshadows //finalgbuffer:SplatmapFinalGBuffer
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
uniform sampler2D _Control;
sampler2D _Splat0,_Splat1,_Splat2,_Splat3;
sampler2D _Normal0,_Normal1,_Normal2,_Normal3;
half _Metallic0;
half _Metallic1;
half _Metallic2;
half _Metallic3;
half _Smoothness0;
half _Smoothness1;
half _Smoothness2;
half _Smoothness3;
struct Input {
float3 worldPos;
float2 uv_Control;
};
void SplatmapVert(inout appdata_full v, out Input data)
{
UNITY_INITIALIZE_OUTPUT(Input, data);
float4 pos = mul (UNITY_MATRIX_MVP, v.vertex);
//UNITY_TRANSFER_FOG(data, pos);
v.tangent.xyz = cross(v.normal, float3(0,0,1));
v.tangent.w = -1;
//data.projPos = ComputeScreenPos(pos);
//data.localPos = v.vertex.xyz;
}
void surf (Input IN, inout SurfaceOutputStandard o) {
fixed4 splatControl = tex2D(_Control, IN.uv_Control);
fixed4 splat0;
fixed4 splat1;
fixed4 splat2;
fixed4 splat3;
fixed4 normal0;
fixed4 normal1;
fixed4 normal2;
fixed4 normal3;
float2 _ScaledUV = IN.worldPos.xz / 50;
normal0 = tex2D(_Normal0, _ScaledUV);
normal1 = tex2D(_Normal1, _ScaledUV);
normal2 = tex2D(_Normal2, _ScaledUV);
normal3 = tex2D(_Normal3, _ScaledUV);
splat0 = tex2D(_Splat0, _ScaledUV);
splat1 = tex2D(_Splat1, _ScaledUV);
splat2 = tex2D(_Splat2, _ScaledUV);
splat3 = tex2D(_Splat3, _ScaledUV);
fixed4 blendSplat = splatControl;
int b1 = 1;
int b2 = 0;
int b3 = 0;
int b4 = 0;
fixed4 finalCol;
finalCol = blendSplat.r * splat0;
finalCol += blendSplat.g * splat1;
finalCol += blendSplat.b * splat2;
finalCol += blendSplat.a * splat3;
finalCol /= b1 + b2 + b3 + b4;
fixed4 nrm;
nrm = blendSplat.r * normal0;
nrm += blendSplat.g * normal1;
nrm += blendSplat.b * normal2;
nrm += blendSplat.a * normal3;
nrm /= b1 + b2 + b3 + b4;
half finalGloss = dot(blendSplat, half4(_Smoothness0, _Smoothness1, _Smoothness2, _Smoothness3)) / (b1 + b2 + b3 + b4);
fixed Alpha = dot(splatControl, 1);
nrm = (nrm*2)-1;
o.Normal = float3(nrm.rg, 1);
o.Albedo = finalCol;
o.Alpha = Alpha;
o.Smoothness = finalGloss;
o.Metallic = dot(blendSplat, half4(_Metallic0, _Metallic1, _Metallic2, _Metallic3)) / (b1 + b2 + b3 + b4);
}
ENDCG
}
Dependency "AddPassShader" = "Custom/Terrain Shader Test Add"
Dependency "BaseMapShader" = "Hidden/TerrainEngine/Splatmap/Standard-Base"
Fallback "Nature/Terrain/Diffuse"
}
I have also attached a scene which clearly illustrates the problem at the following link: https://drive.google.com/file/d/0B7XHf-0bgF2-NjFfRmpLUzR6UzQ/view?usp=sharing
Note: if you require anymore information please feel free to ask.
Thank you in advance.
Your answer
Follow this Question
Related Questions
How can I get this type of terrain texture? 1 Answer
How do you turn off terrain blending? 1 Answer
Blending Reflection 0 Answers
shader for light replacement blending, instead of additive blending? 0 Answers
Silhouette overlay shader 0 Answers