【问题标题】:Unity3D visible seams on borders when tiling texture平铺纹理时边界上的Unity3D可见接缝
【发布时间】:2013-04-03 08:52:56
【问题描述】:

对于我的游戏,我编写了一个着色器,可以让我的纹理很好地平铺在多个对象上。我不是根据顶点的相对位置,而是根据绝对世界位置来选择 uv。自定义着色器如下。基本上它只是将纹理平铺在 1x1 世界单位的网格中。

Shader "MyGame/Tile" 
{
    Properties 
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader 
    { 
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        #pragma surface surf Lambert
        sampler2D _MainTex;

        struct Input 
        {
            float2 uv_MainTex;
            float3 worldPos;
        };

        void surf (Input IN, inout SurfaceOutput o) 
        {
            //adjust UV for tiling
            float2 cell = floor(IN.worldPos.xz);
            float2 offset = IN.worldPos.xz - cell;
            float2 uv = offset;

            float4 mainTex = tex2D(_MainTex, uv);
            o.Albedo = mainTex.rgb;
        }
        ENDCG
    } 
    FallBack "Diffuse"
}

我之前在 XNA 上的 Cg 和 HLSL 着色器中使用过这种方法,它总是很有效。然而,使用 Unity 着色器,我在纹理的边缘看到了非常明显的接缝。我尝试了 Unity 表面着色器以及顶点/片段着色器,两者的结果相同。

纹理本身如下所示。在我的游戏中,它实际上是一个 .tga,而不是 .png,但这不会导致问题。该问题出现在所有纹理过滤器设置以及重复或钳位模式上。

现在我看到有人在这里遇到类似的问题:Seams between planes when lightmapping。 然而,对于如何解决这样的问题,没有明确的答案。此外,我的问题根本与光照贴图或照明无关。在我测试的片段着色器中,没有启用光照,问题仍然存在。

同样的问题也发布在 Unity 回答网站上,但我没有收到任何回答,也没有太多的浏览量,所以我也在这里尝试:Visible seams on borders when tiling texture

【问题讨论】:

  • On your texture,尝试将Wrap Mode更改为“Clamp”。
  • 正如我所说:所有纹理过滤器设置和重复或钳制模式均会出现问题。
  • Ack,我用 grep 表示“换行模式”,而不是钳位。
  • 一定要使用 MipMaps。看看有没有帮助。
  • 您不需要自己实现 frac。 http.developer.nvidia.com/Cg/frac.html

标签: unity3d shader textures fragment-shader tiling


【解决方案1】:

这描述了您的问题的原因: http://hacksoflife.blogspot.com/2011/01/derivatives-i-discontinuities-and.html

这是一个很棒的视觉示例,就像你的: http://aras-p.info/blog/2010/01/07/screenspace-vs-mip-mapping/

除非您要禁用 mipmap,否则我认为 Unity 无法解决此问题,因为据我所知,它不会让您使用可让您指定在片段中使用的 mip 级别的函数着色器(至少在 OS X / OpenGL ES 上;如果您只针对 Windows,这可能不是问题)。

也就是说,我不知道您为什么要进行片段级 uv 计算;只需从顶点着色器传递数据就可以了,带有可平铺的纹理:

struct v2f {
    float4 position_clip : SV_POSITION;
    float2 position_world_xz : TEXCOORD;
};

#pragma vertex vert
v2f vert(float4 vertex : POSITION) {
    v2f o;
    o.position_clip = mul(UNITY_MATRIX_MVP, vertex);
    o.position_world_xz = mul(_Object2World, vertex).xz;
    return o;
}

#pragma fragment frag
uniform sampler2D _MainTex;
fixed4 frag(v2f i) : COLOR {
    return tex2D(_MainTex, i.position_world_xz);
}

【讨论】:

  • 非常感谢,我不知道为什么我自己没有想到这个。当然,我可以直接从顶点着色器中获取世界位置,而无需进一步计算。这实际上使问题消失了(禁用 mip-maps 也有效)。
猜你喜欢
  • 2017-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-15
相关资源
最近更新 更多