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