Question

I have a working code where I am reading vec4 values in the shader from a texture buffer.

On the client side, I create a buffer of displacement vectors:

vec4 vector1 : vec4(x1, y1, z1, w1);
vec4 vector2 : vec4(x2, y2, z2, w2);
vec4 vector3 : vec4(x3, y3, z3, w3);
..

then I create a vertex buffer that contains vector1, vector2, vector3....

next, I create a texture and bind the above buffer to it using:

glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, bufferID);

I chose GL_RGBA32F because each of x1, y1, z1, w1, etc are float.

in the shader I can fetch the individual vectors using:

vec4 vector1 = texelFetch(samplerObj, 0);
vec4 vector2 = texelFetch(samplerObj, 1);
.
.

But, now suppose my displacement vector is not a vec4, but a single integer. i.e

int vector1 = x1; //(int is 32 bit unsigned)
int vector2 = x2; //(int is 32 bit unsigned)

can somebody please tell what will be the corresponding internalFormat be? is it

glTexBuffer(GL_TEXTURE_BUFFER, GL_R32UI, bufferID);

also how will I fetch the value using texelFetch in shader? is it

int vector1 = texelFetch(samplerObj, 0);

or

int vector1 = texelFetch(samplerObj, 0).r ?

I am confused because texelFetch should return a texel that has 4 components, so must I use the red component of the result?

Was it helpful?

Solution

You already mentioned the correct sized internal format for unsigned ints: R32UI. The permissible formats are enumerated in table 8.15, found in section 8.9 of the OpenGL 4.4 Core Profile Specification. Please note that the contents of the buffer store will not be normalized when using texelFetch on a buffer texture with the above internal format! That means, you don't get values in the range [0, 1] but in the range [0, 2^(n-1)] when doing lookups.

Instead of a samplerBuffer you will also need a usamplerBuffer.

If you do a texelFetch on a samplerBuffer with an internal format of R32UI, as specified in the aforementioned table, will return an uvec4 where the components returned will contain the following values: uvec4(R, 0, 0, 1).

int vector1 = texelFetch(samplerObj, 0);

This will lead to a compile-time error, because there is no implicit conversion from uvec4 to int.

int vector1 = texelFetch(samplerObj, 0).r;

this swizzle-mask will return the R-component of the uvec4 returned by texelFetch and do an implicit conversion from uint to int. Semantically, it also doesn't make sense to name a scalar value a vector. ;)

What you actually want is something like

uint displacement = texelFetch(samplerObj, 0).r;

where samplerObj is a usamplerBuffer.

EDIT: Just to clarify, texelFetch will always return a gvec4 - where g will simply by empty (fixed- and floating-point formats), i or u. How the vector is filled depends on the internal format of the buffer texture. If you choose R32F, you'll get a non-normalized vec4(R, 0, 0, 1), for RGBA16 you'll get a normalized vec4(R, G, B, A).

To avoid further confusion: you don't allocate memory for 4-component vectors when using a single-component format! They're all only expanded to a gvec4 on lookup!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top