[英]glsl VertexShader/FragmentShader refuse to compile in OpenTk c#
[英]glsl fragmentshader render objectID
如何将对象的整数ID正确呈现为整数纹理缓冲区?
假设我有一个带有内部格式GL_LUMINANCE16的texture2D,我将它作为颜色附件附加到我的FBO。
渲染对象时,我将整数ID传递给着色器,并希望将此id渲染为整数纹理。
片段着色器输出的类型为vec4。 如何正确地将我的ID转换为四个组件浮点数并避免转换不准确,以便最终整数纹理目标中的整数值对应于我想要渲染的整数ID?
我仍然认为这里没有明确的答案。 所以这就是我通过2D纹理使其工作的方式:
// 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);
在GLSL端,片段着色器应具有(此处为4.3核心配置文件代码):
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.
}
您可以在主机端读取值:
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);
你的问题有几个问题。
首先, GL_LUMINANCE16
不是 “整数纹理”。 它是一个包含规范化无符号整数值的纹理。 它使用整数来表示范围[0,1]上的浮点数。 如果要存储实际整数,则必须使用实际的整数图像格式 。
其次,你无法渲染到亮度纹理; 它们不是颜色可渲染的格式。 如果您确实要渲染到单通道纹理,则必须创建单通道图像格式。 因此,而不是GL_LUMINANCE16
,您使用GL_R16UI
,这是一个16位单通道无符号整数图像格式。
现在你已经正确设置了它,这非常简单。 定义uint
片段着色器输出并让片段着色器将uint
值写入其中。 这个uint
可能来自顶点着色器或来自制服; 但是你想要这样做。
显然你还需要将你的纹理或渲染缓冲器附加到FBO,但我很确定你知道这一点。
最后一件事:不要使用短语“纹理缓冲区”,除非你的意思是其中之一 。 否则,它会让人感到困惑。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.