Unity着色器错误

时间:2019-03-09 11:42:15

标签: c# unity3d shader

我正在使用一个Unity着色器,该着色器可以在一个平面上显示多个不同的图块。 Unity将浮点数组传递给着色器,该着色器带有一个瓦片ID列表和一个4x4瓦片映射,并且在大多数情况下可以完美工作,但是存在一个小问题。

我已附上现象的图像,在瓷砖的接缝处可以看到灰线。我打开了磁贴遮罩以消除问题,因此更容易看到。

下面是着色器代码:


Shader "Unlit/TileMap"
{
    Properties
    {
        // Texture configuration
        _DiffuseTex("Diffuse", 2D) = "white" {}
        _MaskTex("Mask", 2D) = "black" {}
        _MapWidth("Map Width", int) = 0
        _MaskMapWidth("Mask Mask Width", int) = 0
        _WorldWidth("World Width", int) = 0


        // Global illumination modifiers
        _GlobalLumosity("Global Lumosity", Range(0, 1)) = 1
        _GlobalHue("Global Hue", Color) = (1, 1, 1, 1)

    }
    SubShader
    {
        Tags { "Queue"="Transparent" "RenderType"="Transparent" }
        LOD 200
        ZWrite On

        Blend SrcAlpha OneMinusSrcAlpha

        Pass
        {
            CGPROGRAM
            #pragma target 4.0
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct appdata {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _DiffuseTex;
            float4 _DiffuseTex_ST;

            sampler2D _MaskTex;
            float4 _MaskText_ST;

            uint _ID;
            uint _MapWidth;
            uint _MaskMapWidth;
            uint _WorldWidth;

            half _GlobalLumosity;
            float4 _GlobalHue;

            float _allIDs[16];

            v2f vert (appdata v) {
                v2f o;

                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _DiffuseTex);

                return o;
            }

            fixed4 frag (v2f i) : SV_Target {
                float mapSizeModif = 1.0f / _MapWidth;
                float maskMapSizeModif = 1.0f / _MaskMapWidth;
                float worldSizeModif = 1.0f / _WorldWidth;

                // float lightness = tex2D (_MaskTex, i.uv * _MapWidth);
                float lightness = 1.0f;

                uint index = (int)  (floor(i.uv.x * _WorldWidth) +
                                    (floor(i.uv.y * _WorldWidth) * _WorldWidth));

                i.uv.x = i.uv.x % worldSizeModif;
                i.uv.y = i.uv.y % worldSizeModif;

                uint id = (uint) _allIDs[index];

                i.uv.x += mapSizeModif * (id % _MapWidth);
                i.uv.y += mapSizeModif * floor (((float)id) / _MapWidth);

                fixed4 col = tex2D (_DiffuseTex, i.uv);
                col *= _GlobalLumosity;
                col *= _GlobalHue;

                col.a = lightness;

                return col;
            }

            ENDCG
        }
    }
}

这是发生的情况的图像: enter image description here

我觉得需要某种填充来解决此问题,但我不知道我需要哪种填充。我觉得这与线条有关,还有一个涉及某种浮点精度错误的问题:

// Convert position into localised scaling
i.uv.x = i.uv.x % worldSizeModif;
i.uv.y = i.uv.y % worldSizeModif;

这是设置瓦片信息的MonoBehaviour控制器:

void Update()  {
    propBlock.SetFloatArray("_allIDs", new float[16] { 1, 1, 3, 2, 1, 1, 2, 2, 1, 3, 2, 1, 1, 2, 1, 1 });
    renderer.SetPropertyBlock(propBlock);
}

我认为在瓷砖之间可能是简单的纹理渗色,但是,即使强制使用它也是如此,以致不可能发生瓷砖渗色(通过在UV上施加偏移)它仍然会发生

任何帮助将不胜感激

让我知道您是否想要更多的信息

1 个答案:

答案 0 :(得分:2)

这里的问题是在某些像素上获取了纹理的最低点 ,显示为图片的平均值(灰色)。这样做的原因是,纹理水平是根据纹理坐标的导数计算的,纹理坐标在屏幕空间连续的情况下才起作用,这不是您的情况,因为您对每个像素进行模运算。

您可以通过使用tex2Dgrad(official FAQ on yaml.org)并使用ddx()和ddy()传递连续UV的导数来解决此问题