简体   繁体   中英

glsl fragmentshader render objectID

How do I properly render an integer ID of an object to an integer texture buffer?

Say I have a texture2D with internal format GL_LUMINANCE16 and i attach it as color attachment to my FBO.

When rendering an object, i pass an integer ID to the shader and would like to render this id into my integer texture.

fragmentshader output is of type vec4 however. How do I properly transform my ID to four component float and avoid conversion inaccuracies such that in the end the integervalue in my integer texture target corresponds to the integer ID i wanted to render?

I still don't think that there is a clear answer here. So here is how I made it work through a 2D texture:

// First, create a frame buffer:
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);

// Then generate your texture and define an unsigned int array:
glGenTextures(1, &textureid);
glBindTexture(GL_TEXTURE_2D, textureid);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, w, h, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

// Attach it to the frame buffer object:
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, textureid, 0);

// Before rendering    
glBindFramebuffer(GL_FRAMEBUFFER, fbo);    
GLuint buffers[2] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; // this assumes that there is another     texture that is for the render buffer. Color attachment1 is preserved for the element ids.
glDrawBuffers(2, buffers);

// Clear and render here
glFlush(); // Flush after just in case
glBindFramebuffer(GL_FRAMEBUFFER, 0);

On the GLSL side the fragment shader should have (4.3 core profile code here):

layout(location = 0) out vec4 colorOut; // The first element in 'buffers' so location 0    
layout(location = 1) out uvec4 elementID; // The second element in 'buffers' so location 1. unsigned int vector as color

// ...
void main()
{
//...

elementID = uvec4( elementid, 0, 0, 0 ); // Write the element id as integer to the red channel.

}

You can read the values on the host side:

unsigned int* ids = new unsigned int[ w*h ];
glBindTexture(GL_TEXTURE_2D, textureid);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, ids);

There are several problems with your question.

First, GL_LUMINANCE16 is not an "integer texture." It is a texture that contains normalized unsigned integer values. It uses integers to represent floats on the range [0, 1]. If you want to store actual integers, you must use an actual integer image format .

Second, you cannot render to a luminance texture; they are not color-renderable formats. If you actually want to render to a single-channel texture, you must create a single-channel image format. So instead of GL_LUMINANCE16 , you use GL_R16UI , which is a 16-bit single-channel unsigned integral image format.

Now that you have this set up correctly, it's pretty trivial. Define a uint fragment shader output and have your fragment shader write your uint value to it. This uint could come from the vertex shader or from a uniform; however you want to do it.

Obviously you'll also need to attach your texture or renderbuffer to an FBO, but I'm fairly sure you know that.

One final thing: don't use the phrase "texture buffer" unless you mean one of these . Otherwise, it gets confusing.

I suppose that your integer ID is an identifier for a set of primitives; indeed it can be defined as an shader uniform:

uniform int vertedObjectId;

Once you render, you want to store the fragment processing into an integer texture . Note that integer textures shall be sampled with integer samplers ( isampler2D ), which returns integer vectors (ie ivec3 ).

This texture can be attached to a framebuffer object (be aware of framebuffer completeness ). The framebuffer attachment can be bound to an integer output variable:

out int fragmentObjectId;

void main() {
    fragmentObjectId = vertedObjectId;
}

You need a few extension supports, or an advanced OpenGL version (3.2?).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM