You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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)。

请问是否有办法直接告知着色器写入指定字节到颜色缓冲,跳过浮点转换步骤?


解决方案

完全可以直接写入整数,需从以下两方面配置:

  1. 帧缓冲与纹理匹配
    你已创建GL_R16UI类型的无符号整数纹理,需确保帧缓冲颜色附着点与纹理类型匹配。将纹理附加到帧缓冲时使用GL_COLOR_ATTACHMENT0这类附着点,绘制时指定该缓冲作为写入目标。

  2. 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类型中转。
  1. 绘制状态确认
  • 绑定目标帧缓冲,通过glDrawBuffers(1, &GL_COLOR_ATTACHMENT0)启用对应颜色附着点。
  • 无需开启颜色归一化状态,整数纹理会直接存储原始整数。

补充:若ID范围在0~65535之间,GL_R16UI足以存储且无精度损失。读取像素时用glReadPixels,指定GL_RED_INTEGER格式与GL_UNSIGNED_SHORT类型,直接获取原始整数ID即可。


内容的提问来源于stack exchange,提问作者KiraHoneybee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 06:36:26