Javascript Three.js:纹理到数据纹理

Javascript Three.js:纹理到数据纹理,javascript,html5-canvas,webgl,three.js,Javascript,Html5 Canvas,Webgl,Three.js,我正在尝试用javascript实现一个延迟的网络摄像头查看器,使用Three.js实现WebGL功能 我需要存储从网络摄像头抓取的帧,以便在一段时间后(几毫秒到几秒钟)可以显示它们。使用canvas和getImageData(),我可以在不使用Three.js的情况下完成这项工作。你可以找到 我正试图找到一种不用画布的方法,但使用Three.jsTexture或DataTexture对象。问题是我找不到如何将图像从纹理(图像类型为HTMLVideoElement)复制到另一个 在rotateF

我正在尝试用javascript实现一个延迟的网络摄像头查看器,使用Three.js实现WebGL功能

我需要存储从网络摄像头抓取的帧,以便在一段时间后(几毫秒到几秒钟)可以显示它们。使用
canvas
getImageData()
,我可以在不使用Three.js的情况下完成这项工作。你可以找到

我正试图找到一种不用画布的方法,但使用Three.js
Texture
DataTexture
对象。问题是我找不到如何将图像从
纹理
图像
类型为
HTMLVideoElement
)复制到另一个

rotateFrames()
函数中,旧的帧应该丢失,新的帧应该替换,就像在FIFO中一样。但是这条线

frames[i]。image=frames[i+1]。image;
只是复制引用,而不是纹理数据。我想
DataTexture
应该这样做,但我无法从
Texture
HTMLVideoElement
中获得
DataTexture

有什么想法吗


警告:您必须有一个摄像头,并允许浏览器使用它来运行示例。显然,你必须有一个更新的浏览器。

这就是你想要的吗

编辑:

这是最重要的部分:它复制帧并将其保存为dataTexture中的数据

function rotateFrames() {
    for (var i = 0; i != framesNum - 1; ++i) {
/*
         * FIXME: this does not work!
         */
        frames[i].image.data = frames[i + 1].image.data;
        frames[i].needsUpdate = true;
    }
}
然后将数据从帧中的一个纹理复制到另一个纹理

新版本:http://fiddle.jshell.net/hWL2E/4/

function onFrame(dt) {
    if (video.readyState === video.HAVE_ENOUGH_DATA) { /* new frame available from webcam */
        context.drawImage(video, 0, 0,videoWidth,videoHeight);
         var frame = new THREE.DataTexture(new Uint8Array(context.getImageData(0,0,videoWidth, videoHeight).data.buffer) ,videoWidth,videoHeight);
        frames[framesNum - 1] = frame;
        frames[framesNum - 1].needsUpdate = true;
        sprites[framesNum - 1].map = frames[framesNum - 1];
    }
}
它为视频图像每帧生成一个新纹理

function rotateFrames() {
    for (var i = 0; i != framesNum - 1; ++i) {
/*
         * FIXME: this does not work!
         */
        frames[i] = frames[i + 1];
        sprites[i].map = frames[i];

    }
}

这就是它变得更好的原因。因为它重用了使用过的纹理,这意味着它不需要重新发送到GPU

我不确定我是否理解,但应该有一种方法可以做到这一点,而不必手动复制字节,只需旋转指针。我有一个类似的项目,使用了多个屏幕外画布和内置的drawImage()来转移到屏幕上。这非常快,因为Chrome直接在GPU上完成所有工作。因此,如果你想使用shaders/three.js,我会准备好最终的画布,然后更新纹理。这有意义吗?是的,我在C++中的类似项目中完成了这一点。旋转指针就是方法。但是每一个新帧都需要复制到images history数组(每次都在不同的位置)。如果不复制数据,而只复制指针,则会丢失旧帧,因为每个指针都将指向新帧,这就是我要寻找的。请在回答中解释你在做什么,我会接受答案。调用
frames[i].image.data=frames[i+1].image.datafunction rotateFrames() {
    for (var i = 0; i != framesNum - 1; ++i) {
/*
         * FIXME: this does not work!
         */
        frames[i] = frames[i + 1];
        sprites[i].map = frames[i];

    }
}