为什么 mipmapping 对我的 3D 纹理不起作用? (opengl)

Why does mipmapping not work on my 3D texture? (opengl)

所以我正在创建一个地形和纹理,我想使用一个 3D 纹理(深度 3),它在每个 z 层上包含 3 个图像(512x512),这样我就可以在之间使用 GPU 插值这些层仅基于一个因素:0/3 = 图像 1、1/3 = 图像 2、2/3 = 图像 3,并且两者之间的每个值都与下一层(循环)进行插值。

只要我不在此 3D 纹理上启用 mip 贴图,它就可以完美运行。当我启用它时,除非我靠近一点,否则我的地形会得到一个相同的图像,就好像图像已经从 z 层转变为 mip-map 层一样。

我不明白这个,有人能告诉我我做错了什么吗?

这是我生成纹理的地方:

glGenTextures(1, &m_textureId);
glBindTexture(GL_TEXTURE_3D, m_textureId);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, 512, 512, 3, 0, GL_BGR, GL_UNSIGNED_BYTE, 0);

这是我对每个 Z 执行的步骤:

glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, Z, 512, 512, 1, GL_BGR, GL_UNSIGNED_BYTE, imageData);

之后,我做:

glGenerateMipmap(GL_TEXTURE_3D);

在着色器中,我将纹理定义为:

uniform sampler3D tGround;

并简单地对其进行采样:

texture(tGround, vec3(texcoord, f));

其中texcoord是二维坐标,f是我们需要的图层,此时简单的根据高度

有一种方法可以做你想做的事情,但它确实需要工作。而且你不能使用 3D 纹理来做到这一点。

您必须改用 Array Textures。通常将 2D 数组纹理视为一束相同大小的 2D 纹理。但您也可以将其视为 3D 纹理,其中每个 mipmap 级别具有相同数量的 Z 层。但是,还有一个问题是阵列层之间 没有混合

既然要融合,就需要合成。但是使用着色器这很容易:

vec4 ArrayTextureBlend(in vec3 texCoord)
{
  float frac = fract(texCoord.z);
  texCoord.z = floor(texCoord.z);
  vec4 top = texture(arrayTex, texCoord);
  vec4 bottom = texture(arrayTex, texCoord + vec3(0, 0, 1));
  return mix(top, bottom, frac); //Linearly interpolate top and bottom.
}