Поэтому я пытаюсь реализовать "гладкую" местность в моем движке блоков, давая каждому блоку поверхности карту высот.
По сути, для создания этих «карт высот» для каждого блока я создаю высоты с интервалами 0,25 по краю блока. Затем, чтобы построить вершины блока, я перебираю высоту и создаю треугольники от высоты до высоты и помещаю прямоугольники под треугольниками, чтобы создать что-то вроде этого:
Например, чтобы построить X положительную сторону блока, я делаю:
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);
}
Я не уверен, является ли это ошибкой точности с плавающей точкой, но когда я рендерил ее, я получаю эти любопытные дыры на границах базовых прямоугольников (я знаю, что это дыры, потому что их цвета соответствуют цвету позади них)
Что меня действительно отталкивает, так это то, что вместо целой строки это просто случайные точки.
Каркасный взгляд на мир не выявил никаких расхождений. (все, что он сделал, это сделало игру задержкой)
Быстрый маленький взлом, который я сделал, заключался в расширении (i + 1) / 4 в коде до (i + 1.01f) / 4, но я бы предпочел получить конкретное решение, чем что-то подобное.
Возможно, это что-то в моем шейдере? Мой образец текстуры:
Texture TextureAtlas;
sampler TextureSampler = sampler_state
{
texture = <TextureAtlas>;
magfilter = POINT;
minfilter = POINT;
mipfilter = POINT;
AddressU = WRAP;
AddressV = WRAP;
};
Заранее спасибо!