基于高度图生成的3d模型纹理瓦片坐标计算算法

标签 algorithm textures procedure heightmap

我正在将高度图转换为 3d 模型,我有一个小纹理,代表 4 个点(即 2 个三角形)。当点之间的高度差太大时,问题是纹理平铺。我想平铺我的纹理以避免高拉伸(stretch),但我在实现一般情况算法时遇到问题。我已经渲染了图片,代表我的意思:

collage with pictures i rendered

在这个例子中,我只使用了一半的纹理(1 个三角形),所有纹理坐标都是我手动设置的。

请帮我找到一般情况下计算纹理坐标的算法

代码:

class procedure GraphicEngine.AddHeightmapQuad(X, Y, Z1, Z2, Z3, Z4: Double);
const
  Length = 1;
var
  Vertices: PVertex;
  v1, v2, v3, v4: TD3DVector;
begin
  OleCheck(Triangles.Lock(TrianglesCount * 3 * SizeOf(TVertex), 2 * 3 * SizeOf(TVertex), Pointer(Vertices), 0));
  Dec(Vertices);

  Vertices[1]:= TVertex.Create(X         , Y         , Z1,  0,  0);
  Vertices[2]:= TVertex.Create(X + Length, Y         , Z2,  1,  0);
  Vertices[3]:= TVertex.Create(X         , Y + Length, Z3,  0,  1);

  Vertices[4]:= TVertex.Create(X + Length, Y         , Z2,  1,  0);
  Vertices[5]:= TVertex.Create(X         , Y + Length, Z3,  0,  1);
  Vertices[6]:= TVertex.Create(X + Length, Y + Length, Z4,  1,  1);

  D3DXVec3Subtract(v1, Vertices[2].vec, Vertices[1].vec);
  D3DXVec3Subtract(v2, Vertices[3].vec, Vertices[1].vec);

  D3DXVec3Subtract(v3, Vertices[4].vec, Vertices[6].vec);
  D3DXVec3Subtract(v4, Vertices[5].vec, Vertices[6].vec);

  Vertices[2].U:= Sqrt(1 + Sqr(v1.z));
  Vertices[3].V:= Sqrt(1 + Sqr(v2.z));

  Vertices[4].U:= Sqrt(1 + Sqr(v4.z));
  Vertices[5].V:= Sqrt(1 + Sqr(v3.z));

  Vertices[6].U:= Sqrt(1 + Sqr(v4.z));
  Vertices[6].V:= Sqrt(1 + Sqr(v3.z));     

  Inc(TrianglesCount, 2);

  OleCheck(Triangles.Unlock);
end;

最佳答案

您可以通过计算三角形的实际大小来计算纹理上的精确拉伸(stretch)。更简单的是,您可以简单地计算边的长度来调整坐标。将纹理中的一个点固定为 0,0 然后下一个点而不是 0, 1 将是 0, sqrt(1 + (h1 - h2)^2)网格的另一个点也是如此(h1 和 h2 是点的高度)。为避免不匹配,请确保在执行下一个单元格时复制坐标。

关于基于高度图生成的3d模型纹理瓦片坐标计算算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35286077/

相关文章:

php - 逐步将项目添加到站点

c++ - SDL 上的 OpenGL 纹理仅显示部分纹理

android - 在 Android 上使用 OpenGL ES 显示透明纹理时出现问题

php - 显示从最小值到最大值的轴 - 计算比例和标签

c++ - std::vector 超出最小堆范围:C++

opengl - 在加载 SOIL 的纹理之间切换

mysql - 如果存在则更新,否则插入不起作用

Python 列表括号删除

php - 如何在MySQL过程中返回最后插入的id

mysql - 当投票没有降低声誉时,我如何避免声誉增加?