使用 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 可以做到,所以我仍然抱有希望。
据我所知
您不能(截至 2020 年 6 月)在任何浏览器中创建每个通道超过 8 位的 canvas。有提案,但 none 已发货
您无法通过 img
或 ImageBitmap
将每通道 8 位以上的图像加载到 WebGL 中。没有 tests 大于 8 位的数据进入纹理。
如果您自己在 JavaScript 中解析和加载图像,则可以将每通道 > 8 位的图像加载到纹理中,但随后又回到问题 #1,即除了绘制之外无法显示它它变成每通道 8 位 canvas。您可以将数据拉回 JavaScript,生成 16 位图像 blob,为 blob 获取 URL,使用该 URL 添加 img 标签并祈祷浏览器支持绘制它> 每通道 8 位。
郑重声明,目前这是不可能的。最近 activity 看起来很有希望:
我们的项目使用位深度高于 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 可以做到,所以我仍然抱有希望。
据我所知
您不能(截至 2020 年 6 月)在任何浏览器中创建每个通道超过 8 位的 canvas。有提案,但 none 已发货
您无法通过
img
或ImageBitmap
将每通道 8 位以上的图像加载到 WebGL 中。没有 tests 大于 8 位的数据进入纹理。
如果您自己在 JavaScript 中解析和加载图像,则可以将每通道 > 8 位的图像加载到纹理中,但随后又回到问题 #1,即除了绘制之外无法显示它它变成每通道 8 位 canvas。您可以将数据拉回 JavaScript,生成 16 位图像 blob,为 blob 获取 URL,使用该 URL 添加 img 标签并祈祷浏览器支持绘制它> 每通道 8 位。
郑重声明,目前这是不可能的。最近 activity 看起来很有希望: