Vì vậy, tôi đang cố gắng thực hiện địa hình "trơn tru" trong công cụ khối của mình bằng cách cung cấp cho mỗi khối bề mặt một sơ đồ chiều cao.
Về cơ bản, những gì tôi làm để tạo ra các "chiều cao" cho mỗi khối là tôi tạo các độ cao trong các khoảng 0,25 dọc theo cạnh của khối. Sau đó, để xây dựng các đỉnh của khối, tôi lặp qua các độ cao và tạo các hình tam giác từ chiều cao đến chiều cao và đặt hình chữ nhật dưới các hình tam giác để tạo ra một cái gì đó như thế này:
Ví dụ: để xây dựng mặt tích cực X của một khối, tôi làm:
Vector2[] uv = BlockUtil.UVMappings[(byte)side]; // uv[0] = top left
float height;
float nextHeight;
float min;
float tex_len = 1f / EngineGlobals.TEXTURE_ATLAS_SIDE;
for (int i = 0; i < 4; i++)
{
height = (float)b.Heights[4, i] / 255f;
nextHeight = (float)b.Heights[4, i + 1] / 255f;
min = Math.Min(height, nextHeight);
//create the triangles at the top
if (nextHeight > height)
{
int offset = ch.vertexMap.Count;
AddVertex(ch, 0, 0, uv[0] + new Vector2(tex_len * (i / 4f), (1-height)*tex_len), blockPos, new Vector3(1f, height, i / 4f), tr, isliquid);
AddVertex(ch, 0, 0, uv[0] + new Vector2(tex_len * ((i + 1) / 4f), 0), blockPos, new Vector3(1f, height, (i + 1) / 4f), tr, isliquid);
AddVertex(ch, 0, 0, uv[0] + new Vector2(tex_len * ((i + 1) / 4f), 0), blockPos, new Vector3(1f, nextHeight, (i + 1) / 4f), tr, isliquid);
AddTriIndices(offset, 0, 1, 2);
}
else if (nextHeight < height)
{
int offset = ch.vertexMap.Count;
AddVertex(ch, 0, 0, uv[0] + new Vector2(tex_len * (i / 4f), (1-height)*tex_len), blockPos, new Vector3(1f, height, i / 4f), tr, isliquid);
AddVertex(ch, 0, 0, uv[0] + new Vector2(tex_len * (i / 4f), (1-nextHeight)*tex_len), blockPos, new Vector3(1f, nextHeight, i / 4f), tr, isliquid);
AddVertex(ch, 0, 0, uv[0] + new Vector2(tex_len * ((i + 1) / 4f), (1 - nextHeight) * tex_len), blockPos, new Vector3(1f, nextHeight, (i + 1) / 4f), tr, isliquid);
AddTriIndices(offset, 0, 1, 2);
}
// else: heights are equal; ignore
// create the base rectangle
AddVertex(ch, 0, 0, uv[0] + new Vector2(tex_len * (float)i / 4f + tex_len / 4f, (1 - min) * tex_len), blockPos, new Vector3(1, min, (float)(i + 1) / 4f), tr, isliquid);
AddVertex(ch, 0, 1, uv[0] + new Vector2(tex_len * (float)i/4f, (1 - min) * tex_len), blockPos, new Vector3(1, min, (float)i / 4f), tr, isliquid);
AddVertex(ch, 0, 2, uv[0] + new Vector2(tex_len * (float)i / 4f + tex_len / 4f, tex_len), blockPos, new Vector3(1, 0, (float)(i + 1) / 4f), tr, isliquid);
AddVertex(ch, 0, 3, uv[0] + new Vector2(tex_len * (float)i / 4f, tex_len), blockPos, new Vector3(1, 0, (float)i / 4f), tr, isliquid);
AddIndices(ch, 0, 1, 2, 2, 1, 3, isliquid);
}
Tôi không chắc đây có phải là lỗi chính xác của dấu phẩy động hay không, nhưng khi tôi kết xuất nó, tôi nhận được các lỗ tò mò này trên các đường viền của hình chữ nhật cơ sở (tôi biết chúng là các lỗ vì màu của chúng khớp với màu phía sau chúng)
Điều thực sự làm tôi thất vọng là thay vì cả một dòng, nó chỉ là những dấu chấm ngẫu nhiên.
Một cái nhìn khung dây của thế giới đã không tiết lộ bất kỳ sự khác biệt. (tất cả những gì nó đã làm là khiến trò chơi bị lag)
Một cách nhanh chóng mà tôi đã làm là mở rộng (i + 1) / 4 trong mã thành (i + 1.01f) / 4, nhưng tôi muốn có một giải pháp cụ thể hơn là một giải pháp cụ thể.
Có lẽ đó là một cái gì đó trong shader của tôi? Bộ lấy mẫu kết cấu của tôi là:
Texture TextureAtlas;
sampler TextureSampler = sampler_state
{
texture = <TextureAtlas>;
magfilter = POINT;
minfilter = POINT;
mipfilter = POINT;
AddressU = WRAP;
AddressV = WRAP;
};
Cảm ơn trước!