I'm trying to build a compute shader to create a noise texture to use as a height map. gl_GlobalInvocationID is always (0, 0) from my debugging, and I'm not sure why. The good news is that something is being written inside of the compute shader, since I am able to retrieve an all-red texture, but I cannot write more than a solid color. I tried moving around the image binding as well as the dispatching command of the compute shader, but I haven't had any luck so far.
Not pictured is my shader program initializations, but no errors are being generated from compilation or linking, so I don't think the issue lies there. I believe that the image and texture formats are consistent and correct as well.
Thank you for any insight you could provide to this issue!
Compute Shader:
#version 430
layout(local_size_x = 1, local_size_y = 1) in;
layout(rgba32f, binding = 0) uniform image2D noiseImage;
void main() {
vec4 color = vec4(0.0, 0.0, 0.0, 1.0);
ivec2 pixel = ivec2(gl_GlobalInvocationID.xy);
// Debugging
if (pixel.x == 0 && pixel.y == 0) {
color = vec4(1.0, 0.0, 0.0, 1.0);
} else {
color = vec4(0.0, 1.0, 0.0, 1.0);
}
imageStore(noiseImage, pixel, color);
}
OpenGL Code:
width = 512;
height = 512;
noiseTexture = 0;
// Snipped (runs once)
glGenTextures(1, &noiseTexture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, noiseTexture);
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);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, NULL);
glBindImageTexture(0, noiseTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
// Snipped (runs every frame)
glUseProgram(computeShader);
glDispatchCompute(width, height, 1);
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, noiseTexture);
glUseProgram(vertex/fragment);
render();
Hmm, so you're rendering the resulting image afterwards? Do you perhaps need the GL_TEXTURE_FETCH_BARRIER_BIT barrier too, so that the results of the compute shader rendering are visible to the texture fetch?
Related
I cannot get sampler3D value in my GLSL fragment shader.
I am writing a shader in GLSL and want to take sampler3D (3d texture) as volume data and do volume rendering. However, seems I cannot bind 3d texture to my shader's sampler3D. texture3D() always returns (0,0,0,0) on shader side. But on my application side, I can use glGetTexImage to get the data.
Application Side (dS is a Shader class object):
dS.use();
dS.setInt("volumeData", 0);
uint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_3D, texture);
float data[64];
for (int i = 0; i < 64; ++i) data[i] = 1.0f;
glTexImage3D(GL_TEXTURE_3D, 0, GL_R16F, 4, 4, 4, 0, GL_RED, GL_FLOAT, data);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_3D, 0);
float read[64];
glBindTexture(GL_TEXTURE_3D, texture);
glGetTexImage(GL_TEXTURE_3D, 0, GL_RED, GL_FLOAT, read);
std::cout << read[0] << "," << read[63] << std::endl; // 1,1
glBindTexture(GL_TEXTURE_3D, 0);
// When drawing.
dS.use();
dS.setMat4("model", glm::mat4(1.0f));
dS.setMat4("view", view);
dS.setMat4("projection", projection);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_3D, texture);
cube.draw();
Vertex Shader
#version 330 core
// for snow rendering
layout (location = 0) in vec3 aPos;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
}
Fragment Shader
#version 330
out vec4 FragColor;
uniform sampler3D volumeData;
void main()
{
ivec3 size = textureSize(volumeData, 0);
float c = texture3D(volumeData, vec3(0)).x;
if (size.x == 1)
FragColor = vec4(1.0, 0.0, c, 1.0);
else if (size.x > 2)
FragColor = vec4(0.0, 1.0, 0.0, 1.0);
else if (size.x == 0)
FragColor = vec4(0.0, 0.0, 1.0, 1.0);
else
FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
I only got a red cube, which means size.x == 1 and texture3D returns 0, which is expected to be size.x == 4 and texture3D returns 1.0
I used similar method for 2d texture and it works. So I guess my Shader class is right. And I also tried to add glEnable(GL_TEXTURE_3D) before I did any 3d texture operation.
And I am not sure if this helps: I used glfw-3.2.1 WIN64 and glad.
I solved it.
It's a really stupid typo.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
should use GL_TEXTURE_3D instead of GL_TEXTURE_2D.
And since GL_TEXTURE_MIN_FILTER default state is GL_NEAREST_MIPMAP_LINEAR. It leads to mipmap incompleteness.
I have a program that takes the following texture:
which is generated via FreeType2. Basically, it's creating a texture atlas for every character that I've requested to be drawn. As you can see, the characters are bright and clear. In fact, you can see that the top-leftmost pixel of the lowercase 'i' has a value of 71 (out of 255) or 0.7098 when I inspect the texture in RenderDoc.
Next, the engine blits letters onto a Framebuffer Object. This is done via textured quads. The vertex shader:
#version 330
layout(location=0) in vec2 inVertexPosition;
layout(location=1) in vec2 inTexelCoords;
layout(location=2) in float inDepth;
out vec2 texelCoords;
out float depth;
void main()
{
gl_Position = vec4(inVertexPosition.x,-inVertexPosition.y, 0.0, 1.0);
texelCoords = vec2(inTexelCoords.x,1-inTexelCoords.y);
depth = inDepth;
}
And the frag shader:
#version 330
layout(location=0) out vec4 frag_colour;
in vec2 texelCoords;
in float depth;
uniform sampler2D uTexture;
uniform vec4 uTextColor;
void main()
{
vec4 c = texture(uTexture,texelCoords);
frag_colour = uTextColor * c.r;
gl_FragDepth = depth;
}
As you can see, it's sets the pixel color to be a factor of the red channel.
However, when I view the contents of the FBO via RenderDoc, and saved out to file here, you see this:
If you look at this without transparency (just a second layer added underneath in Gimp to illustrate better):
You can see that the text is a little faded compared to what it was before. If you look at the top-leftmost pixel of the lowercase 'i', it's now a value of 50.2, or for a range of 0-1 it's 0.50196 (via RenderDoc).
Next, when the FBO is finally put onto the screen via another textured quad it fades even more. First here's the vertex shader:
#version 330
layout(location=0) in vec2 inVertexPosition;
layout(location=1) in vec2 inTexelCoords;
varying vec2 texelCoords;
void main()
{
gl_Position = vec4(inVertexPosition.x,-inVertexPosition.y, 0.0, 1.0);
texelCoords = vec2(inTexelCoords.x,1-inTexelCoords.y);
}
and the fragment shader:
#version 330
precision highp float;
layout(location=0) out vec4 frag_colour;
varying vec2 texelCoords;
uniform sampler2D uTexture;
void main()
{
vec4 c = texture(uTexture,texelCoords);
frag_colour = c;
}
The results, as I said are more faded than before:
original:
gimp background for clarity:
now that pixel has a value of 25.1 or 0.05139.
What is causing this fading after every render?
I think it's important to note that the brighter areas don't fade.
My Framebuffer creation code
glGenFramebuffers(1, &m_framebuffer);
glGenTextures(1, &m_fboColorAttachment);
glGenTextures(1, &m_fboAdditionalInfo);
glGenTextures(1, &m_fboDepthStencil);
glCall(glBindFramebuffer,GL_FRAMEBUFFER, m_framebuffer);
/* setup color output 0 */
glBindTexture(GL_TEXTURE_2D, m_fboColorAttachment);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
glCall(glTexImage2D, GL_TEXTURE_2D, 0, GL_RGBA8, screenDimensionsX, screenDimensionsY, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_fboColorAttachment, 0);
glBindTexture(GL_TEXTURE_2D, 0);
/* setup color output 1 */
glBindTexture(GL_TEXTURE_2D, m_fboAdditionalInfo);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
glCall(glTexImage2D, GL_TEXTURE_2D, 0, GL_R32UI, screenDimensionsX, screenDimensionsY, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, nullptr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, m_fboAdditionalInfo, 0);
glBindTexture(GL_TEXTURE_2D, 0);
/* setup depth and stencil */
glBindTexture(GL_TEXTURE_2D, m_fboDepthStencil);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
glCall(glTexImage2D, GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, screenDimensionsX, screenDimensionsY, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_fboDepthStencil, 0);
glBindTexture(GL_TEXTURE_2D, 0);
The initial (red) texture creation:
glActiveTexture(GL_TEXTURE0);
glGenTextures(1,&textureData.texture);
glBindTexture(GL_TEXTURE_2D,textureData.texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 500, 500, 0, GL_RED, GL_UNSIGNED_BYTE, 0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
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_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
My blending is done as
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
has a value of 71 (out of 255) or 0.7098
No idea, what you even mean here. 71/255 would be 0.278. 0.7098 normalized would be 181 out of 255. Looks like your "out of 255" are just percentage values, out of 100%.
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
You use that color values from the red channel also as alpha, so, when you have blending enabled, you end up with 0.7098*0.7098=.5038. Since the result will be rounded to the nearest reprersentable value, we rather end with 181/255 * 181/255 = .50382 rounded to 128/255
it's now a value of 50.2, or for a range of 0-1 it's 0.50196
128/255 is 0.50196078....
So the solution is: disable blending for all steps when you don't need it. Or if you need it, set useful alpha values.
Side note:
now that pixel has a value of 25.1 or 0.05139.
No Idea what this means, the 25.1 does not relate to 0.05139 in any obvious way, you definitively switched the meaning of those values again.
I'm attempting to generate a sky box for my OpenGL scene by using GLSL to texture quads. However, the sky box simply becomes black when I attempt to use the texture to generate the sky box color. The sky box works when I manually set the color, so I have basically narrowed the problem down to something being wrong with how I'm setting up the texture. I also messed around with a bunch of different eyeDirection vector values for the texture function, and I still get only a black square.
Here is my Fragment Shader:
#version 450 compatibility
layout(binding=0) uniform samplerCube currTexture;
smooth in vec3 eyeDirection;
out vec4 fragmentColor;
void main() {
fragmentColor = texture(currTexture, eyeDirection);
//fragmentColor = vec4(eyeDirection, 1.0);
}
Here is my vertex shader:
#version 450
uniform mat4 projection;
uniform mat4 modelView;
in vec4 aPosition;
smooth out vec3 eyeDirection;
void main() {
mat3 inverseModelView = inverse(mat3(modelView));
vec3 unprojected = (inverse(projection) * aPosition).xyz;
eyeDirection = inverseModelView * unprojected;
// eyeDirection = aPosition.xyz;
//gl_Position = aPosition.xyww;
gl_Position = new vec4(aPosition.x, aPosition.y, 1.0, aPosition.w );
}
Here is where I initialize the texture:
// initializes all the necessary texture values
void TrainView::initTextures() {
// loading in texture maps
SDL_Surface* xPos = IMG_Load("SkyBoxXpos.png");
SDL_Surface* xNeg = IMG_Load("SkyBoxXneg.png");
SDL_Surface* yPos = IMG_Load("SkyBoxYpos.png");
SDL_Surface* yNeg = IMG_Load("SkyBoxYneg.png");
SDL_Surface* zPos = IMG_Load("SkyBoxZpos.png");
SDL_Surface* zNeg = IMG_Load("SkyBoxZneg.png");
if (!xPos)
printf("IMG_Load: %s\n", IMG_GetError());
if (!xNeg)
printf("IMG_Load: %s\n", IMG_GetError());
if (!yPos)
printf("IMG_Load: %s\n", IMG_GetError());
if (!yNeg)
printf("IMG_Load: %s\n", IMG_GetError());
if (!zPos)
printf("IMG_Load: %s\n", IMG_GetError());
if (!zNeg)
printf("IMG_Load: %s\n", IMG_GetError());
// handle error
glGenTextures(1, &skyBoxTexture);
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_CUBE_MAP);
glBindTexture(GL_TEXTURE_CUBE_MAP, skyBoxTexture);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
// files are 24-bit bmp files
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, xPos->w, xPos->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, xPos->pixels);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, xNeg->w, xNeg->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, xNeg->pixels);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, yPos->w, yPos->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, yPos->pixels);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, yNeg->w, yNeg->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, yNeg->pixels);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, zPos->w, zPos->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, zPos->pixels);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, zNeg->w, zNeg->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, zNeg->pixels);
glBindTexture(GL_TEXTURE_CUBE_MAP, NULL);
}
Here is where I attempt to draw/render the sky box:
// handles everything for drawing the sky box
void TrainView::drawSkyBox(){
glUseProgram(skyBoxShader);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, skyBoxTexture);
int loc = glGetUniformLocation(skyBoxShader, "modelView");
GLfloat mvFl[16], projFl[16];
glGetFloatv(GL_MODELVIEW_MATRIX, mvFl);
glUniformMatrix4fv(loc, 1, GL_FALSE, mvFl);
loc = glGetUniformLocation(skyBoxShader, "projection");
glGetFloatv(GL_PROJECTION_MATRIX, projFl);
glUniformMatrix4fv(loc, 1, GL_FALSE, projFl);
loc = glGetUniformLocation(skyBoxTexture, "currTexture");
glUniform1i(loc, 0);
// not sure if this is necessary or done as intended by opengl
GLuint sampler;
glGenSamplers(1, &sampler);
glBindSampler(0, sampler);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glBegin(GL_QUADS);
glVertex3f(-1.0, -1.0, 0.0);
glVertex3f(1.0, -1.0, 0.0);
glVertex3f(1.0, 1.0, 0.0);
glVertex3f(-1.0, 1.0, 0.0);
glEnd();
glUseProgram(NULL);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
}
You are enabling mipmapped sampling for your cube texture here:
glTexParameteri(GL_TEXTURE_CUBE_MAP,
GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
However, you are not creating mipmaps for your texture. In spec language, this means that your texture is not "mipmap complete", which in turn makes it not "texture complete". The result of sampling an incomplete texture is BLACK.
The easiest way to create mipmaps is by calling glGenerateMipmap() after your texture data has been specified, i.e. after all the glTexImage2D() calls for the 6 sides:
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
If you don't need mipmaps, you can simply set the value of the filter parameter to not use mipmaps:
glTexParameteri(GL_TEXTURE_CUBE_MAP,
GL_TEXTURE_MIN_FILTER, GL_LINEAR);
What you attempted to do with creating a sampler object is not going to help here. Sampler objects are useful if you want to sample the same texture with multiple different sampling attributes. Say you wanted to sample the same texture with both GL_LINEAR and GL_NEAREST in the same shader, you could do that by creating two sampler objects for this texture. I don't think it's a very common use case, but there are situations where it comes in handy, and it was impossible to do before sampler objects were introduced.
I'm trying to sample a depth texture into a compute shader and to copy it into an other texture.
The problem is that I don't get correct values when I read from the depth texture:
I've tried to check if the initial values of the depth texture were correct (with GDebugger), and they are. So it's the imageLoad GLSL function that retrieve wrong values.
This is my GLSL Compute shader:
layout (binding=0, r32f) readonly uniform image2D depthBuffer;
layout (binding=1, rgba8) writeonly uniform image2D colorBuffer;
// we use 16 * 16 threads groups
layout (local_size_x = 16, local_size_y = 16) in;
void main()
{
ivec2 position = ivec2(gl_GlobalInvocationID.xy);
// Sampling from the depth texture
vec4 depthSample = imageLoad(depthBuffer, position);
// We linearize the depth value
float f = 1000.0;
float n = 0.1;
float z = (2 * n) / (f + n - depthSample.r * (f - n));
// even if i try to call memoryBarrier(), barrier() or memoryBarrierShared() here, i still have the same bug
// and finally, we try to create a grayscale image of the depth values
imageStore(colorBuffer, position, vec4(z, z, z, 1));
}
and this is how I'm creating the depth texture and the color texture:
// generate the deth texture
glGenTextures(1, &_depthTexture);
glBindTexture(GL_TEXTURE_2D, _depthTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, wDimensions.x, wDimensions.y, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
// generate the color texture
glGenTextures(1, &_colorTexture);
glBindTexture(GL_TEXTURE_2D, _colorTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, wDimensions.x, wDimensions.y, 0, GL_RGBA, GL_FLOAT, NULL);
I fill the depth texture with depth values (bind it to a frame buffer and render the scene) and then I call my compute shader this way:
_computeShader.use();
// try to synchronize with the previous pass
glMemoryBarrier(GL_ALL_BARRIER_BITS);
// even if i call glFinish() here, the result is the same
glBindImageTexture(0, _depthTexture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32F);
glBindImageTexture(1, _colorTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);
glDispatchCompute((wDimensions.x + WORK_GROUP_SIZE - 1) / WORK_GROUP_SIZE,
(wDimensions.y + WORK_GROUP_SIZE - 1) / WORK_GROUP_SIZE, 1); // we divide the compute into groups of 16 threads
// try to synchronize with the next pass
glMemoryBarrier(GL_ALL_BARRIER_BITS);
with:
wDimensions = size of the context (and of the framebuffer)
WORK_GROUP_SIZE = 16
Do you have any idea of why I don't get valid depth values?
EDIT:
This is what the color texture looks like when I render a sphere:
and it seems that glClear(GL_DEPTH_BUFFER_BIT) doesn't do anything:
Even if I call it just before the glDispatchCompute() I still have the same image...
How can this be possible?
Actually, i discovered that you cannot send a depth texture as an image to a compute shader, even with the readonly keyword.
So i've replaced:
glBindImageTexture(0, _depthTexture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32F);
by:
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _depthTexture);
and in my compute shader:
layout (binding=0, r32f) readonly uniform image2D depthBuffer;
by:
layout (binding = 0) uniform sampler2D depthBuffer;
and to sample it i just write:
ivec2 position = ivec2(gl_GlobalInvocationID.xy);
vec2 screenNormalized = vec2(position) / vec2(ctxSize); // ctxSize is the size of the depth and color textures
vec4 depthSample = texture2D(depthBuffer, screenNormalized);
and it works very well like this
I'm trying to show a greyscale texture on the screen. I create my texture via
glGenTextures(1, &heightMap);
glBindTexture(GL_TEXTURE_2D, heightMap);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 512, 512, 0, GL_RED, GL_FLOAT, colorData);
colorData is a float[512*512] with values between 0.0 and 1.0.
When rendering, I use:
glBindTexture(GL_TEXTURE_2D, heightMap);
glUniform1i(shader.GetUniformLocation("textureSampler"), 0);
shader.GetUniformLocation is a function of a library we use at university. It is essentially the same as glGetUniformLocation(shader, "textureSampler"), so don't be confused by it.
I render two triangles via triangle strip. My fragment shader is:
#version 330
layout(location = 0) out vec4 frag_color;
in vec2 texCoords;
uniform sampler2D textureSampler;
void main()
{
frag_color = vec4(texture(textureSampler, texCoords).r, 0, 0, 1);
}
I know the triangles are rendered correctly (e.g. if I use vec4(1.0, 0, 0, 1) for frag_color, I get a completely red screen). However with the line above, I only get a completely black screen. Every texture value seems to be 0.0.
Does anyone have an idea, what I have done wrong? Are there mistakes in that few lines of code or are these completely correct and the error is somewhere else?
As one of the comments below says, setting glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); and glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); solves the problem. :)