使用 webgl 将高位深度纹理渲染到屏幕

Using webgl to render high bit-depth textures to the screen

我们的项目使用位深度高于 8 位(通常为 10 位)的图像。这些存储在 16 位 PNG 中,具有 P3 色彩空间(因此每个通道 1024 种颜色)。

我正在尝试使用 WebGL2 在浏览器中显示这些图像。到目前为止没有运气。我知道 Chrome 可以做到这一点,因为我有一些测试图像可以在我的 Macbook 视网膜屏幕上显示扩展的色彩范围(但在 8 位外接显示器上没有)。

这是测试图片:https://webkit.org/blog-files/color-gamut/Webkit-logo-P3.png (Source: https://webkit.org/blog/6682/improving-color-on-the-web/)

如果您使用的是 8 位屏幕和硬件,测试图像将完全是红色的。如果你有一个高位深度显示器,你会看到一个微弱的 webkit 标志。尽管我的高位深度监视器在 Chrome 中显示徽标细节,但应用此纹理的 WebGL 四边形看起来是红色的。

我的研究表明 WebGL/OpenGL 确实提供了对浮点纹理和高位深度的支持,至少在绘制到渲染目标时是这样。

我想要实现的很简单,在 WebGL 中使用高位深度纹理,应用于屏幕上的四边形。这是我加载纹理的方式:

var texture = gl.createTexture();
gl.activeTexture(gl.TEXTURE0 + 0);
gl.bindTexture(gl.TEXTURE_2D, texture);

// Store as a 16 bit float
var texInternalFormat = gl.RGBA16F;
var texFormat = gl.RGBA16F;
var texType = gl.FLOAT;

var image = new Image();
image.src = "10bitTest.png";
image.addEventListener('load', function() {
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texImage2D(
    gl.TEXTURE_2D,
    0,
    texInternalFormat,
    texFormat,
    texType,
    image
    );
    gl.generateMipmap(gl.TEXTURE_2D);
});

这失败了

 WebGL: INVALID_ENUM: texImage2D: invalid format

如果我将 texFormat 更改为 gl.RBGA,它会呈现四边形,但呈现纯红色,没有扩展颜色。

我想知道这是否可能,尽管 Chrome 可以做到,所以我仍然抱有希望。

据我所知

  1. 您不能(截至 2020 年 6 月)在任何浏览器中创建每个通道超过 8 位的 canvas。有提案,但 none 已发货

  2. 您无法通过 imgImageBitmap 将每通道 8 位以上的图像加载到 WebGL 中。没有 tests 大于 8 位的数据进入纹理。

如果您自己在 JavaScript 中解析和加载图像,则可以将每通道 > 8 位的图像加载到纹理中,但随后又回到问题 #1,即除了绘制之外无法显示它它变成每通道 8 位 canvas。您可以将数据拉回 JavaScript,生成 16 位图像 blob,为 blob 获取 URL,使用该 URL 添加 img 标签并祈祷浏览器支持绘制它> 每通道 8 位。

郑重声明,目前这是不可能的。最近 activity 看起来很有希望:

https://bugs.chromium.org/p/chromium/issues/detail?id=1083693&can=2&q=component%3ABlink%3ECanvas%20colorspace