如何将纹理作为一个组件16位(灰度)发送到GPU?

时间:2015-09-17 10:55:23

标签: opengl-es webgl

我有一个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个字节;我这样做是否会失去精确度?

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

1 个答案:

答案 0 :(得分:4)

无法将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_WEBGL和{{1} }设置。然后它会调用UNPACK_COLORSPACE_CONVERSION_WEBGL

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

当然,您始终可以使用ArrayBuffer自行上传数据,以获得无损半浮点数或浮点数据。但是否则你需要将数据分成8位通道。