在 OpenGL 中对一个输入纹理使用多个 sampler2D

Use multiple sampler2D over one input texture in OpenGL

现在我有一个由这个网站生成的噪声纹理:https://aeroson.github.io/rgba-noise-image-generator/。我想在我的计算着色器中使用 4 个统一采样器从 单个 噪声纹理中获取 4 个随机 rgba 值。我的计算着色器源代码如下所示:

#version 430 core

layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

uniform sampler2D noise_r0;
uniform sampler2D noise_i0;
uniform sampler2D noise_r1;
uniform sampler2D noise_i1;

layout (binding = 0, rgba32f) writeonly uniform image2D tilde_h0k;

layout (binding = 1, rgba32f) writeonly uniform image2D tilde_h0minusk;

uniform int N = 256; 

....

// Box-Muller algorithm
vec2 texCoord = vec2(gl_GlobalInvocationID.xy) / float(N); // Here every invocation refers to a pixel of output image 
float noise00 = clamp(texture(noise_r0, texCoord).r, 0.001, 1.0);
float noise01 = clamp(texture(noise_i0, texCoord).r, 0.001, 1.0);
float noise02 = clamp(texture(noise_r1, texCoord).r, 0.001, 1.0);
float noise03 = clamp(texture(noise_i1, texCoord).r, 0.001, 1.0);

....

在主程序中,我使用此代码将下载的噪声纹理上传到计算着色器:

unsigned int tex_noise;
glGenTextures(1, &tex_noise);
glBindTexture(GL_TEXTURE_2D, tex_noise);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
int w_noise, h_noise, nrChannels;
unsigned char* data = stbi_load("noise.png", &w_noise, &h_noise, &nrChannels, 0);
if (data) {
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w_noise, h_noise, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
    glGenerateMipmap(GL_TEXTURE_2D);
}
else std::cout << "Failed to load noise texture." << std::endl;
stbi_image_free(data);
....
....

我的问题是:我可以使用这段代码在计算着色器中设置那些 sampler2D 吗?

glUseProgram(computeProgram);
glActiveTexture(GL_TEXTURE1);
glUniform1i(glGetUniformLocation(computeProgram, "noise_r0"), 1);
glActiveTexture(GL_TEXTURE2);
glUniform1i(glGetUniformLocation(computeProgram, "noise_i0"), 2);
glActiveTexture(GL_TEXTURE3);
glUniform1i(glGetUniformLocation(computeProgram, "noise_r1"), 3);
glActiveTexture(GL_TEXTURE4);
glUniform1i(glGetUniformLocation(computeProgram, "noise_i1"), 4);

如果错误,我应该如何设置那些sampler2D's,并确保我从那些sampler2D's 得到的随机rgba 值不相同? (因为如果它们相同,则 Box-Muller 算法将不起作用)。 非常感谢您的帮助!

制服的类型是 ìmage2D,而不是 sampler2D。要加载和存储图像,您必须使用 glBindImageTexture. See Image Load Store 将纹理绑定到图像单元。例如:

glBindImageTexture(1, tex_noise, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);

如果您想将纹理绑定到纹理单元,您需要 select 激活纹理单元 glActiveTexture and then bind the texture with glBindTexture:

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture_object);

您可以使用 sampler2D 类型的制服和 texture* 函数在着色器中访问此纹理:

layout(binding = 1) uniform sampler2D myTextue;

如果要将纹理绑定到图像单元,则必须使用glBindImageTexture:

glBindImageTexture(1, texture_object, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);

您可以使用 iamge2D 类型的制服和 image* 函数在着色器中访问此纹理:

layout (binding = 1, rgba32f) writeonly uniform image2D myImage;