OpenGL 3D纹理mip贴图

时间:2015-08-29 08:05:51

标签: c# opengl opentk

我正在尝试将3D纹理作为纹理图集的替代品。我想将它用于地形表面。 3D纹理效果很好,直到我尝试使用mip贴图(输出颜色总是黑色)。

代:

int glTexture;
glTarget = TextureTarget.Texture3D;

GL.GenTextures(1, out glTexture);
GL.BindTexture(glTarget, glTexture);

for (int level = 0; level < LevelCount; level++){
    GL.TexImage3D(glTarget, level, glInternalFormat, width, height, depth, 0, glFormat, glType, IntPtr.Zero);

    width = width >> 1;
    height = height >> 1;
}

设置每个面部和mip贴图的数据:

GL.BindTexture(glTarget, glTexture);
GL.TexSubImage3D(glTarget, level, 0, 0, depth, width, height, 1, glFormat, glType, dataPtr);

我确信,所有mip贴图都已设置(Apitrace会将它们全部显示为512到1)。知道发生了什么事吗?

2 个答案:

答案 0 :(得分:0)

3D纹理是纹理图册的非常差的替代品。它们应该被认为是体积纹理,特别是当涉及到它们的mipchain时,因为以任何其他方式来考虑它们是如此不直观。

这些数据来自微软的Direct3D 11 documentation,但它们也适用于GL。

2D阵列纹理Mipchain (立方体贴图)

enter image description here

3D纹理Mipchain:

https://i-msdn.sec.s-msft.com/dynimg/IC520453.png

用于将数据上传到2D数组纹理中的图层的API与3D纹理相同,但数据的表示方式却截然不同(特别是在mipmap方面看到的情况)。

答案 1 :(得分:0)

要为3D纹理指定正确的mipmap,您需要在所有3个方向上缩小每个级别的大小:

for (int level = 0; level < LevelCount; level++){
    GL.TexImage3D(glTarget, level, glInternalFormat, width, height, depth, 0,
                  glFormat, glType, IntPtr.Zero);

    width = width >> 1;
    height = height >> 1;
    depth = depth >> 1;
}

您可以将3D纹理拍摄为2D纹理的完全概括为3维。每个mipmap的大小都是前三个维度中mipmap的一半。 3D纹理的典型用途是用于体积数据,可以通过纹理像素的3D网格来描述,然后使用3个纹理坐标对其进行采样。

正如评论中已经提到的,您尝试使用的声音更像是 2D纹理数组。顾名思义,这是一个单独的2D纹理数组,其中深度指定数组中2D纹理的数量。

现在,如果您将纹理数组描绘为堆叠在一起的一堆2D纹理,它看起来非常类似于3D纹理。在这两种情况下,您最终都会得到一个3D纹理网格。事实上,只要你没有使用mipmap,差异就相当微妙。

随着mipmap的发挥,存在很大的差异:

  • 在3D纹理中,每个mipmap用于整个3D纹理。它的形状是一个盒子,每个方向的尺寸都是一半。
  • 在2D纹理数组中,数组中的每个纹理都有自己的mipmap。如果您将整个阵列的给定mipmap级别的图像再次叠加在一起,则结果仍然具有与原始纹理阵列相同的图像数量(即与原始纹理数据的深度相同),但是每个图像的大小(即它的宽度和高度)是前一级别大小的一半。

显然你看起来像第二种情况。您真正需要做的就是更改纹理目标。纹理目标在C绑定中为GL_TEXTURE_2D_ARRAY。如果C#绑定遵循相同的模式,则应该是:

glTarget = TextureTarget.Texture2DArray;

与3D纹理和2D纹理阵列之间的mipmap的不同大小相关,它们的采样方式也存在差异。对于3D纹理,在所有3个方向上都有mipmapping。因此,线性采样可以使用来自两个不同mipmap级别的8个纹素。对于2D纹理数组,采样将始终仅使用单个图层中的纹素,这意味着使用了来自2个mipmap级别的4个纹素。