简体   繁体   English

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

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

So I am creating a terrain and for texturing, I want to use a 3D texture (depth 3) which holds 3 images (512x512) on each z-layer, so that I would be able to use GPU interpolation between these layers based on just one factor: 0/3 = image 1, 1/3 = image 2, 2/3 = image 3, and every value in between interpolates with the next level (cyclic). 因此,我要创建一个地形并进行纹理处理,我想使用一个3D纹理(深度3),该纹理在每个z层上都可以容纳3张图像(512x512),这样我就可以基于一个因数:0/3 =图像1,1/3 =图像2,2/3 =图像3,并且之间的每个值都与下一级进行插值(循环)。

This works perfectly as long as I don't enable mip maps on this 3D texture. 只要我不在此3D纹理上启用Mip贴图,此方法就可以完美地工作。 When I do enable it, my terrain gets the same one image all over unless I come closer, as if the images have shifted from being z-layers to being mip-map layers. 当我启用它时,除非我靠近,否则我的地形将始终获得相同的一幅图像,就好像图像已从z层转换为mip地图层一样。

I don't understand this, can someone tell me what I'm doing wrong? 我不明白,有人可以告诉我我做错了什么吗?

This is where I generate the texture: 这是我生成纹理的地方:

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);

This is the step I perform for every Z: 这是我为每个Z执行的步骤:

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

After this, I do: 之后,我要做:

glGenerateMipmap(GL_TEXTURE_3D);

In the shader, I define the texture as: 在着色器中,我将纹理定义为:

uniform sampler3D tGround;

and simply sample it with: 并简单地用以下方法采样:

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

where texcoord is a 2D coordinate and f is the layer we need, simply based on height at this moment. 其中texcoord是2D坐标,而f是我们需要的图层,仅基于当前高度。

There is a way to do something like what you want, but it does require work. 有一种方法可以执行您想要的操作,但这确实需要工作。 And you can't use a 3D texture to do it. 而且,您不能使用3D纹理来做到这一点。

You have to use Array Textures instead. 您必须改为使用阵列纹理 The usual way to think of a 2D array texture is as a bundle of 2D textures of the same size. 想到2D阵列纹理的通常方法是将一堆相同大小的2D纹理打包。 But you can also think of it as a 3D texture where each mipmap level has the same number of Z layers. 但您也可以将其视为3D纹理,其中每个mipmap级别具有相同数量的Z层。 However, there's also the issue where there is no blending between array layers. 但是,还存在数组层之间没有混合的问题。

Since you want blending, you will need to synthesize it. 由于要混合,因此需要对其进行合成。 But that's easy enough with shaders: 但这对于着色器很简单:

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.
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM