【问题标题】:How do I send a texture to the GPU as one component 16 bit (greyscale)?如何将纹理作为一个 16 位(灰度)组件发送到 GPU?
【发布时间】:2015-09-17 23:07:58
【问题描述】:

我有一个 16 位灰度 PNG,值在 [0,65535] 中,我在 WebGL 中用作纹理:

gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);

在着色器中,我只读取 R 组件并使用该值从颜色表中查找 RGBA。

这很好用。但是我真的不明白这里发生了什么。图像每个像素有 2 个字节。相反,我告诉 WebGL 它有 4 个组件,每个组件 1 个字节。我认为这将导致读取两个像素而不是一个。

图像的精度为 2 字节。由于每个组件都被指定为只有 1 个字节,我想知道;这样做会不会降低精度?

理想情况下,我只想向 GPU 发送一个 16 位通道 R。 我该怎么做?

【问题讨论】:

    标签: opengl-es webgl


    【解决方案1】:

    无法将 16 位纹理上传到 WebGL。您可以改为上传 2 个 8 位通道(如 R 和 G)并将它们添加到着色器中。

    vec4 color = texture2D(someSampler, someTexCoord);
    float value = color.r + color.g * 256.0f
    

    至于gl.texImage2D如何处理图片,gl.texImage2D采用以下参数。

    gl.texImage2D(target, level, internalFormat, 
                  format, type, image/video/canvas);
    

    WebGL 将首先获取图像、视频或画布并将其转换为 formattype,同时考虑到 UNPACK_PREMULTIPLY_ALPHA_WEBGLUNPACK_FLIP_Y_WEBGLUNPACK_COLORSPACE_CONVERSION_WEBGL 设置。然后它会调用glTexImage2D

    因为 WebGL 不支持 16 位整数格式,但无法上传 16 位整数通道。如果用户的机器支持这些格式并且您启用了扩展OES_texture_float 和或OES_texture_half_float,则可以上传到浮点或半浮点纹理,但是从图像转换时无法保证转换的损耗程度。另外,AFAIK Safari 是唯一可以加载 16 位和/或浮点图像的浏览器(它在图像标签中接受 16 位和 32 位 .TIF 文件,或者我上次检查大约 4 年前做过)。它是否在 WebGL 中无损上传它们我不相信在 WebGL 规范中指定也没有经过测试。只需正确设置UNPACK_ 设置,只需 8 位图像即可无损上传。

    当然,您始终可以使用 ArrayBuffer 自己上传数据以获得无损的半浮点或浮点数据。但除此之外,您需要将数据拆分为 8 位通道。

    【讨论】:

    猜你喜欢
    • 2015-12-23
    • 2015-05-02
    • 1970-01-01
    • 2013-03-18
    • 2014-01-31
    • 2015-08-11
    • 2012-02-07
    • 2011-09-19
    • 1970-01-01
    相关资源
    最近更新 更多