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?
A Buffer Texture is a one-dimensional Texture whose storage comes from a Buffer Object. They are used to allow a shader to access a large table of memory that is managed by a buffer object.
vec4 is a floating point vector with four components. It can be initialized by: Providing a scalar value for each component. Providing one scalar value. This value is used for all components.
Description. texelFetch performs a lookup of a single texel from texture coordinate P in the texture bound to sampler . The array layer is specified in the last component of P for array forms. The lod parameter (if present) specifies the level-of-detail from which the texel will be fetched.
Language Definition uniform sampler2D texture1; void Function(in sampler2D myTexture); Samplers do not have a value. They can not be set by expressions and the only expression they can be used in is as the direct argument to a function call which takes an in sampler of that type.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With