Я работаю над шейдером Unity, который может отображать несколько разных плиток на одной плоскости. Unity передает массив с плавающей запятой в шейдер со списком идентификаторов тайлов и картой тайлов 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), это все равно происходит
Буду признателен за любую помощь
Дайте мне знать, если вам нужна дополнительная информация