2017-01-19 5 views
0

この質問は奇妙かもしれませんが、例えばexperimentのような3Dコンテンツを描画するキャンバスがあるとします。HTMLキャンバススニッフWebglデータ

同じ効果を得るためにThreeJS、Babylonまたは他のライブラリを使用しないで、すべてのボクセルの誕生をコピーして後でそれを繰り返す(再描画する)間隔を設定することは可能ですか?

RTC、ビデオ、または画像シーケンスを使用せずにキャンバス描画プロセスを記録して再生したいだけです。

何が完了しましたか?

私はWebGl ContextStream Captureにしようとしているが、残念ながら所望の結果を達成することができませんでした。

誰でも助けてもらえますか?

+1

どのようにストリームキャプチャを試しましたか?それは与えられた[例のリンク](http://www.laplace2be.com/lab/PixelParticles/)で私のためにうまくいきます。これをコンソールにコピーします: 'let s = mycanvas.captureStream()、r = new MediaRecorder(s) chunks = []; r.ondataavailable = e => chunks.push(e.data); r.onstop = e => { window.open(URL.createObjectURL(new Blob(chunks))); }; r.start(); setTimeout(_ => r.stop()、3000); ' – Kaiido

+0

@Kaiidoはあなたのコメントに感謝します。私はそれを行いましたが、このブロブは実際に私の場合は実際に最適な解決策ではないwebmビデオです。サイズは大きくなります。これを答えに加えてください。 – ProllyGeek

答えて

1

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-Inspectorはこれを行い、フレームを再生することができますので、良い例かもしれません。このwebgl-captureライブラリもあります。

あなたのプログラムのためにキャプチャする必要があるのはあなたのプログラムです。例えば、バッファやテクスチャが決して変化しないことがわかっていて、再生したいときにそれらがまだメモリに残っている場合は、上記の両方の例で必要なバッファとテクスチャの状態をキャプチャしようとする必要はありません。

+0

答えにスクロールバーを表示させるにはどうすればよいですか? – J3STER

+0

どういう意味ですか? [それは私のためにスクロールする](http://imgur.com/a/qkhY1)。それがあなたのためにスクロールしていないなら、私はあなたに[バグを報告する]ことを勧めます(http://meta.stackoverflow.com)。さもなければ、40行以上のコードブロックが自動的にスクロールバーを取得します – gman

+0

あなたの助けてくれてありがとう@gman、あなたの答えは私が前に気付かなかったものをたくさん発見しました。 – ProllyGeek

1

私はあなたが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>要素でそれを再生することができ、その後、draw it in your webgl context