sampler2DArray - 设置和使用

sampler2DArray - setup and use

我正在研究 OpenGL,我不得不使用 sampler2DArray。我整天都在受折磨——一切都无济于事。我有两个问题:

  1. 如何创建纹理列表?
  2. 如何在shader中使用sampler2DArray?

这是我尝试创建纹理列表的结果:

// textures - ids loaded textures
private int createTextureArray(GL2 gl, int[] textures, int width, int height) {
        int layerCount = textures.length;
        int mipLevelCount = 1;
        IntBuffer texture = IntBuffer.allocate(1);
        gl.glGenTextures(1, texture);
        gl.glActiveTexture(GL.GL_TEXTURE0);
        gl.glBindTexture(GL2.GL_TEXTURE_2D_ARRAY, texture.get(0));
        gl.glTexStorage3D(GL2.GL_TEXTURE_2D_ARRAY, mipLevelCount, GL2.GL_RGBA8, width, height, layerCount);

        for (int i = 0; i<textures.length; i++) {
             gl.glTexSubImage3D(GL2.GL_TEXTURE_2D_ARRAY, i, // error here
                     0, 0, 0,
                     width, height, layerCount,
                     GL2.GL_RGBA, GL2.GL_UNSIGNED_BYTE,
                     textures[i]);

        }

        // Always set reasonable texture parameters
        gl.glTexParameteri(GL2.GL_TEXTURE_2D_ARRAY, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR);
        gl.glTexParameteri(GL2.GL_TEXTURE_2D_ARRAY, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR);
        gl.glTexParameteri(GL2.GL_TEXTURE_2D_ARRAY, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP_TO_EDGE);
        gl.glTexParameteri(GL2.GL_TEXTURE_2D_ARRAY, GL2.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP_TO_EDGE);

        return texture.get(0);
    }

着色器示例:

#version 130
uniform sampler2DArray textures;
varying vec2 UV;
...
void main() {
   ...
   int layer = 0;
   gl_FragColor = texture2DArray(textures, vec3(UV, layer));
}

我将不胜感激。

一个array texture而不是一个"list of textures"。数组纹理是一个单独的 OpenGL 纹理,其中单独有许多准独立层。虽然您可能在概念上将阵列纹理的每一层视为单独的概念纹理,但在 OpenGL(和 GLSL)中,它是一个 单个对象 .

鉴于此,您函数中的接口不正确。它应该 return 一个单独的纹理对象,它应该作为参数,而不是 int 的数组(注意:OpenGL 对象是 无符号 整数),但是单个整数:要在该纹理中创建的数组层数。

在 GLSL 中使用数组纹理的方式很简单。您的 uniform 采样器使用数组纹理采样器类型(例如 sampler2DArray 用于二维数组纹理)。您将数组纹理绑定到您指定为采样器统一绑定的相同纹理图像单元(就像您对非数组 2D 纹理所做的那样)。

您的 GLSL 缺少一件事。没有 texture2DArray 功能。正确使用的函数只是 texture。 post-GL 3.0 中的纹理类型仅由参数指定,不再由函数名称指定。

除了@NicolBolas 已经说过的:着色器代码存在很多问题,主要是由于版本 130 中已弃用的功能:

  • 任何标准 glsl 版本都没有方法 texture2DArray。 EXT_texture_array 扩展中有一个,但它从未被集成,因为在 glsl 130 中,所有纹理查找函数(texture2D、texture3D,...)都已被重载的 texture 命令取代。如果你的目标是 130 没有扩展名,你应该使用
    texture(textures, vec3(UV, layer))
  • varying 关键字在 glsl 130 中已弃用,应替换为 in/out

  • gl_FragColor 已弃用,应使用用户定义的输出 (out) 变量。

您可能想查看 GLSL 130 Spec 的第 1.2.1 节,其中描述了弃用以及应如何处理它们。总的来说,除非有特殊原因,否则我会鼓励大家今天根本不要使用 130。最好转向 OpenGL 3.3+ Core Profile 和 GLSL 330+。