I am working on a Unity shader that can display multiple different tiles on a single plane. Unity passes a floating point array to the shader with a list of tile IDs and a 4x4 tile map and for the mostpart it works perfectly, however there is one slight issue.
I have attached an image of the phenomenon, at the seams of the tiles you can see grey lines. I turned on the tile masking to extenuate the issue so it's easier to see.
Below is the shader code:
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 } } }
And here is an image of what happens:
I feel like some sort of padding would be needed to fix this issue but I don't know what kind of padding I would need. I feel it has something to do with the lines, and an issue that involves some sort of floating point accuracy error:
// Convert position into localised scaling
i.uv.x = i.uv.x % worldSizeModif;
i.uv.y = i.uv.y % worldSizeModif;
And this is the MonoBehaviour controller that sets the tile information:
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);
}
I thought it may be simple texture bleed between the tiles, however, even when forcing it so that no tile bleed is possible (by putting an offset on the UV) it still happens
Any help would be appreciated
Let me know if there is any more info you'd like
i.uv.x = i.uv.x % (worldSizeModif - 1);
(and the equivalent same foruv.y
). – 3Dave