我正在生成动态世界地图,并使用Unity Texture Array作为纹理基础来执行此操作。但是,着色器我目前在x / z上具有良好的平铺效果,但在y上的拉伸效果很差。有什么办法可以纠正它,使其在所有三个轴上平铺?
Shader "Custom/TerrainTexture" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Terrain Texture", 2DArray) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Standard fullforwardshadows
#pragma target 3.5
UNITY_DECLARE_TEX2DARRAY(_MainTex);
struct Input {
float4 color : COLOR;
float3 worldPos;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
void surf (Input IN, inout SurfaceOutputStandard o) {
float2 uv = IN.worldPos.xz * 0.20;
fixed4 c = UNITY_SAMPLE_TEX2DARRAY(_MainTex, float3(uv, 1));
o.Albedo = c.rgb * _Color;
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
答案 0 :(得分:3)
为此,您需要三面映射。原理是,将纹理投影到XZ平面上,就像您所做的一样,但随后还将其投影到ZY和XY平面上。最后,使用表面法线(通常多次平方)将纹理混合在一起(相乘和相加)。
以下是混合功能的外观:
inline float3 TriplanarBlendFactor(half3 normal) {
float3 bf = pow(abs(normal), 6);
bf /= dot(bf, (float3)1);
return bf;
}
然后只需像这样组合纹理样本:
fixed4 cx = tex2D(tex, tx) * blendFactor.x;
fixed4 cy = tex2D(tex, ty) * blendFactor.y;
fixed4 cz = tex2D(tex, tz) * blendFactor.z;
fixed4 finalColor = cx + cy + cz;
如果要控制混合距离,可以将混合功能中的功能作为着色器属性公开。