在给定的世界坐标处修改网格上的纹理

时间:2017-02-12 13:19:25

标签: c++ directx-11

我正在制作一个编辑器,我想在其中构建地形图。我想用鼠标来增加/减少地形高度来创造山脉和湖泊。

从技术上讲,我有一个高度图,我想在我用鼠标选择的某个texcoord上进行修改。要做到这一点,我首先从屏幕坐标到世界位置 - 我已经做到了。下一步,从世界位置到选择正确的纹理坐标让我感到困惑。我该怎么做?

3 个答案:

答案 0 :(得分:1)

假设您的地形是一个简单的矩形,您首先要计算鼠标世界位置和地形原点之间的向量。 (地形四边形的顶点,高度贴图的左上角将映射到该顶点)。例如。 mouse (50,25) - origin(-100,-100) = (150,125)
现在将x和y坐标除以地形四边形的世界空间宽度和高度 150 / 200 = 0.75125 / 200 = 0.625。这为您提供纹理坐标,如果您需要它们作为像素坐标而不是简单地乘以纹理的大小。

答案 1 :(得分:1)

我假设以下内容:

  1. 您计算的世界坐标是视图截头内的鼠标指针。我将它们命名为mouseCoord
  2. 我们还有相机坐标,camCoord
  3. 世界由三角形组成
  4. 每个三角形点都有纹理坐标,这些坐标由重心坐标
  5. 插值

    如果是这样,解决方案是这样的:

    1. 使用camCoord作为原点。计算光线的方向为mouseCoord - camCoord。
    2. 计算与三角形的交点。天真的变体是检查每个三角形是否相交,更复杂的是先用其他算法排除几个三角形,比如在立方体中划分世界,沿立方体追踪光线,只看有重叠的三角形与立方体。可以像在这个网站上一样计算三角形的交点:http://www.lighthouse3d.com/tutorials/maths/ray-triangle-intersection/
    3. 计算相对于该三角形的交点重心坐标,如:https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-rendering-a-triangle/barycentric-coordinates
    4. 使用重心坐标作为相应三角形点的纹理坐标的权重。结果是交叉点的纹理坐标,也就是你想要的。
    5. 如果我误解了您想要的内容,请使用其他信息修改您的问题。

      另一种特定于高度图的变体:

      假设假设改变如下:

      1. 世界上有地砖超过x和y
      2. 地砖的角落有高度值
      3. 对于图块中的某个点,高度值会以某种方式进行插值,例如通过双线性插值。
      4. 纹理以相同的方式插值,同样使用角落的给定纹理坐标
      5. 一种可行的算法(近似):

        1. 再次,计算原点和方向。
        2. Wlog,我们假设方向的x方向变化较大。如果没有,请在算法中交换x和y。
        3. 以x的给定步长跟踪光线,即在每个步骤中,x坐标按该步长变化。 (沿着方向,乘以步长除以它的x值,将新方向添加到从原点开始的当前位置)
        4. 对于您当前的坐标,检查它的z值是否低于当前高度(又名刚刚与地面相撞)
        5. 如果是这样,要么完成或减少步长,要在附近进行更精细的搜索,然后向后移动,直到再次超过高度,然后再往前走更精细的步骤等等。结果是当前的x和y坐标
        6. 计算当前图块中x和y坐标的相对位置。将其用于角点纹理坐标的权重。
        7. 理论上,该算法可以跳过非常薄的顶部。选择足够小的步长来对付它。在不知道高度图使用什么类型的插值的情况下,我无法给出精确的算法。无论如何,创建三角形可能不是最糟糕的想法,可能是双线性插值坐标?在任何情况下,该算法都很适合找到它碰撞的图块。

          另一种变体是跟踪光线在其x-y坐标穿过瓷砖网格的点上,然后查看z坐标是否低于高度图。然后我们就知道它在这个瓷砖中碰撞了。如果高度可以在瓦片内部比在其边缘处更大,则这可能产生假阴性,因为某些形式的插值可以产生,尤其是那些考虑相邻瓦片的那些。但是,使用双线性插值可以正常工作。

          在双线性插值中,可以找到精确的交点:采用光线穿过网格的两个(x,y)坐标。计算检索两个(x,y,z)坐标的高度。用它们创建一条线。计算该线与光线的交点。它们的交点是与瓦片高度图的交点。

答案 2 :(得分:0)

最简单的方法是将网格渲染为uvs作为颜色的预传。没有屏幕需要世界。 uv是鼠标位置的值。使用mips /过滤etv

时要小心