gpt4 book ai didi

c++ - 为加载了高度图的地形创建 UV 坐标?

转载 作者:搜寻专家 更新时间:2023-10-31 00:51:46 24 4
gpt4 key购买 nike

我使用高度图图像在 OpenGL 中创建了一个地形。结果是一个动态分配的数组,其中包含步幅为 3 的地形 (x,y,z) 的所有顶点,如下所示:(firstvertexX,firstvertexY,firstvertexZ,secondvertexX,secondvertexY,thirdvertexZ...)。

为了渲染它,我还计算了法线(在类似的数组中)和假定的地形 UV 的极其糟糕的近似值(使用...法线)。渲染完全没有问题,除了正如我所说,UV 近似值非常糟糕,渲染的纹理有一种“多边形”的感觉(使用 GL_TRIANGLE_STRIPS)。

我想澄清一下,我希望地形在 OpenGl 中创建,而不是在任何其他程序(如 Blender)中创建。所以我必须以某种方式为上面提到的包含顶点的数组中的每个顶点指定一个 UV 坐标。我还想说,我不是在寻找完美的 UV 解决方案(即使有一个),而是一种进行粗略近似以使结果不错的方法。

所以我的问题是:

  1. UV 坐标是否需要在 0 到 1 之间,而不考虑地形的宽度和长度?
  2. UV 坐标数组的长度是否需要与顶点数组的长度相同?
  3. 是否有任何简单的算法或方法可以指定地形的 UV?

渲染的纹理:

Renderedimage

图片来自网络:

Actual image

指定创建数组的代码:

for (i = 0; i < terrainGridLength - 1 ; i++) { //z
for (j = 0; j < terrainGridWidth; j++) { //x

TerrainVertices[k] = startW + j + xOffset;
TerrainVertices[k + 1] = 20 * terrainHeights[(i + 1)*terrainGridWidth + (j)] + yOffset;
TerrainVertices[k + 2] = startL - (i + 1) + zOffset;
k = k + 3;


TerrainVertices[k] = startW + j +xOffset;
TerrainVertices[k + 1] = 20 * terrainHeights[(i)*terrainGridWidth + j] +yOffset;
TerrainVertices[k + 2] = startL - i + zOffset;
k = k + 3;


float x = RandomFloat(0.16, 0.96);
TerrainUVs[d] = x* (terrainNormals[ 3*((i+1 )*terrainGridWidth + j)]);
TerrainUVs[d + 1] = terrainNormals[3* ((i+1 )*terrainGridWidth + j) + 2 ];

x = RandomFloat(0.21, 0.46);
TerrainUVs[d+2] = x*(terrainNormals[ 3*((i+1 )*terrainGridWidth + j) +1]);
d = d + 3;


x = RandomFloat(0.3, 0.49);
TerrainUVs[d] = x*(terrainNormals[3* ((i )*terrainGridWidth + j) ]);
TerrainUVs[d + 1] = terrainNormals[ 3*((i )*terrainGridWidth + j)+2 ];

x = RandomFloat(0.4, 0.85);
TerrainUVs[d + 2] = x*(terrainNormals[3* ((i )*terrainGridWidth + j) +1]);

d = d + 3;
}
}

最佳答案

我会尽力解决您的所有问题。

1) Do the UV coordinates need to range from 0 to 1, with no consideration of the terrain's width and length or not?

UV 坐标通常在 0 到 1 空间内,但如果您传入的 UV 不是 0 到 1,处理 UV 的方式将取决于您如何设置 OpenGL 来处理这种情况。

您可以使用以下代码告诉纹理采样器将坐标视为环绕:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

或者,您可以使用以下代码限制 UV 值:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

在此处查看有关纹理采样器的更多信息: https://www.khronos.org/opengl/wiki/Sampler_Object

Does the UV coordinate array need to be the same length as the vertices array?

一般来说,是的。在对某些几何体进行纹理处理时,您通常需要每个顶点至少有一个 UV,因此您应该拥有与顶点相同数量的 UVS。但是,如果您对几何体应用了不止一种纹理,那么您可能拥有更多,或者如果您通过其他方式对几何体进行纹理化,例如使用您编写的不需要 UVS 的片段着色器,您可能拥有更少。如果你的 UVS 被索引,你也可以有更少的东西,这是当共享相同 UV 的每个顶点通过索引引用数组中的相同 UV 时。但是,如果您想使事情简单化,只需选择 1 对 1,不要担心重复。

Is there any simple algorithm or way that i could specify the UVs of the terrain?

一个简单的方法就是将每个三角形纹理化为四边形的一部分。你的地形应该只是一个四边形网格,这意味着你可以遍历你的顶点列表,为你的网格中的每个四边形分配纹理坐标,如下所示:

enter image description here

更好的是,如果你的地形网格在 x 和 z 上的大小为 1,你只需插入你的网格在 x 和 z 上的世界空间坐标,并将你的纹理采样器设置为环绕,假设你的网格没有旋转.如果您的网格旋转,它仍然有效,但纹理不会随之旋转。

关于c++ - 为加载了高度图的地形创建 UV 坐标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54136126/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com