Javascript HTML画布嗅探Webgl数据

Javascript HTML画布嗅探Webgl数据,javascript,html5-canvas,webgl,pixel-manipulation,webgl2,Javascript,Html5 Canvas,Webgl,Pixel Manipulation,Webgl2,这个问题可能有点奇怪,但假设我们有一个画布,比如画一些像这样的3D内容 不考虑使用ThreeJS、Babylon或任何其他库来实现相同的效果,是否可以设置一些间隔来复制每个体素的诞生,并在以后重复(重画)它 我只想记录画布绘制过程并重放它,而不使用RTC、视频或图像序列 做了什么? 我一直在尝试 和,但不幸的是未能达到预期的结果 有人可以帮忙吗?您可以包装WebGL上下文并捕获所有函数调用。包装WebGL上下文的示例如下 const rawgl=document.querySelector(“

这个问题可能有点奇怪,但假设我们有一个画布,比如画一些像这样的3D内容

不考虑使用ThreeJS、Babylon或任何其他库来实现相同的效果,是否可以设置一些间隔来复制每个体素的诞生,并在以后重复(重画)它

我只想记录画布绘制过程并重放它,而不使用RTC、视频或图像序列

做了什么?

我一直在尝试,但不幸的是未能达到预期的结果


有人可以帮忙吗?

您可以包装WebGL上下文并捕获所有函数调用。包装WebGL上下文的示例如下

const rawgl=document.querySelector(“canvas”).getContext(“webgl”);
常量gl=wrapContext(rawgl);
总图视口(0,0,总图画布宽度,总图画布高度);
总帐启用(总帐剪刀测试);
gl.剪刀(40,50,200,60);
gl.clearColor(0,1,1,1);
总账清除(总账颜色缓冲位);
gl.剪刀(60,40,70,90);
gl.clearColor(1,0,1,1);
总账清除(总账颜色缓冲位);
函数wrapContext(gl){
常量包装器={};
对于(让名称在总账中){
var prop=gl[名称];
if(类型(道具)=“功能”){
包装器[名称]=包装功能(总帐、名称、道具);
}否则{
包装属性(包装、总帐、名称);
}
}
返回包装器;
}
函数包装函数(总帐、名称、原始编号){
//返回一个函数,该函数记录调用,然后调用原始func
返回函数(…args){
日志(`gl.${name}(${[…args].join(“,”});`);
原始应用(总帐,参数);
};
}
函数包装属性(包装、总帐、名称){
//创建一个getter,因为这些值是动态的
Object.defineProperty(包装器、名称、{
可枚举:正确,
get:function(){
返回总账[名称];
},
});
}
函数日志(…args){
const elem=document.createElement(“pre”);
elem.textContent=[…args].join(“”);
文件.正文.附件(elem);
}
canvas{边框:1px纯黑;}
前{margin:0;}

您可以包装WebGL上下文并捕获所有函数调用。包装WebGL上下文的示例如下

const rawgl=document.querySelector(“canvas”).getContext(“webgl”);
常量gl=wrapContext(rawgl);
总图视口(0,0,总图画布宽度,总图画布高度);
总帐启用(总帐剪刀测试);
gl.剪刀(40,50,200,60);
gl.clearColor(0,1,1,1);
总账清除(总账颜色缓冲位);
gl.剪刀(60,40,70,90);
gl.clearColor(1,0,1,1);
总账清除(总账颜色缓冲位);
函数wrapContext(gl){
常量包装器={};
对于(让名称在总账中){
var prop=gl[名称];
if(类型(道具)=“功能”){
包装器[名称]=包装功能(总帐、名称、道具);
}否则{
包装属性(包装、总帐、名称);
}
}
返回包装器;
}
函数包装函数(总帐、名称、原始编号){
//返回一个函数,该函数记录调用,然后调用原始func
返回函数(…args){
日志(`gl.${name}(${[…args].join(“,”});`);
原始应用(总帐,参数);
};
}
函数包装属性(包装、总帐、名称){
//创建一个getter,因为这些值是动态的
Object.defineProperty(包装器、名称、{
可枚举:正确,
get:function(){
返回总账[名称];
},
});
}
函数日志(…args){
const elem=document.createElement(“pre”);
elem.textContent=[…args].join(“”);
文件.正文.附件(elem);
}
canvas{边框:1px纯黑;}
前{margin:0;}

我不知道您是如何尝试使用
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,您可以在
元素中播放它,然后。

我不知道您是如何尝试使用
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,您可以在
元素中播放它,然后。

如何在答案中显示滚动条?您的意思是什么。如果它不适合你,我建议你。否则,任何超过40行的代码块都会自动得到一个滚动条感谢您的帮助@gman,您的回答让我发现了许多我以前没有意识到的东西。@gman capture webgl是您的库吗?如果是这样的话,请你加上一些例子,听起来很有希望。是的,我写的。我主要是以它为例,但当实际使用它时,它会生成很大的文件,因为它必须写出所有的数据(纹理和缓冲区),所以最好是一个例子。有一个有效的例子。它捕获第一帧,然后在示例上方显示生成的HTML。如果你把那个HTML复制粘贴到你得到的另一个文件中。你如何在你的答案中显示一个滚动条?你是什么意思。如果它不适合你,我建议你。否则,任何超过40行的代码块都会自动得到一个滚动条感谢您的帮助@gman,您的回答让我发现了许多我以前没有意识到的东西。@gman capture webgl是您的库吗?如果是这样的话,请你加上一些例子,听起来很有希望。是的,我写的。我主要是以它为例,但当实际使用它时,它会生成很大的文件,因为它必须写出所有的数据(纹理和缓冲区),所以最好是一个例子。有一个有效的例子。它捕获第一帧,然后在示例上方显示生成的HTML。如果您将HTML复制并粘贴到另一个文件中,您是如何尝试流捕获的?它在给定的环境中对我很有效。在控制台中复制此命令:
让s=mycanvas.captureStream(),r=new-MediaRecorder,chunks=[];r、 ondataavailable=e=>chunks.push(e.data);r、 onstop=e=>{window.open(URL.createObjectURL(新Blob(chunks));};r、 start();setTimeout(=>r.stop