在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
。在那种情况下,我将如何完成我想要做的事情?
答案 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不同,扩展仅在明确请求时可用。