前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OpenGL ES 如何渲染 16bit 图像(P010)?

OpenGL ES 如何渲染 16bit 图像(P010)?

作者头像
字节流动
发布2024-01-02 17:14:45
3220
发布2024-01-02 17:14:45
举报
文章被收录于专栏:字节流动字节流动

16bit 图像(P010)

可以类比,10bit YUV 就是每个 Y、U、V 分量分别占用 10 个 bit ,但是实际处理中,我们是以字节为单位进行存储和处理的,所以最终处理的数据是以 2 个字节来存储 10bit 的有效数据。

也就是说 10bit YUV ,每个像素( Y 分量)将占用 16bit 两个字节,但是其中 6 个 bit 是 padding ,补 0 。

10bit YUV 结构

为什么要了解 10bit YUV ? 最近发现越来越多的视频解码出来是 10bit YUV 的图像,毫无疑问 10bit YUV 会有更好的动态范围,能表现出更丰富的颜色信息

随着移动设备性能不断提升,这种能表现更高动态范围的图像存储格式将会逐渐成为主流,但是现在很多算法都不能直接处理 10bit 的 YUV ,都是先将其转换为 8bit YUV ,然后再进行处理,这实际上是丢弃了 10bit YUV 的图像高动态范围优势。

关于 P010 与 NV21 的转换可以参考文章 10bit YUV(P010)的存储结构和处理

OpenGL ES 如何渲染 16bit 图像?

最近有不少读者私信问 OpenGL ES 如何处理 16bit 图像(P010)?

然后我直接贴给他们一段在 OpenGL 环境下验证过的上传 16bit 图像数据的代码

代码语言:javascript
复制
glTexImage2D(GL_TEXTURE_2D, 0, GL_R16UI, width, height, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, data);

看了下 OpenGL ES 实际上也是支持这一套格式,但是我之前没有在 GL ES 环境下运行验证过。

据读者普遍反馈,这套 16bit 的纹理格式在 ES 上无法正常使用,尽管文档是支持这套格式。

既然直接使用 16bit 的格式不行,也不能直接使用 CPU 转换成 8bit 的图像(性能过慢),又要想 GPU 直接处理 16bit 图像,我觉得可以利用 2 个通道 8bit 格式如 GL_LUMINANCE_ALPHA 或者 GL_RG8 完成加载 16bit 图像数据到纹理,然后采样的时候再将 2 个 8bit 数据转换成 16bit .

在 shader 采样之后,每一个通道的值都会被归一化,8bit 归一化之前的范围是 0~255,16bit 归一化之前的范围是 0~65535, 2 个 8bit 值进行移位求和转成 16bit 值,最后再进行归一化。

对应的片段着色器如下,这里默认 16bit 为小端序。

代码语言:javascript
复制
#version 300 es
precision highp float;
in vec2 v_texCoord;
uniform sampler2D u_texture;
out vec4 outColor;
void main() {
    vec4 col = texture(u_texture, v_texCoord);
    float val = 255.0 * col.r + col.a * 255.0 * pow(2.0, 8.0);
    outColor = vec4(vec3(val / 65535.0), 1.0);
}

加载数据到纹理:

代码语言:javascript
复制
    glBindTexture(GL_TEXTURE_2D, m_uTextureId);

    glTexImage2D ( GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, m_RenderImage.width, m_RenderImage.height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, m_RenderImage.ppPlane[0]);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glBindTexture(GL_TEXTURE_2D, GL_NONE);

渲染效果与原图一致

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-12-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 字节流动 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 16bit 图像(P010)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档