sampler2DArray - 设置和使用
sampler2DArray - setup and use
我正在研究 OpenGL,我不得不使用 sampler2DArray。我整天都在受折磨——一切都无济于事。我有两个问题:
- 如何创建纹理列表?
- 如何在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+。
我正在研究 OpenGL,我不得不使用 sampler2DArray。我整天都在受折磨——一切都无济于事。我有两个问题:
- 如何创建纹理列表?
- 如何在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+。