2014-08-31 84 views
0

假设有一个由两个由三个顶点构成的瓷砖组成的游戏的网格地形。我们如何找到四个顶点之间的Y(上)位置?如何找到四个顶点之间的Y点? HLSL

Terrain

我已经试过这样:

float diffZ1 = lerp(heights[0], heights[2], zOffset); 
float diffZ2 = lerp(heights[1], heights[3], zOffset); 
float yPosition = lerp(diffZ1, diffZ2, xOffset); 

其中Z/Y偏移是z/y的百分比/ 100瓦的第一个顶点这适用于平坦的表面,但不能抵消在颠簸的地形上如此之好。

我想这与三角形的地形有关,上面的三角形可能在平面上工作。我不确定,但有人知道发生了什么问题吗?

这可以更好地解释什么是怎么回事:

enter image description here

在上面的代码“高度[]”是Y的阵列的周围顶点坐标v0-3。 三角1由顶点0,2和1。 三角2由顶点1,2和3

我希望能够找到坐标P1 Y的时,其x,y坐标v0-3之间铺设的。

所以我试图确定的一点是通过这个函数三角:

bool PointInTriangle(float3 pt, float3 pa, float3 pb, float3 pc) 
{ 
    // Compute vectors   
    float2 v0 = pc.xz - pa.xz; 
    float2 v1 = pb.xz - pa.xz; 
    float2 v2 = pt.xz - pa.xz; 

    // Compute dot products 
    float dot00 = dot(v0, v0); 
    float dot01 = dot(v0, v1); 
    float dot02 = dot(v0, v2); 
    float dot11 = dot(v1, v1); 
    float dot12 = dot(v1, v2); 

    // Compute barycentric coordinates 
    float invDenom = 1.0f/(dot00 * dot11 - dot01 * dot01); 
    float u = (dot11 * dot02 - dot01 * dot12) * invDenom; 
    float v = (dot00 * dot12 - dot01 * dot02) * invDenom; 

    // Check if point is in triangle 
    return (u >= 0.0f) && (v >= 0.0f) && (u + v <= 1.0f); 
} 

这不是给我,结果我的预期

话,我想找到的y坐标每个三角形内点p1:

// Position of point p1 
float3 pos = input[0].PosI; 

// Calculate point and normal for triangles 
float3 p1 = tile[0]; 
float3 n1 = (tile[2] - p1) * (tile[1] - p1); // <-- Error, cross needed 
     // = cross(tile[2] - p1, tile[1] - p1); 
float3 p2 = tile[3]; 
float3 n2 = (tile[2] - p2) * (tile[1] - p2); // <-- Error 
     // = cross(tile[2] - p2, tile[1] - p2); 
float newY = 0.0f; 

// Determine triangle & get y coordinate inside correct triangle 
if(PointInTriangle(pos, tile[0], tile[1], tile[2])) 
{ 
    newY = p1.y - ((pos.x - p1.x) * n1.x + (pos.z - p1.z) * n1.z)/n1.y; 
} 
else if(PointInTriangle(input[0].PosI, tile[3], tile[2], tile[1])) 
{ 
    newY = p2.y - ((pos.x - p2.x) * n2.x + (pos.z - p2.z) * n2.z)/n2.y; 
} 

使用下面找到第e正确的三角形:

if((1.0f - xOffset) <= zOffset) 
    inTri1 = true; 

而纠正上面的代码使用正确的交叉函数似乎已经解决了这个问题。

enter image description here

+0

因此,如果您的坐标位于第一个或第二个三角形的内部,这很重要吗? – usr2564301 2014-08-31 22:28:27

+0

如果你使用'xOffset'等变量定义了四个顶点,这将更加清晰,特别是,如何从四个顶点创建两个三角形?两个三角形之间是否共享两个顶点? – aecolley 2014-08-31 22:31:40

+2

是,两个顶点是共享的,我有点理解为什么它不起作用,因为有两个三角形而不是一个扁平的正方形。我应该按照三角形检查它吗? – 2014-08-31 22:41:28

回答

3

因为你的4个顶点可能不是在一个平面上,你应该分别考虑每个三角形。首先找到该点所在的三角形,然后使用以下StackOverflow讨论来求解Z值(注意轴的不同命名)。我个人比较喜欢DanielKO的回答要好得多,但接受的答案应太:

Linear interpolation of three 3D points in 3D space


编辑:对于您的问题的第二部分(找到三角的一点是在): 因为你的瓷砖投影到xz平面上(当你定义你的坐标时)是完美的正方形,找到该点所在的三角形是一个非常简单的操作。在这里,我将使用左右的术语来指代x轴(从x的较低值到较高值)以及从底部到顶部来指代z轴(从z的较低值到较高值)。

每个图块只能以两种方式之一分割。 (A)通过从左下角到右上角的对角线,或(B)通过从右下角到左上角的对角线。

  • 对于用于分割为A的任何瓷砖: 检查如果x“> Z”,其中x“是从的距离离开平铺到点的边缘,且z”是从距离将瓦片的边缘点设为底部。如果x'> z'那么你的点位于右下三角形中;否则它在左上角的三角形中。

  • 对于每个已拆分为B有块:检查是否X”> Z”,其中x”是从瓷砖到该点的边缘的距离,和Z”是从底部的距离瓦片的边缘点。如果x”> Z”那么你的点是在左下角的三角形,否则它在右上角的三角形

(小注:以上我假设你的砖不会在XZ平面旋转。 ;即它们与轴线对齐,如果不正确,只需旋转它们使其与轴线对齐,然后再进行上述检查。)

+0

好吧,我已经看过两个答案,并会尝试执行一个 – 2014-08-31 23:48:56

+0

让我知道你是否需要任何帮助。 – Arda 2014-09-01 00:11:50

+0

我试图关注DanielKO的答案,但我只是在确定点是否在一个三角形或其他三角形内时才有问题。我怎样才能做到这一点?每个三角形都有一个点和一个法线。 'FLOAT3 P1 =瓦片[0];' 'FLOAT3 N1 =(瓦[2] - P1)*(瓦[1] - P1);' 'FLOAT3 P2 =瓦片[3];' 'FLOAT3 n2 =(tile [2] - p2)*(tile [1] - p2);' – 2014-09-01 00:58:33

相关问题