Colors 使用webgl向屏幕渲染高位深度纹理

Colors 使用webgl向屏幕渲染高位深度纹理,colors,webgl,color-space,webgl2,Colors,Webgl,Color Space,Webgl2,我们的项目使用位深度大于8位(通常为10位)的图像。这些存储在16位PNG中,P3颜色空间(每个通道1024种颜色) 我正在尝试使用WebGL2在浏览器中显示这些图像。到目前为止没有运气。我知道Chrome可以做到这一点,因为我有一些测试图像,这些图像在我的Macbook的视网膜屏幕上显示了一个扩展的颜色范围(但在8位外部显示器上没有) 这是测试图像:(来源:) 如果您使用的是8位屏幕和硬件,测试图像将显示为完全红色。如果您有一个高位深度监视器,您将看到一个模糊的webkit徽标。尽管我的高比特

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

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

这是测试图像:(来源:)

如果您使用的是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可以做到,但我仍然抱着希望。

AFAIK

  • 您不能(截至2020年6月)在任何浏览器中创建每个频道超过8位的画布。有一些提案,但没有一个已经提交

  • 您不能通过
    img
    ImageBitmap
    将每通道超过8比特的图像加载到WebGL中。在纹理中没有大于8位的数据


  • 如果您自己用JavaScript解析并加载图像,则可以将每通道>8位的图像加载到纹理中,但问题1是,除了将其绘制到每通道8位的画布中,您无法显示图像。您可以将数据拉回到JavaScript中,生成一个16位的图像blob,获取blob的URL,使用该URL添加一个img标记,并祈祷浏览器支持每个通道绘制>8位的图像。

    对于记录,这目前是不可能的。最近的活动看起来很有希望:


    除非
    RENDERBUFFER\u INTERNAL\u FORMAT
    每种颜色的位数超过8位(请参见和),否则无法实现此功能。
    RGBA16F
    不是有效的格式。
    RGBA16F
    的内部格式的正确格式是
    RGBA
    (正如您已经注意到的)。该格式仅指定传入数据(
    图像
    ),但与纹理的存储或渲染方式无关。@Ivella不是渲染到纹理的RENDERBUFFER\u内部格式吗?我只是想呈现给屏幕注意:“扩展颜色”(正如您所写)与更高的位无关(对于更高的位,我们倾向于使用扩展颜色,但多年来我们一直使用DCI-P3或AdobeRGB“8位数据”屏幕(硬件经过校准,因此面板可以做得更多,就像现代优秀的10位屏幕具有14或16位功能一样);所以这些是正交的东西)。因此,我不确定您是否找到了问题的正确部分。@sipi您找到解决此问题的方法了吗?顺便说一句,这里是纹理内部格式、格式和类型的可能组合的官方列表:您说过“如果您自己用JavaScript解析并加载图像,您可以在纹理中加载每个通道>8位的图像”。。。您知道如何对视频流的一帧执行此操作吗?另外,关于将高深度图像加载到WebGL,这不是Chromium问题(2019年修复)应该支持的吗?他们在阿法克砍掉了它。这不是规范的一部分。有而且可能他们不测试16位图像。浏览器支持的格式取决于浏览器。例如,Safari不支持webm或webp(9/2020)。第二,如果没有一致性测试,你可以指望它不起作用。一致性测试例如,8位png的二进制数据可以完美地将其转换为纹理,即使默认情况下浏览器可能颜色正确。其他格式的二进制相等性没有经过AFAIK测试。因此,虽然您可以上传任何图像并请求浮点数据,但您无法确保数据没有从8位放大到有损。除非他们添加了一个需要它的一致性测试。你能做的最好的就是测试。制作一个1到4像素的浮动图像,将其作为浮动上传到纹理。呈现和读取结果的方式应确保您可以判断数据是否丢失。与16位图像相同。感谢您的澄清。CG并不是我的专业领域,所以我很难从一台热照相机上读取温度,它可以在16位图像中传输帧。随着当今高深度设备的普及,令人惊讶的是,浏览器仍然停留在每个通道8位。