Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use texture buffers to read a single integer instead of vec4

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?

like image 932
viktorzeid Avatar asked Sep 06 '13 06:09

viktorzeid


People also ask

What is texture buffering?

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.

What is vec4 in opengl?

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.

What is texelFetch?

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.

What is uniform sampler2D?

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.


1 Answers

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!

like image 193
thokra Avatar answered Oct 11 '22 12:10

thokra