non vorrei lavorare

ブログ名の通りです。javascript three.js mruby rust OCaml golang julialang blender

オフスクリーンでWebGLを描画して、それをCanvasにコピーする

この記事は@kjunichiの2017年パーソナルアドベントカレンダーの17日目の記事です 。

背景

WindowsでElectronで透明ウインドウを使ってWebGLを使うと、頻繁に異常に動きが遅くなる。 そこで、直接WebGLを描画せず、オフスクリーンで描画して、Canvasに転送すれば、解消しないかと 思いつきやってみた

WebGLの描画結果をCanvasにコピーする

以下のようにwebglのコンテキストをreadPixelsで描画結果を読み出すことだ出来、 それをImageDataに書き込むことでCanvasにコピー出来た。 どうやら、WebGLnバッファとCanvasのImageDataは上下が逆の模様。

      const sctx = renderer.domElement.getContext("webgl");
      const pdata =  new Uint8Array(4*cs3.width*cs3.height);
      sctx.readPixels(0,0,sctx.drawingBufferWidth,sctx.drawingBufferHeight,sctx.RGBA,sctx.UNSIGNED_BYTE,pdata);
      const dctx = cs3.getContext("2d");
      const image = dctx.getImageData(0,0,sctx.drawingBufferWidth,sctx.drawingBufferHeight);
      for(let y=0;y < sctx.drawingBufferHeight;y++){
        for(let x=0; x < sctx.drawingBufferWidth;x++) {
          image.data[4*((cs3.height-y)*cs3.width+x)+0] = pdata[4*(y*cs3.width+x)+0];
          image.data[4*((cs3.height-y)*cs3.width+x)+1] = pdata[4*(y*cs3.width+x)+1];
          image.data[4*((cs3.height-y)*cs3.width+x)+2] = pdata[4*(y*cs3.width+x)+2];
          image.data[4*((cs3.height-y)*cs3.width+x)+3] = pdata[4*(y*cs3.width+x)+3];
        }
      }
      dctx.putImageData(image,0,0);

改善したか

余計遅くなってしまったw