gpt4 book ai didi

c++ - 无法在 openGL 片段着色器中正确检索 16 位整数

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:50:20 27 4
gpt4 key购买 nike

我想做的:在片段着色器中使用带符号的 16 位整数进行 GPGPU 计算,在 iOS 上使用 openGL ES 2.0。

我已经验证我已经正确设置了我的(输入)纹理缓冲区和(输出)帧缓冲区,并且可以传递 16 位整数(通过使用无符号的 8 位指针别名到缓冲区),渲染单个字节到帧缓冲区,检索字节并在 CPU 端重建正确的 16 位值。

如果我调用 glClearColor,我可以传入诸如

之类的值
glClearColor(0.5, 0.5, 0.5, 0.5);  // endian-agnostic way to initialize buffer with "no data" values (-32640)
glClear(GL_COLOR_BUFFER_BIT);

我正在为 glClearColor 使用 (0.5, 0.5, 0.5, 0.5) 的测试值。这些应该等同于传入 -32640(有符号)或 32896(无符号)。

我可以正确地检索片段着色器中的值(作为无符号等价物)

#extension GL_EXT_shader_framebuffer_fetch : require

varying highp vec2 vTexCoord;
uniform sampler2D myTexture;

void main()
{
lowp vec4 myIntArray = texture2D( myTexture, vTexCoord);
// Retrieve value from frame buffer
lowp vec4 lastFragColor = gl_LastFragData[0];

// Recover the value (stored in alpha (high byte) and red (low byte)
highp float signed_value = lastFragColor.a;
signed_value = signed_value*255.0*256.0 + lastFragColor.r*255.0;

// ... Do stuff with the recovered value.
// Here, I simply verify value is recovered correctly (as an unsigned int equivalent):

// This draws the pixel green, indicating success
if (signed_value >= 32896.0) {
gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
}
else {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

// But changing the threshold value very slightly (replacing the lines
// above with those below) draws the pixel red, correctly
// indicating the condition is not met, because the value is
// 32896
if (signed_value >= 32896.01) {
gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
}
else {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
}

但是,我想传递一个不同值的数组,所以我没有使用 glClearColor,而是设置了一个缓冲区,并向它传递了一个指向我的有符号 16 位整数数组的指针(基本上是我的有符号 int16_t 的别名字节就好像它们只是无符号字节一样。)

然后我可以将这些渲染到帧缓冲区,并使用 glReadPixels 并将指向该数组的 int16_t 指针别名返回到 CPU 上,然后取回正确的值。然而,使用与上面相同的逻辑,但访问我的纹理而不是帧缓冲区:

highp float signed_value = myIntArray.a;
signed_value = value*255.0*256.0 + myIntArray.r*255.0;

使用纹理中的值,我只能在片段着色器中正确重建从 0 到 32767 的值,但不能重建 > 32767 的值。我需要能够重建 2^16 个可能值中的任何一个,无论是有符号的还是未签名。为什么我可以从帧缓冲区而不是我的纹理缓冲区重建大于 32767 的值?有什么想法吗?

(编辑添加:更正 - 似乎我无法通过我的纹理传入、渲染和检索所有 16 位整数......之前出现的负值是初始化的产物使用 glClear()。我通过我的纹理传递的负值呈现为黑色,并在 CPU 上重建为零。正确处理 0 到 32767 之间的值。所以...是否可以传递带符号的 int16 值(或 unsigned int16 值 > 32767) 并在片段着色器中正确重建它们?)

最佳答案

原来片段着色器代码没问题;我找错地方了。我不知道的是,“客户”正在将输入限制为非负数。谜团解开了,尽管前额被打了一巴掌。

关于c++ - 无法在 openGL 片段着色器中正确检索 16 位整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30202732/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com