4
votes

So I have a Compute Shader that is supposed to take a texture and copy it over to another texture with slight modifications. I have confirmed that the textures are bound and that data can be written using RenderDoc which is a debugging tool for graphics. The issue I have is that inside the shader the variable gl_GlobalInvocationID, which is created by OpenGL, does not seem to work properly.

Here is my call of the compute shader: (The texture height is 480)

glDispatchCompute(1, this->m_texture_height, 1);            //Call upon shader
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);

And then we have my compute shader here:

#version 440
#extension GL_ARB_compute_shader : enable
#extension GL_ARB_shader_image_load_store : enable

layout (rgba8, binding=0) uniform image2D texture_source0;
layout (rgba8, binding=1) uniform image2D texture_target0;

layout (local_size_x=640 , local_size_y=1 , local_size_z=1) in; //Local work-group size

void main() {
  ivec2 txlPos;     //A variable keeping track of where on the texture current texel is from
  vec4 result;      //A variable to store color

  txlPos = ivec2(gl_GlobalInvocationID.xy);
  //txlPos = ivec2( (gl_WorkGroupID * gl_WorkGroupSize + gl_LocalInvocationID).xy  );

  result = imageLoad(texture_source0, txlPos);          //Get color value

  barrier();

  result = vec4(txlPos, 0.0, 1.0);

  imageStore(texture_target0, txlPos, result);          //Save color in target texture
}

When I run this the target texture becomes entirely yellow, save for a 1pxl thick green line along the left border and a 1pxl thick red line along the bottom border. My expectation is to see some sort of gradient given that a save txlPos as a colour value.

Am I somehow defining my work-groups wrong? I've tried splitting the gl_GlobalInvokationID up into its components but not managed to get any wiser fiddling with them.

1
A 8-bit floating point texture can usually only store values between 0 and 1. txlPos is usually larger than 1. What happens if you output float(txlPos) / vec2(640,480) instead?BDL
I got a gradient, black to yellow from left to right.Hoxbot
So that's almost what you want. I made a mistake with the float(..) thing, but I'll write an answer and correct this.BDL

1 Answers

4
votes

A 8-bit floating point texture can only store values between 0 and 1. Since gl_GlobalInvocationID is in most cases larger than 1, it get's clamped to the maximum value of 1 which makes the texture yellow.

If you want to create a gradient in both directions, then you have to make sure that the values stored start at 0 and end at 1. One possiblity is to divide by the maximum:

result = vec4(vec2(gl_GlobalInvocationID.xy) / vec2(640, 480), 0, 1);