javascript - 获取使用gl.texImage2D绘制的纹理的 'red'像素值

标签 javascript webgl framebuffer glteximage2d webgl2

我使用纹理将 Float32array 发送到我的片段着色器(这里的目标是使用纹理将数据发送到着色器,在着色器中处理该数据,然后将其发送回 JavaScript)。由于我的数据实际上不是图像,因此我决定通过“gl.R32F”发送它,并且我尝试在使用 gl.readPixels 处理后读取该数据。这是我的代码,作为示例,尚未处理数据,首先我试图找到一种将数据发送回javascript的方法;

var canvas = document.getElementById('webgl-canvas');
var bbb = 4096*4096;
var widthcanvas = Math.sqrt(bbb)
canvas.width = widthcanvas;
canvas.height = widthcanvas;
var gl = initGL(canvas);

var boxVertices = new Float32Array([
    -1.0,  1.0,  0, 0, 
    -1.0, -1.0,  0, 1,
     1.0,  1.0,  1, 0,
     1.0, -1.0,  1, 1
]);
var boxVertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, boxVertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, boxVertices, gl.STATIC_DRAW);
var boxTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, boxTexture);

gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);


var data= new Float32Array(bbb);
for(var i = 0; i < bbb; i++) {
    data[i] = -i;
}

gl.texImage2D(gl.TEXTURE_2D, 0, gl.R32F, widthcanvas, widthcanvas, 0, gl.RED, gl.FLOAT, data);
gl.bindTexture(gl.TEXTURE_2D, null);

var a_position = gl.getAttribLocation(shaderProgram, 'a_position');
var a_textCoords = gl.getAttribLocation(shaderProgram, 'a_textCoords');

gl.vertexAttribPointer  (a_position, 2, gl.FLOAT, gl.FALSE, 4 * Float32Array.BYTES_PER_ELEMENT, 0);
gl.vertexAttribPointer(a_textCoords, 2, gl.FLOAT, gl.FALSE, 4 * Float32Array.BYTES_PER_ELEMENT, 2 * Float32Array.BYTES_PER_ELEMENT);



gl.enableVertexAttribArray(a_position);

gl.clearColor(0.75, 0.85, 0.8, 1.0);
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

gl.bindTexture(gl.TEXTURE_2D, boxTexture);
gl.activeTexture(gl.TEXTURE0);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);

var framebuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, boxTexture, 0);

var pixels = new Float32Array(gl.drawingBufferWidth * gl.drawingBufferHeight);
gl.readPixels(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight, gl.RED, gl.FLOAT, pixels);
console.log(pixels);
gl.deleteFramebuffer(framebuffer);

当我尝试将数据写入纹理时,我没有收到任何错误(尽管我不知道数据是否在没有任何更改的情况下发送,因为我无法读回它)。但是,当我尝试使用 gl.readPixels 读回它时,出现以下错误,

ERROR :GL_INVALID_FRAMEBUFFER_OPERATION : glReadPixels: framebuffer incomplete

所以,我的问题是这样的;

  1. 如果我使用纹理发送数据的方式是正确的,并且在此过程中我的数据没有改变,我如何将其发送回JavaScript?
  2. 如果我发送数据的方式错误,我该如何实现我的目标?

如果您能帮我解决这个问题,我将不胜感激。谢谢。

P.s:数据并不总是完美的平方。

最佳答案

pleup是对的。 R32F 需要扩展才能呈现色彩。当我将以下内容添加到代码中时,一切正常,

var ext = gl.getExtension('EXT_color_buffer_float');

再次感谢您的回答。

关于javascript - 获取使用gl.texImage2D绘制的纹理的 'red'像素值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47761831/

相关文章:

javascript - 重置按钮在表单提交之前有效,但在表单提交之后无效

javascript - Firefox 中奇怪的 JavaScript

javascript - 如何在 WebGL 的裁剪空间坐标中找到当前输出像素位置?

javascript - 从 Google Chrome 浏览器控制台使用所有请求立即回答 Quora 上的问题

WebGL2 渲染到 R32F 纹理

javascript - 如何让webGL扭曲它下面的HTML?

javascript - WebGL:使用帧缓冲区来拾取多个对象

android - 没有 GL_OES_packed_depth_stencil 的 OpenGL 帧缓冲区 android(在 Nexus 7 2012 上)

opengl - 设置 OpenGL 多个渲染目标

javascript - 我可以通过 Javascript 获取非标准 CSS 属性的值吗?