繁体   English   中英

WebGL 从屏幕外画布正确读取像素

[英]WebGL Reading pixels properly from offscreen canvas

我知道这方面有很多资源,但没有一个对我有用。
有些是: webgl readpixels 总是返回 0,0,0,0
还有这个: https://stackoverflow.com/questions/44869599/readpixels-from-webgl-canvas\\以及这个: 从 WebGL 纹理读取像素
但它们都没有帮助或成功。

目标:使用 WebGL 着色器渲染屏幕外画布,然后将其用作单独的 WebGL 着色器中的纹理。

笔记:

  • 对于这些 WebGL 着色器,我使用了用于像素着色器的通用顶点着色器,特别是光线跟踪器/光线行进器。 这是: attribute vec2 a_position; void main() { gl_Position = vec4(a_position.xy, 0.0, 1.0); } attribute vec2 a_position; void main() { gl_Position = vec4(a_position.xy, 0.0, 1.0); } attribute vec2 a_position; void main() { gl_Position = vec4(a_position.xy, 0.0, 1.0); } . 这个顶点着色器被输入了两个覆盖屏幕的三角形,所以基本上片段着色器完成了所有的工作。

问题:为了从屏幕外画布中获取图像数据,我尝试了以下方法:

  1. WebGL gl.readPixels函数
var capturedImageData = new Float32Array(screenWidth * screenHeight * 4);
gl.readPixels(0, 0, screenWidth, screenHeight, gl.RGBA, gl.FLOAT, capturedImageData);
  1. 将另一个画布与getContext('2d')
var offscreenCanvas = document.createElement("canvas");
offscreenCanvas.width = screenWidth;
offscreenCanvas.height = screenHeight;
var ctx = offscreenCanvas.getContext('2d');
ctx.drawImage(glCanvas, 0, 0);
var capturedImageData = ctx.getImageData(0, 0, screenWidth, screenHeight);

这两种方法都会导致capturedImageData数组被填充
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, . . . ,这显然是不对的。

如果有人对此问题有经验,将不胜感激。 谢谢!

该计划的直接链接是: https : //www.khanacademy.org/cs/-/6289631977619456

您应该始终查看浏览器的 JavaScript 控制台(按 F12)或从菜单中选择它。 我应该为您的代码显示错误

var capturedImageData = new Float32Array(screenWidth * screenHeight * 4);
gl.readPixels(0, 0, screenWidth, screenHeight, gl.RGBA, gl.FLOAT, capturedImageData);

 const gl = document.createElement('canvas').getContext('webgl'); const screenWidth = 300; const screenHeight = 150; var capturedImageData = new Float32Array(screenWidth * screenHeight * 4); gl.readPixels(0, 0, screenWidth, screenHeight, gl.RGBA, gl.FLOAT, capturedImageData);

当我运行您的代码时,出现此错误

js:16 WebGL: INVALID_ENUM: readPixels: invalid type

你不能用FLOAT阅读。 看到这个答案

但是,您尝试做的是渲染到一个纹理并将其用作另一个着色器的输入不应使用 readPixels 来完成。 它应该使用帧缓冲区来完成,允许您直接渲染到纹理。

或也许有这些

出于某种原因,gl.readPixels 与 Uint8Array 搭配使用效果更好。

var capturedImageData = new Uint8Array(screenWidth * screenHeight * 4);
gl.readPixels(0, 0, screenWidth, screenHeight, gl.RGBA, gl.UNSIGNED_BYTE, capturedImageData);

这是一个演示:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />

  </head>
  <canvas></canvas>
  <body>
    <script>
      var gl = document.querySelector("canvas").getContext("webgl");    

    
     gl.clearColor(1, 0, 1, 1);
     gl.clear(gl.COLOR_BUFFER_BIT);
    
    
      var pixels = new Uint8Array(4 * window.innerWidth * window.innerHeight);
      gl.readPixels(0, 0, window.innerWidth, window.innerHeight, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
      
      
      console.log(pixels[0]);
    

  
    </script>
  </body>
</html>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM