Home > Enterprise >  Use multiple sampler2D over one input texture in OpenGL
Use multiple sampler2D over one input texture in OpenGL

Time:05-24

Now I have a noise texture generated by this website: https://aeroson.github.io/rgba-noise-image-generator/. I want to use 4 uniform samplers in my computing shader to get 4 random rgba values from a single noise texture. My computing shader source codes look like:

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

....

and in the main program, I use this code to upload my downloaded noise texture to the computing shader:

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

My question is: Can I set up those sampler2D's in computing shader using this code?

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

If it is wrong, what should I do to set up those sampler2D's, and make sure that the random rgba values I get from those sampler2D's are not the same? (cause if they are the same, the Box-Muller algorithm won't work). Thanks so much for your help!

CodePudding user response:

The type of the uniform is ìmage2D, not sampler2D. To load and store an image, you must bind the texture to an image unit using glBindImageTexture. See Image Load Store. e.g.:

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

If you want to bind a texture to a texture unit you need to select active texture unit with glActiveTexture and then bind the texture with glBindTexture:

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

You can access this texture in the shader with a uniform of type sampler2D and and the texture* functions:

layout(binding = 1) uniform sampler2D myTextue;

If you want to bind a texture to a image unit, you have to use glBindImageTexture:

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

You can access this texture in the shader with a uniform of type iamge2D and and the image* functions:

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