这个问题可能很奇怪,但假设我们有一个画布,例如绘制一些3D内容,就像这个实验一样。
不考虑使用ThreeJS、Babylon或任何其他库来实现相同的效果,是否可以设置一些间隔来复制每个体素的出生,并在以后重复(重新绘制)它。
简单地说,我想记录画布绘制过程并回放它,而不使用RTC、视频或图像序列。
做了什么
我一直在尝试使用WebGl-Context和流捕获,但遗憾的是无法达到预期的结果。
有人能帮忙吗?
您可以包装WebGL上下文并捕获所有函数调用。包装WebGL上下文的一个例子是类似的内容
const rawgl = document.querySelector("canvas").getContext("webgl");
const gl = wrapContext(rawgl);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.enable(gl.SCISSOR_TEST);
gl.scissor(40, 50, 200, 60);
gl.clearColor(0,1,1,1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.scissor(60, 40, 70, 90);
gl.clearColor(1,0,1,1);
gl.clear(gl.COLOR_BUFFER_BIT);
function wrapContext(gl) {
const wrapper = {};
for (let name in gl) {
var prop = gl[name];
if (typeof(prop) === 'function') {
wrapper[name] = wrapFunction(gl, name, prop);
} else {
wrapProperty(wrapper, gl, name);
}
}
return wrapper;
}
function wrapFunction(gl, name, origFn) {
// return a function that logs the call and then calls the original func
return function(...args) {
log(`gl.${name}(${[...args].join(", ")});`);
origFn.apply(gl, arguments);
};
}
function wrapProperty(wrapper, gl, name) {
// make a getter because these values are dynamic
Object.defineProperty(wrapper, name, {
enumerable: true,
get: function() {
return gl[name];
},
});
}
function log(...args) {
const elem = document.createElement("pre");
elem.textContent = [...args].join(" ");
document.body.appendChild(elem);
}
canvas { border: 1px solid black; }
pre { margin: 0; }
<canvas></canvas>
在您的情况下,您不需要记录调用,而是将它们添加到仅针对您想要捕获的帧的某个调用数组中。
然后,您需要以某种方式跟踪所有资源(缓冲区、纹理帧缓冲区、渲染缓冲区、着色器、程序)及其所有参数(如纹理上的过滤设置),还需要跟踪统一设置等。
WebGL检查器可以做到这一点,并且可以播放帧,因此它可能是一个很好的例子。还有这个webgl捕获库。
你需要为你的程序捕获什么取决于你的程序。例如,如果你知道你的缓冲区和纹理永远不会改变,并且当你想播放时它们仍然在内存中,那么也许你不需要像上面的两个例子一样尝试捕捉缓冲区和质地的状态。
我不知道你是如何尝试captureStream
方法的,但在你的示例页面上,这段代码确实有效。
let s = mycanvas.captureStream(),
r = new MediaRecorder(s),
chunks = [];
r.ondataavailable = e => chunks.push(e.data);
r.onstop = e => {
let videoURL = URL.createObjectURL(new Blob(chunks));
doSomethingWith(videoURL);
};
r.start();
setTimeout(_=>r.stop(), 3000); // records 3 seconds
现在您已经有了一个指向画布记录的有效blobURL,您可以在<video>
元素中播放它,然后在webgl上下文中绘制它。