Hello forum. I’ve been experimenting with the terrain triplanar shaders online lately and I’ve been able to implement it into my custom terrain shader. This shader automatically paints a cliff texture for the terrain depending on the dot product of the normal.
However, both the bottom and top parts of a cliff are textured incorrectly and I haven’t been able to figure out the cause of this (see screenshot). Instead of being textured horizontally, the y and z blends are being texture slightly vertically.
How can I achieve a horizontal texturing straight across the terrain walls? I’ve pasted my terrain surface shader below to show how the triplanar mapping is done. Thanks!
void surf(Input IN, inout SurfaceOutput o)
{
// Splat map controls.
half4 splat_control;
half weight;
fixed4 mixedDiffuse;
// Splat map mixer called in cginc.
SplatmapMix(IN, splat_control, weight, mixedDiffuse, o.Normal);
// texture scape for cliff texture
float3 scaledWorldPos = IN.localCoord / _MapScale;
// Get UVs for each axis based on local position of the fragment.
half2 yUV = IN.localCoord.xz / _MapScale;
half2 xUV = IN.localCoord.zy / _MapScale;
half2 zUV = IN.localCoord.xy / _MapScale;
// Texture samples from diffuse map with each of the 3 UV sets.
half3 yDiff = tex2D(_VerticalTex, yUV);
half3 xDiff = tex2D(_VerticalTex, xUV);
half3 zDiff = tex2D(_VerticalTex, zUV);
// Get the absolute value of the world normal.
// Put the blend weights to the power of BlendSharpness to sharpen transition
half3 blendWeights = pow(abs(IN.localNormal), _TriplanarBlendSharpness);
// Divide blend mask by the sum of it's components.
blendWeights = blendWeights / (blendWeights.x + blendWeights.y + blendWeights.z);
// Sharpen blend weight completely by rounding (currently causing black spots between blends).
blendWeights = round(blendWeights);
// Blend together all three samples based on the blend mask.
half3 color = xDiff * blendWeights.x + yDiff * blendWeights.y + zDiff * blendWeights.z;
// Automatically texture terrain with cliff texture if dot product is greater than 0.8.
if (dot(IN.localNormal, fixed3(0, 1, 0)) >= 0.8)
{
o.Albedo = mixedDiffuse.rgb;
}
else {
o.Albedo = color.rgb;
}
o.Alpha = 1;
}