[英]Modifying a texture on a mesh at given world coordinate
Im making an editor in which I want to build a terrain map. 我正在制作一个编辑器,我想在其中构建地形图。 I want to use the mouse to increase/decrease terrain altitude to create mountains and lakes.
我想用鼠标来增加/减少地形高度来创造山脉和湖泊。
Technically I have a heightmap I want to modify at a certain texcoord that I pick out with my mouse. 从技术上讲,我有一个高度图,我想在我用鼠标选择的某个texcoord上进行修改。 To do this I first go from screen coordinates to world position - I have done that.
要做到这一点,我首先从屏幕坐标到世界位置 - 我已经做到了。 The next step, going from world position to picking the right texture coordinate puzzles me though.
下一步,从世界位置到选择正确的纹理坐标让我感到困惑。 How do I do that?
我怎么做?
If you are using a simple hightmap, that you use as a displacement map in lets say the y direction. 如果您使用的是简单的hightmap,那么您将其用作位移贴图,即y方向。 The base mesh lays in the xz plain (y=0).
基础网格位于xz平面(y = 0)。
You can discard the y coordinate from world coordinate that you have calculated and you get the point on the base mesh. 您可以从已计算的世界坐标中丢弃y坐标,并获得基础网格上的点。 From there you can map it to texture space the way, you map your texture.
从那里你可以将它映射到纹理空间,你可以映射你的纹理。
I would not implement it that way. 我不会那样实现它。 I would render the scene to a framebuffer and instead of rendering a texture the the mesh, colorcode the texture coordinate onto the mesh.
我会将场景渲染到帧缓冲区,而不是渲染纹理网格,将纹理坐标颜色编码到网格上。 If i click somewhere in screen space, i can simple read the pixel value from the framebuffer and get the texture coordinate directly.
如果我点击屏幕空间中的某个地方,我可以简单地从帧缓冲区读取像素值并直接获取纹理坐标。 The rendering to the framebuffer should be very inexpensive anyway.
无论如何,对帧缓冲区的渲染应该非常便宜。
Assuming your terrain is a simple rectangle you first calculate the vector between the mouse world position and the origin of your terrain. 假设您的地形是一个简单的矩形,您首先要计算鼠标世界位置和地形原点之间的向量。 (The vertex of your terrain quad where the top left corner of your height map is mapped to).
(地形四边形的顶点,高度贴图的左上角将映射到该顶点)。 Eg
mouse (50,25) - origin(-100,-100) = (150,125)
. 例如
mouse (50,25) - origin(-100,-100) = (150,125)
。
Now divide the x and y coordinates by the world space width and height of your terrain quad. 现在将x和y坐标除以地形四边形的世界空间宽度和高度。
150 / 200 = 0.75
and 125 / 200 = 0.625
. 150 / 200 = 0.75
和125 / 200 = 0.625
。 This gives you the texture coordinates, if you need them as pixel coordinates instead simply multiply with the size of your texture. 这为您提供纹理坐标,如果您需要它们作为像素坐标而不是简单地乘以纹理的大小。
I assume the following: 我假设如下:
If so, the solution goes like this: 如果是这样,解决方案是这样的:
If I misunderstood what you wanted, please edit your question with additional information. 如果我误解了您的想法,请使用其他信息编辑您的问题。
Another variant specific for a height map: 另一种特定于高度图的变体:
Assumed that the assumptions are changed like that: 假设假设改变如下:
A feasible algorithm for that (approximative): 一种可行的算法(近似):
This algorithm can theoretically jump over very thin tops. 理论上,该算法可以跳过非常薄的顶部。 Choose a small enough step size to counter that.
选择足够小的步长来对付它。 I cannot give an exact algorithm without knowing what type of interpolation the height map uses.
在不知道高度图使用什么类型的插值的情况下,我无法给出精确的算法。 Might be not the worst idea to create triangles anyway, out of bilinear interpolated coordinates maybe?
无论如何,创建三角形可能不是最糟糕的想法,可能是双线性插值坐标? In any case, the algorithm is good to find the tile in which it collides.
在任何情况下,该算法都很好地找到它碰撞的区块。
Another variant would be to trace the ray over the points at which it's xy-coordinates cross the tile grid and then look if the z coordinate went below the height map. 另一种变体是在xy坐标穿过瓷砖网格的点上跟踪光线,然后查看z坐标是否低于高度图。 Then we know that it collides in this tile.
然后我们就知道它在这个瓷砖中碰撞了。 This could produce a false negative if the height can be bigger inside the tile than at it's edges, as certain forms of interpolation can produce, especially those that consider the neighbour tiles.
如果高度可以在区块内部比在其边缘处更大,则可能产生假阴性,因为某些形式的插值可以产生,尤其是那些考虑相邻区块的插值。 Works just fine with bilinear interpolation, though.
但是,使用双线性插值可以正常工作。
In bilinear interpolation, the exact intersection can be found like that: Take the two (x,y) coordinates at which the grid is crossed by the ray. 在双线性插值中,可以找到精确的交点:采用光线穿过网格的两个(x,y)坐标。 Compute the height of those to retrieve two (x,y,z) coordinates.
计算检索两个(x,y,z)坐标的高度。 Create a line out of them.
用它们创建一条线。 Compute the intersection of that line with the ray.
计算该线与光线的交点。 The intersection of those is that of the intersection with the tile's height map.
那些交叉点是与瓦片高度图的交点。
Simplest way is to render the mesh as a pre-pass with the uvs as the colour. 最简单的方法是将网格渲染为uvs作为颜色的预传。 No screen to world needed.
没有屏幕需要世界。 The uv is the value at the mouse position.
uv是鼠标位置的值。 Just be careful though with mips/filtering etv
使用mips /过滤etv时要小心
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.