用于计算基于高度图生成的三维模型中的纹理图块坐标的算法

时间:2016-02-09 07:20:10

标签: algorithm textures procedure heightmap

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

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;

1 个答案:

答案 0 :(得分:0)

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