How to do complex image processing in compute shaders?

Hi there,

I'm trying to implement different image processing algorithms like grayscaling, filtering, quantizing etc. on Android smartphones. I've got the camera preview rendered to a quad
as an external texture, it works fine with grayscaling in fragment shader. But when I try to do the same in OpenGL ES 3.1 with compute shaders, I get invalid operation error,
when calling glBindImageTexture(...) before dispatch compute. According to https://www.khronos.org/registry/gles/extensions/OES/OES_EGL_image_external_essl3.txt

if I bind an external texture like GL_TEXTURE_EXTERNAL_OES and bind it with glBindImageTexture, I should be able to access the image via image2D sampler in GLSL.
What am I doing wrong?

Parents
  • In case someone like me ends up here with a similar or related problem, the issue for me was accessing external texture in compute shader as follows

    glBindImageTexture(texture_loc, texture_id, 0, false, 0, GL_READ_ONLY, format);
    
    --------------------------------------------------------------
    
    layout(rgba8, binding = 0) uniform readonly image2D inTexture;
    ...
    vec4 texColor = imageLoad(inTexture, storePos).rgba;

    Instead of this you should access and use them as we do in vertex/fragment shaders as follows

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id);
    glUniform1i(texture_loc, 0);
    
    --------------------------------------------------------------
    
    uniform samplerExternalOES sTexture
    ...
    vec4 cameraColor = texture(sTexture, vec2(float(gl_GlobalInvocationID.x)/width,float(gl_GlobalInvocationID.y)/height));
    

Reply
  • In case someone like me ends up here with a similar or related problem, the issue for me was accessing external texture in compute shader as follows

    glBindImageTexture(texture_loc, texture_id, 0, false, 0, GL_READ_ONLY, format);
    
    --------------------------------------------------------------
    
    layout(rgba8, binding = 0) uniform readonly image2D inTexture;
    ...
    vec4 texColor = imageLoad(inTexture, storePos).rgba;

    Instead of this you should access and use them as we do in vertex/fragment shaders as follows

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id);
    glUniform1i(texture_loc, 0);
    
    --------------------------------------------------------------
    
    uniform samplerExternalOES sTexture
    ...
    vec4 cameraColor = texture(sTexture, vec2(float(gl_GlobalInvocationID.x)/width,float(gl_GlobalInvocationID.y)/height));
    

Children