- Home /
mesh terrain shader when tiling has seams , help !
hi , everyone . i wrote a shader to support 6 or more layer in a terrain mesh on gles2 (mobile) .
cause gles2 limitation , i can only combine four texture to one and adjust the uv in shader .
(if layer and texture is one to one ,the instruction and temporary register int the shader with #pragma target 2.0 is not enought)
the follow pic show how the shader work:
i use the "layer1" to instead layer 1 to 3 and use the "control1 texuture rgb" to control what layer1~3 show.
the "layer2" instead layer 4 to 6 and the "control2 texuture rgb" to control what layer4~6 show.
and the texture title 1~6 value control all sub texture tiling (sorry for i type a wrong word "title" to "tiling" ).
the follow pic show the seams when tiling repeat.
and i also use a color only texture to show what it happen really ,the result bellow here:
this is the shader i wrote:
Shader "SL_ShaderLevel/SL_TerrainWithSixTexture_TestByXu" {
Properties {
_TextureTitle1("Texture Title 1", Range(1.0,20.0)) = 1.0
_TextureTitle2("Texture Title 2", Range(1.0,20.0)) = 1.0
_TextureTitle3("Texture Title 3", Range(1.0,20.0)) = 1.0
_TextureTitle4("Texture Title 4", Range(1.0,20.0)) = 1.0
_TextureTitle5("Texture Title 5", Range(1.0,20.0)) = 1.0
_TextureTitle6("Texture Title 6", Range(1.0,20.0)) = 1.0
_Splat0 ("Layer 1", 2D) = "white" {}
_Splat1 ("Layer 2", 2D) = "white" {}
_Control ("Control (RGBA)", 2D) = "black" {}
_Control2 ("Control2 (RGBA)", 2D) = "black" {}
}
SubShader {
Tags {
"RenderType" = "Opaque"
}
CGPROGRAM
#include "UnityCG.cginc"
//#pragma surface surf Lambert
#pragma surface surf TestLightModel exclude_path:prepass noforwardadd
inline fixed4 LightingTestLightModel (SurfaceOutput s, fixed3 lightDir, fixed atten)
{
fixed diff = dot (s.Normal, lightDir);
fixed4 c;
c.rgb = s.Albedo * _LightColor0.rgb * (diff * atten * 2);
c.a = 0.0;
return c;
}
struct Input {
float2 uv_Control : TEXCOORD0;
float2 uv_Splat0 : TEXCOORD1;
float2 uv_Splat1 : TEXCOORD2;
};
sampler2D _Control,_Control2;
sampler2D _Splat0,_Splat1;
half _TextureTitle1;
half _TextureTitle2;
half _TextureTitle3;
half _TextureTitle4;
half _TextureTitle5;
half _TextureTitle6;
void surf (Input IN, inout SurfaceOutput o) {
fixed4 splat_control = tex2D (_Control, IN.uv_Control).rgba;
fixed4 splat_control2 = tex2D (_Control2, IN.uv_Control).rgba;
half2 uv2 = IN.uv_Splat0;
half2 uv1_new = lerp(half2(0.0,0.0),half2(0.5,0.5),frac(_TextureTitle1 * uv2));
half2 uv2_new = half2(0.5,0.0) + lerp(half2(0.0,0.0),half2(0.5,0.5),frac(_TextureTitle2 * uv2));
half2 uv3_new = half2(0.0,0.5) + lerp(half2(0.0,0.0),half2(0.5,0.5),frac(_TextureTitle3 * uv2));
half2 uv4_new = lerp(half2(0.0,0.0),half2(0.5,0.5),frac(_TextureTitle4 * uv2));
half2 uv5_new = half2(0.5,0.0) + lerp(half2(0.0,0.0),half2(0.5,0.5),frac(_TextureTitle5 * uv2));
half2 uv6_new = half2(0.0,0.5) + lerp(half2(0.0,0.0),half2(0.5,0.5),frac(_TextureTitle6 * uv2));
half3 lay1 = tex2D (_Splat0, uv1_new);
half3 lay2 = tex2D (_Splat0, uv2_new);
half3 lay3 = tex2D (_Splat0, uv3_new);
half3 lay4 = tex2D (_Splat1, uv4_new);
half3 lay5 = tex2D (_Splat1, uv5_new);
half3 lay6 = tex2D (_Splat1, uv6_new);
o.Alpha = 0.0;
o.Albedo.rgb = (lay1 * splat_control.r + lay2 * splat_control.g + lay3 * splat_control.b+ lay4 * splat_control2.r + lay5 * splat_control2.g + lay6 * splat_control2.b );
}
ENDCG
}
Fallback "Diffuse"
}
and i also try to set a tiny offset to ignore the edge sampling . but no effect .i guess the tex2D() func in shader may get the wrong sampling.
could anyone help ? thx a lot !
by the way , this is all my resources files:
Answer by Fei-Chang · Jan 02, 2014 at 04:06 AM
I want to help you,But....
please do not post as an answer something that isn't an answer, use the comment section to comment of questions and answers.
Answer by sparkzbarca · Jan 02, 2014 at 04:01 AM
looks easy enough to solve you just need to redo the 4 texture thing real quick to add some buffer space.
http://wiki.polycount.com/EdgePadding
this will explain it, you basically put say a brown edge around the edge of a brown texture then you have that part transparent so its not drawn but when they go to sample they get a color close to what the actual texture is so it works.
there is also techniques to do things like extrude the edge of the texture.
But basically take heart its just the texture itself thats causing this and you need to go into photoshop, fix the texture and your in business :)
I know about it some but i'd suggest if you want up to date good info you post this in photoshop, or Gimp forums, texture artists actually know alot more about solving your issue than programmers. :)
Answer by ZhipingXu · Jan 02, 2014 at 07:26 AM
thx sparkzbarca.
i try add some buffer space (and trim the Calculated UV to fix buffer space , for example 0.0 to 0.5 ->0.1 to 0.4 ),
but doen't work , the seams still exist...
this problem had troubled me for several days ...
am my shader had some problem on calculating ?