1

I am implementing a feature extraction algorithm with OpenGL ES 3.0 (given an input texture with some 1's and mostly 0's, produce an output texture that has feature regions labeled). The problem I face in my fragment shader is how to perform a “lookup” on an intermediate vec or float rather than a sampler.

Conceptually every vec or float is just a texel-valued function, so there ought to be a way to get its value given texel coordinates, something like textureLikeLookup(texel_valued, v_color) - but I haven’t found anything that parallels the texture* functions.

The options I see are:

  1. Render my vector to a framebuffer and pass that as a texture into another shader/rendering pass - undesirable because I have many such passes in a loop, and I want to avoid interleaving CPU calls;
  2. Switch to ES 3.1 and take advantage of imageStore (https://www.khronos.org/registry/OpenGL-Refpages/es3.1/html/imageStore.xhtml) - it seems clear that if I can update an intermediate image within my shader then I can achieve this within the fragment shader (cf. https://www.reddit.com/r/opengl/comments/279fc7/glsl_frag_update_values_to_a_texturemap_within/), but I would rather stick to 3.0 if possible.

Is there a better/natural way to deal with this problem? In other words, do something like this

// works, because tex_sampler is a sampler2D
vec4 texel_valued = texture(tex_sampler, v_color); 

when the data is not a sampler2D but a vec:

// doesn't work, because texel_valued is not a sampler but a vec4
vec4 oops = texture(texel_valued, v_color);
Shir L
  • 11
  • 2
  • It's not clear whether you want to index into the vector like into an array, for which you can use "[]", or you are trying to do some sort of interpolation, for which you can use "lerp". Or whether you are trying to sample the texture again with your second call. For that you can just sample the texture, if you need the texel to the right of the previous one. – Tiberiu Maran Apr 01 '19 at 11:22
  • I would like to treat the vector as an array, but `[` provides lookup in the r/g/b/a dimension, not per-texel. I can't "just sample the texture," as I have done some per-texel computations and I would like to sample this secondary output _as if_ it were a texture. (In my code block, this is what I mean by `texel_valued`, which is no longer a true texture.) – Shir L Apr 01 '19 at 11:41
  • A `vec2` is just a `vec2` ... there is no "array" here. If you want array indexing then you need to declare an actual array of data to index in to ... – solidpixel Apr 01 '19 at 12:09
  • > "I can update an intermediate texture within my shader then I can achieve this within the fragment shader." Define how the update works when you are trying to parallelize across multiple fragments? It sounds like you want to read modifications from outside of the current pixel location, which you have no gurantee have been fragment shaded yet. – solidpixel Apr 01 '19 at 12:12
  • Sorry, not intermediate texture but intermediate _image_ - if I understand `imageStore`/`imageLoad` correctly it should be possible to achieve this by updating an image (atomically) as a way of storing per-texel state. – Shir L Apr 01 '19 at 12:20
  • Is your line defining "texel_valued" supposed to generate a virtual texture where newTexture[i][j] == oldTexture[i][j].xx * vec2(i ,j) / vec2(width, height) where 0 <= i < width, and 0 <= j < height? If not, what else? If you do a simple mapping between the two textures, you will be able to do it in one pass. If you have a more complex mapping, maybe doing multiple writes to one texel, you might need multiple passes. – Tiberiu Maran Apr 01 '19 at 12:36
  • 2
    I guess what i mean is that instead of providing pseudocode for what you think the solution should be, you should rather provide more information on your problem. https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem – Tiberiu Maran Apr 01 '19 at 12:45
  • > Is your line defining "texel_valued" supposed to generate a virtual texture where newTexture[i][j] == oldTexture[i][j].xx * vec2(i ,j) / vec2(width, height) where 0 <= i < width, and 0 <= j < height? Yes, exactly. I wrote a degenerate example but my goal is to store and update an ID per texel (region labels mentioned in original post). This works fine when I access the original texture, but once I have my state in a vec rather than a sampler (second iteration), I don't have a way access/update by coordinate. – Shir L Apr 01 '19 at 13:07
  • Just a side note here: texture2D is deprecated in _VERSION_>= ES 300. Assuming that the texture is just an 2D array and you want to use ES3 you have plenty of options to access and manipulate data like http://docs.gl/el3/texelFetch for example texelFetch(sampler2D myTex, ivec2(ARRAY_ROW_POSITION, ARRAY_COLUMN_POSITION)); I would go with option 1 "Render my vector to a framebuffer ..." – nabr Apr 01 '19 at 16:31
  • Thanks. The crux of my question is how to do a lookup entirely within GLSL (preferably ES3.0 and not 3.1, without doing a render and binding a new texture) when the texel data is stored in a vec and not a sampler. I also understand an SSBO might help, but again, that's ES3.1. I will update my code snippet to clarify as it has caused some confusion. – Shir L Apr 01 '19 at 18:38
  • @ShirL yeah, it wont work that way. You have to rethink your implementation. Maybe just (an other) hint that points you in the right direction, Here i iterate over some data with a for loop. You can do basically the same. And create a new 2D array. Scroll down to // here comes this importend part unpack the texture https://stackoverflow.com/questions/53765363/ray-tracing-a-scene-with-triangle-meshes-with-webgl-2-0-deferred-shading-frame/53770158#53770158 – nabr Apr 01 '19 at 21:12

0 Answers0