如何将纹理作为一个 16 位(灰度)组件发送到 GPU?
How do I send a texture to the GPU as one component 16 bit (greyscale)?
我有一个 16 位灰度 PNG,其值在 [0,65535] 中,我在 WebGL 中用作纹理:
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
在着色器中,我只读取 R 分量并使用此值从颜色 table 中查找 RGBA。
这很好用。但是我真的不明白这里发生了什么。图像每个像素有 2 个字节。相反,我告诉 WebGL 它有 4 个组件,每个组件有 1 个字节。我认为这会导致读取两个像素而不是一个像素。
图像精度为 2 字节。由于每个组件都被指定为只有 1 个字节,我想知道;我这样做会失去精度吗?
理想情况下,我只想将一个 16 位通道 R 发送到 GPU。
我该怎么做?
无法将 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 将首先获取图像、视频或 canvas 并将其转换为 format
、type
,同时考虑 UNPACK_PREMULTIPLY_ALPHA_WEBGL
、UNPACK_FLIP_Y_WEBGL
和 UNPACK_COLORSPACE_CONVERSION_WEBGL
设置。然后它将调用 glTexImage2D
因为 WebGL 不支持 16 位整数格式,但无法上传 16 位整数通道。如果用户的机器支持这些格式并且您启用了扩展 OES_texture_float
and or OES_texture_half_float
,则可以上传到浮点或半浮点纹理,但是当从图像转换时,无法保证转换会有多大损失。另外,AFAIK Safari 是唯一可以加载 16 位和/或浮点图像的浏览器(它接受图像标签中的 16 位和 32 位 .TIF 文件,或者我上次检查大约 4 年前)。它是否在 WebGL 中无损上传它们我不相信在 WebGL 规范中指定也没有测试。无损上传只需要 8 位图像,并且前提是您正确设置了 UNPACK_
设置。
当然,您始终可以使用 ArrayBuffer 自己上传数据以获得无损半浮点数或浮点数数据。但否则你需要将数据分成 8 位通道。
我有一个 16 位灰度 PNG,其值在 [0,65535] 中,我在 WebGL 中用作纹理:
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
在着色器中,我只读取 R 分量并使用此值从颜色 table 中查找 RGBA。
这很好用。但是我真的不明白这里发生了什么。图像每个像素有 2 个字节。相反,我告诉 WebGL 它有 4 个组件,每个组件有 1 个字节。我认为这会导致读取两个像素而不是一个像素。
图像精度为 2 字节。由于每个组件都被指定为只有 1 个字节,我想知道;我这样做会失去精度吗?
理想情况下,我只想将一个 16 位通道 R 发送到 GPU。 我该怎么做?
无法将 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 将首先获取图像、视频或 canvas 并将其转换为 format
、type
,同时考虑 UNPACK_PREMULTIPLY_ALPHA_WEBGL
、UNPACK_FLIP_Y_WEBGL
和 UNPACK_COLORSPACE_CONVERSION_WEBGL
设置。然后它将调用 glTexImage2D
因为 WebGL 不支持 16 位整数格式,但无法上传 16 位整数通道。如果用户的机器支持这些格式并且您启用了扩展 OES_texture_float
and or OES_texture_half_float
,则可以上传到浮点或半浮点纹理,但是当从图像转换时,无法保证转换会有多大损失。另外,AFAIK Safari 是唯一可以加载 16 位和/或浮点图像的浏览器(它接受图像标签中的 16 位和 32 位 .TIF 文件,或者我上次检查大约 4 年前)。它是否在 WebGL 中无损上传它们我不相信在 WebGL 规范中指定也没有测试。无损上传只需要 8 位图像,并且前提是您正确设置了 UNPACK_
设置。
当然,您始终可以使用 ArrayBuffer 自己上传数据以获得无损半浮点数或浮点数数据。但否则你需要将数据分成 8 位通道。