在OpenGL ES中存储纹理中的浮动

时间:2014-04-17 04:27:35

标签: opengl-es

在WebGL中,我正在尝试使用每个由4个浮点值组成的纹素来创建纹理。在这里,我尝试创建一个简单的纹理,其中包含一个vec4

var textureData = new Float32Array(4);

var texture = gl.createTexture();
gl.activeTexture( gl.TEXTURE0 );
gl.bindTexture(gl.TEXTURE_2D, texture);

gl.texImage2D(
          // target, level, internal format, width, height 
          gl.TEXTURE_2D, 0, gl.RGBA, 1, 1,
          // border, data format, data type, pixels
          0, gl.RGBA, gl.FLOAT, textureData
      );

我的目的是使用像这样的采样器在着色器中对其进行采样:

uniform sampler2D data;
...
vec4 retrieved = texture2D(data, vec2(0.0, 0.0));

但是,我在gl.texImage2D期间收到错误:

WebGL: INVALID_ENUM: texImage2D: invalid texture type
WebGL error INVALID_ENUM in texImage2D(TEXTURE_2D, 0, RGBA, 1, 1, 0, RGBA, FLOAT,
[object Float32Array])

比较texImage2D的{​​{3}}和OpenGL ES spec,似乎不允许我使用gl.FLOAT。在那种情况下,我将如何完成我想要做的事情?

2 个答案:

答案 0 :(得分:2)

您可以从float数组创建一个字节数组。每个浮点数应该是4字节(32位浮点数)。可以使用带有无符号字节的标准RGBA格式将此数组放入纹理中。这将创建一个纹理,其中每个纹素包含一个32位浮点数,这似乎正是您想要的。

唯一的问题是,当您从片段着色器中的纹理中检索浮动值时,浮动值会被拆分为4个浮动值。所以你要找的东西最有可能是“how to convert vec4 into a single float”。

你应该注意你正在尝试用内部格式做什么,因为RGBA由32位浮点组成将不起作用,因为你的纹理总是每个纹素是32位,所以即使以某种方式强制浮动进入纹理也会导致钳位或精度损失。然后,即使纹理纹理元素由4个RGBA 32位浮点数组成,您的着色器也很可能在某些时候使用lowp将它们视为texture2D

答案 1 :(得分:1)

我的问题的解决方案实际上非常简单!我只需要输入

var float_texture_ext = gl.getExtension('OES_texture_float');

现在WebGL可以使用纹理浮动!

This MDN page告诉我们原因:

  

注意:在WebGL中,与其他GL API不同,扩展仅在明确请求时可用。