我正在使用一个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 } } }
我觉得需要某种填充来解决此问题,但我不知道我需要哪种填充。我觉得这与线条有关,还有一个涉及某种浮点精度错误的问题:
// 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上施加偏移)它仍然会发生
任何帮助将不胜感激
让我知道您是否想要更多的信息
答案 0 :(得分:2)
这里的问题是在某些像素上获取了纹理的最低点 ,显示为图片的平均值(灰色)。这样做的原因是,纹理水平是根据纹理坐标的导数计算的,纹理坐标在屏幕空间连续的情况下才起作用,这不是您的情况,因为您对每个像素进行模运算。
您可以通过使用tex2Dgrad(official FAQ on yaml.org)并使用ddx()和ddy()传递连续UV的导数来解决此问题