我有一个 webgl2 应用程序,在其中渲染到帧缓冲区,然后使用 readPixels 读取值。当我初始化帧缓冲区并随后使用 RGBA/UNSIGNED_BYTE 调用 readPixels 并将其读入 Uint8Array 时,此方法工作正常。但是,如果我尝试使用 RGBA16UI/RGBA_INTEGER/UNSIGNED_SHORT 执行此操作并读入 Uint16Array,则会收到“片段着色器输出类型与绑定的帧缓冲区附件类型不匹配”。当我调用 readPixels 时出错。
我像这样初始化帧缓冲区...
level = 0;
internalFormat = gWebGL.RGBA16UI;
border = 0;
format = gWebGL.RGBA_INTEGER;
type = gWebGL.UNSIGNED_SHORT;
data = null;
gWebGL.texImage2D(gWebGL.TEXTURE_2D, level, internalFormat, targetTextureWidth, targetTextureHeight, border, format, type, data);
// Create and bind the framebuffer
gFrameBuffer = gWebGL.createFramebuffer();
gWebGL.bindFramebuffer(gWebGL.FRAMEBUFFER, gFrameBuffer);
// attach the texture as the first color attachment
const attachmentPoint = gWebGL.COLOR_ATTACHMENT0;
gWebGL.framebufferTexture2D(gWebGL.FRAMEBUFFER, attachmentPoint, gWebGL.TEXTURE_2D, gTargetTexture, level);
渲染后,我像这样调用 readPixels...
var size = width * height * 4;
const pixels = new Uint16Array(size);
gWebGL.readPixels(
0,
0,
width,
height,
gWebGL.RGBA_INTEGER,
gWebGL.UNSIGNED_SHORT,
pixels,
);
当我调用 readPixels 时,我得到“片段着色器输出类型与绑定的帧缓冲区附件类型不匹配”。错误。
我还尝试了使用 RGBA32UI/UNSIGNED_INT 与 Uint32Array 的组合,结果相同。我关注过其他文章,这些文章似乎表明这些组合应该有效。我究竟做错了什么?感谢您的任何帮助或建议。
事实证明,问题是当使用 RGBA16UI/RGBA_INTEGER/UNSIGNED_SHORT 时,GLSL 片段着色器必须输出 uvec4,而不是 vec4。这是出乎意料的,因为纹理格式 RGBA/UNSIGNED_BYTE 确实允许着色器输出为 0 -> 1 范围内的 vec4 值,然后自动将它们映射到 0 -> 255 范围。