基于GL_RED_INTEGER的GLES 3.0物体拾取技术问题
问题:GLSL 3.0中如何直接向整数纹理写入物体ID以实现鼠标拾取
我绘制了一个包含大量物体的场景,希望实现鼠标选择物体的功能。计划将场景渲染到纹理,每个物体以编码了其ID的纯色绘制,随后读取纹理像素,获取鼠标位置对应的ID来选中物体。
我创建离屏缓冲的代码如下:
XGL(glTexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, mWidth, mHeight,0,GL_RED_INTEGER, GL_UNSIGNED_SHORT, mBits));
但我遇到了问题:不知道如何让GLSL 3.0着色器写入整数而非归一化浮点数。虽然可以将整数ID编码为归一化四通道浮点数,读取时再转换回来,但担心浮点精度误差(例如整数ID3转为浮点数后变为2.999999999999)。
请问是否有办法直接告知着色器写入指定字节到颜色缓冲,跳过浮点转换步骤?
解决方案
完全可以直接写入整数,需从以下两方面配置:
帧缓冲与纹理匹配
你已创建GL_R16UI类型的无符号整数纹理,需确保帧缓冲颜色附着点与纹理类型匹配。将纹理附加到帧缓冲时使用GL_COLOR_ATTACHMENT0这类附着点,绘制时指定该缓冲作为写入目标。GLSL 3.0着色器整数输出设置
- 片段着色器中声明整数类型输出变量:
out uvec1 objectID; // 对应GL_R16UI单通道无符号整数 // 多通道整数纹理可使用uvec2/uvec3/uvec4 - 主函数中直接赋值物体ID:
必须使用void main() { objectID = uvec1(your_object_id); // your_object_id为无符号整数类型ID }uvec(无符号整数向量)或ivec(有符号整数向量)类型输出,才能跳过浮点转换直接写入整数纹理,不能用普通vec类型中转。
- 绘制状态确认
- 绑定目标帧缓冲,通过
glDrawBuffers(1, &GL_COLOR_ATTACHMENT0)启用对应颜色附着点。 - 无需开启颜色归一化状态,整数纹理会直接存储原始整数。
补充:若ID范围在0~65535之间,GL_R16UI足以存储且无精度损失。读取像素时用glReadPixels,指定GL_RED_INTEGER格式与GL_UNSIGNED_SHORT类型,直接获取原始整数ID即可。
内容的提问来源于stack exchange,提问作者KiraHoneybee
相关产品推荐
相关产品推荐

