我有一个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. 我该怎么做?
答案 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将首先拍摄图片,视频或画布,并将其转换为format
,type
,并考虑UNPACK_PREMULTIPLY_ALPHA_WEBGL
,UNPACK_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位通道。