【问题标题】:THREE.js read pixels from GPUComputationRenderer textureTHREE.js 从 GPUComputationRenderer 纹理中读取像素
【发布时间】:2017-02-05 18:24:03
【问题描述】:

我一直在使用this three.js example 的修改版本上的 GPUComputationRenderer,它使用 GPU 着色器修改交互 boid 的速度,以保存、读取和操作 boid 位置和速度数据。

我已经到了可以使用着色器将 GPU 计算数据(预测的碰撞时间)放入纹理缓冲区的阶段。但现在我想在主要的 javascript 动画脚本中读取一些纹理数据(以找到最早的碰撞)。

这是渲染函数中的相关代码(在每个动画过程中调用)

//... GPU calculations as per original THREE.js example
gpuCompute.compute();   //... gpuCompute is the gpu computation renderer.           
birdUniforms.texturePosition.value = gpuCompute.getCurrentRenderTarget( positionVariable ).texture;
birdUniforms.textureVelocity.value = gpuCompute.getCurrentRenderTarget( velocityVariable ).texture;

var xTexture = birdUniforms.texturePosition.value;//... my variable, OK.

//... From http://zhangwenli.com/blog/2015/06/20/read-from-shader-texture-with-threejs/
//... but note that this reads from the main THREE.js renderer NOT from the gpuCompute renderer.
//var pixelBuffer = new Uint8Array(canvas.width * canvas.height * 4);               
//var gl = renderer.getContext();
//gl.readPixels(0, 0, canvas.width, canvas.height, gl.RGBA, gl.UNSIGNED_BYTE, pixelBuffer);

var pixelBuffer = new Uint8Array( WIDTH * WIDTH * 4);   //... OK.

//var gl = gpuCompute.getContext();//... no getContext function!!!

//... from Nick Whaley here: http://stackoverflow.com/questions/13475209/three-js-get-data-from-three-webglrendertarget
//WebGLRenderer.readRenderTargetPixels ( renderTarget, x, y, width, height, buffer )

gpuCompute.readRenderTargetPixels ( xTexture, 0, 0, WIDTH, WIDTH, pixelBuffer ); //... readRenderTargetPixels is not a function!

如代码所示,我“想要”gpuCompute 渲染器对象以提供诸如 .getContext()readRenderTargetPixels() 之类的函数,但 gpuCompute 不存在这些函数。


编辑:

然后我尝试添加以下代码:-

//... the WebGLRenderer code is included in THREE.js build
myWebglRenderer = new THREE.WebGLRenderer();                            
var myRenderTarget = gpuCompute.getCurrentRenderTarget( positionVariable );             
myWebglRenderer.readRenderTargetPixels ( 
        myRenderTarget,  0, 0, WIDTH, WIDTH, pixelBuffer );

这执行正常,但 pixelBuffer 仍然完全充满零,而不是所需的位置坐标值。


请任何人建议我如何将纹理数据读入像素缓冲区? (最好在 THREE.js/plain javascript 中,因为我不了解 WebGL)。

【问题讨论】:

  • 这将难以接受,但是......您无法在 OpenGL 中将常规纹理像素读回系统内存,只能从 FrameBuffer 对象 (FBO) 或 RenderBuffer 中读取。要实现这一点,您必须使用其他东西然后 THREE.WebGLRenderTarget 作为渲染目标。在那种情况下我不知道three.js中的什么对你有帮助,但你肯定需要修改gpuCompute代码。
  • @VallyN 感谢您的解释和建议。修补gpuCompute 超出了我目前的技能。

标签: javascript three.js webgl shader


【解决方案1】:

此答案已过时。见底部链接

简短的回答是这并不容易。在 WebGL 1.0 中,没有简单的方法可以从 GPUComputationRenderer 使用的浮点纹理中读取像素。

如果您真的想读回数据,您需要将 GPUComputationRenderer 浮点纹理渲染为 8 位 RGBA 纹理,执行从 32 位浮点到 8 位纹理的某种编码。然后,您可以在 JavaScript 中读回它并查看值。

WebGL Read pixels from floating point render target

【讨论】:

  • 非常感谢您的指导和链接。我的 WebGL 不存在,因此我可能需要很长时间才能进一步深入研究。
  • 我是 GPUComputationRenderer 的合著者。现在水模拟示例包括读取纹理数据作为浮点数(用于模拟表面上的网球)
  • @yombo 我在 Chrome 性能选项卡中看到,WebGL API 似乎阻塞了渲染,在 readPixelscheckFramebufferStatus 下花费的大部分时间之间交替。我想这就是这些 API 的缺点,配置文件显示这个没关系?我正在处理的事情中遇到了同样的行为,我希望你对浏览器中的实现有更多的了解。性能似乎并没有受到太大的负面影响,我很感兴趣的是 GPU 似乎正在“在”那些 GL 调用下进行渲染工作。
猜你喜欢
  • 2012-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多