Unity3d 使用此Unity着色器可以避免垂直纹理拉伸吗?

Unity3d 使用此Unity着色器可以避免垂直纹理拉伸吗?,unity3d,shader,Unity3d,Shader,我正在制作一个动态世界地图,并使用Unity纹理数组作为它的纹理基础。但是,我当前使用的着色器在x/z方向上平铺良好,但在y方向上拉伸严重。有没有办法纠正这一点,使其在所有三个轴上平铺 Shader "Custom/TerrainTexture" { Properties { _Color ("Color", Color) = (1,1,1,1) _MainTex ("Terrain Texture", 2DArray) = "white" {}

我正在制作一个动态世界地图,并使用Unity纹理数组作为它的纹理基础。但是,我当前使用的着色器在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"
}

为此,您需要三平面映射。其原理是将纹理投影到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;

如果希望控制混合距离,可以将混合函数中的电源作为着色器属性公开

为此,您需要三平面映射。其原理是将纹理投影到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;

如果希望控制混合距离,可以将混合函数中的电源作为着色器属性公开

你能发布一个截图吗?它在x、y和z轴上是如何渲染的?这不是2D图像吗?你能发布截图吗?它在x、y和z轴上是如何渲染的?这不是2D图像吗?太棒了。我不太明白这个问题,但你的回答既澄清了问题,又回答了问题。加上一点奖励,你做得很简洁。太棒了。我不太明白这个问题,但你的回答既澄清了问题,又回答了问题。加上奖金,你做得很简洁。