【问题标题】:Fetching integer/byte texture data "as is" in openGL ES 3.0在 openGL ES 3.0 中“按原样”获取整数/字节纹理数据
【发布时间】:2016-04-08 22:23:39
【问题描述】:

我在 IOS 上玩了一些技巧来尝试构建一个 CPU-GPU-hybrid JPEG 编码器。从我对 CPU 的测试来看,我相信使用 GPU 来执行 DCT 和量化步骤很有意义,并且应该会显着提高性能(压缩大量 JPEG 是我应用程序的瓶颈)。有了变换反馈,这应该是可行的,因为我已经用它在 GPGPU 计算中获得了很好的结果。棘手的部分是如何有效地获取数据(RGBA 的无符号整数)。

如前所述,我曾经使用 openGL ES 3.0 进行 GPGPU 计算,所以我只有浮点纹理的经验,这是由

glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA32F,WIDTH,HEIGHT,0,GL_RGBA,GL_GLOAT,data);

并通过

传递给着色器
texelFetch()

但是现在我的输入数据存储为一个无符号字节(或 uint8)数组,我需要每次依次获取其中的 64 个。我想我可以将它们作为无符号字节的纹理获取,或者更有效地作为无符号整数的纹理获取,然后通过位移将它们分开。

我的问题是,我该怎么做呢?更具体地说,我应该如何为 glTexImage2D() 设置 internalFormatformattype?我尝试了很多组合,但它们都只在着色器中提供了 0(我仔细检查了数据源,它们不是零)。

【问题讨论】:

  • 对于普通的 RGBA,每个像素已经有 4 个字节。 glTexImage2D() 可用于逐字节获取,因为每个 vec4 组件都代表该字节中的一个。这些值已标准化,因此您需要将它们乘以 255 以获得表示一个字节的整数值。因此,通过对 glTexImage2D() 进行 16 (64/4) 次调用,您可以获得 64 个字节。还是我在这里遗漏了什么?
  • 抱歉,不是 glTexImage2D()。我的意思是着色器中的纹素提取。
  • 是的,那是我的 B 计划。我遇到的问题是我不知道如何获取存储为无符号字节的纹理(或者如何为此配置 glTexImage2D)。如果可能的话,我很想跳到计划 A,在其中我获取一个整数(四个字节)而不是一个字节作为“像素”,这会将获取的次数减少到 64/4/4=4。
  • 我不确定您是否能够将纹理配置为每像素存储超过 32 位(实际上更少),因此实际上可能无法实现 A 计划。但是,如果您确实找到了一些可靠的东西,我会很高兴听到它……也许是一些普遍支持的扩展或其他东西。 B-Plan:GL_RGBA 用于配置每个像素存储 4 个无符号字节。如上所述,您应该通过将它们乘以 255 来缩放这些值。

标签: opengl-es opengl-es-3.0


【解决方案1】:

在 ES 3 中,认真考虑创建一个像素解包缓冲区并对其进行映射,以便获得一个位置来制定您的像素数据。这至少会节省驱动程序内部的memcpy,并且可以显着用于减少同步。在glBindBuffergl[Un]MapBuffer[Range] 上见GL_PIXEL_UNPACK_BUFFER;你最终会得到一个glTexImage2D(..., (void *)0); 来将像素解包缓冲区指定为源,类似于将绑定缓冲区指定为属性、元素等的源的方式。请参阅glFenceSync 进行同步假设您使用@987654327 @ 并因此打算自己处理同步。

对于全整数RGBA(无缩放)使用GL_RGBA8UI作为内部格式,GL_RGBA_INTEGER作为格式,GL_UNSIGNED_BYTE作为类型;然后声明一个usampler2d('u' 表示无符号,隐式整数)并使用标准texture(sampler, coordinate) 进行采样。

您还需要GL_CLAMP_TO_EDGEGL_NEAREST 纹理参数。

编辑:同样值得一提的是,来自usampler2d 的值属于uvec4 类型,因此它们是不可分割的。与 ES 2 不同,ES 3 有真正的整数,包括位运算符——ES 2 允许它们被浮点数模拟(对于我们这些 90 年代的人来说,这确实是一个意想不到的未来)。因此,我最近的一个仿真项目中值得一提的简化且足够琐碎的 sn-p:

vec4 rgb_sample(usampler2D sampler, vec2 coordinate)
{
    uint texValue = texture(sampler, coordinate).r;
    return vec4(texValue & 4u, texValue & 2u, texValue & 1u, 1.0);
}

这当然是将 TTL 样式的 RGB-in-one-byte 单通道纹理解压缩为适合 gl_FragColor 的格式(依赖于饱和度)。

【讨论】:

  • 感谢您提供大量详细信息!这对我来说很有意义,我会在尝试后更新它的结果。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-17
  • 1970-01-01
  • 2012-03-04
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
相关资源
最近更新 更多