【问题标题】:How can I get the pixel data of a scene without actually rendering it on the canvas in Three.js?如何在 Three.js 的画布上不实际渲染场景的情况下获取场景的像素数据?
【发布时间】:2023-04-08 06:08:02
【问题描述】:

我想知道如果我要正常渲染场景,但实际上不做在画布上渲染它们。如果有,怎么做?

我真的没有任何代码来做这样的事情,因为我不知道它是否可能。 (而且我对 Three.js 还是很陌生)

【问题讨论】:

    标签: javascript three.js


    【解决方案1】:

    几乎是的:您可以将场景渲染为THREE.WebGLRenderTarget 并使用renderer.readRenderTargetPixels() 访问渲染数据。我知道的唯一区别是它没有抗锯齿。

    所以是这样的:

    const rt = new THREE.WebGLRenderTarget(rendererWidth, rendererHeight);
    renderer.render(scene, camera, rt);
    
    // w/h: width/height of the region to read
    // x/y: bottom-left corner of that region
    const buffer = new Uint8Array(w * h * 4);
    renderer.readRenderTargetPixels(rt, x, y, w, h, buffer);
    

    现在,如果您只想渲染您感兴趣的屏幕的一小部分,您可以使用scissor-testing

    renderer.setScissor(x, y, w, h);
    renderer.setScissorTest(true);
    
    renderer.render(scene, camera, rt);
    
    renderer.setScissor(0, 0, rendererWidth, rendererHeight);
    renderer.setScissorTest(false);
    

    【讨论】:

    • 我注意到的一点是,如果你想使用context.putImageData(outputBuffer, 0, 0),你需要一个Uint8ClampedArray,但readRenderTargetPixels 只接受Uint8Array 作为它的目标。将Uint8Array 转换为带有全屏帧缓冲区(带有Uint8ClampedArray.from(buffer))的Uint8ClampedArray 需要500 毫秒。对此有何想法?
    • hm,您不需要转换,因为底层数据格式是相同的。尝试new Uint8ClampedArray(uint8Array.buffer) 创建一个新的固定数组,共享底层数组缓冲区。
    • 哦,你是对的。我明白了,from 只是为了复制。
    • 延迟也可能来自于这是一个同步函数。不过,这对我来说仍然有点模糊。您必须等待渲染完成,而那里发生的事情可能会减慢速度。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-27
    • 2020-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多