Display various scenes sharing resources on multiple canvases

I use three.js to create an interactive web application, and I came across a little stumbling block:

I have several canvases contained in draggable divs on the page. In each canvas, I hope to display an unlit 3D object using a different material (each material uses custom shaders). All these materials work with the same texture (one may be blue toner, may be unsaturated, etc.).

The amount of canvas on the page can vary, but I expect that the number will usually reach / exceed 20 canvases, and since such sharing resources (especially for large textures) will be very useful.

So far, I have used several renderings, cameras, and scenes that worked fine until I started using the same texture in multiple scenes.

Most materials use uniforms and attributes to avoid duplication of information, and also to keep all materials in sync with each other (for example, when some of the materials change over time, they should all change in the same way).

I was wondering if there is a way to share textures between scenes / renderings / canvases? When I try, I get the following error:

WebGL: INVALID_OPERATION: bindTexture: object not from this context 

In my research, trying to find a solution to this problem, I came across the assumption that this can be solved by creating several viewports, but I don’t know how to display different viewports on different canvases.

TL/DR;

Is it possible:

  • Show the same scene on different canvases?
  • ( ) , / ?

!

Griffork

+3
1

, () .

  • .

    : http://webglsamples.org/multiple-views/multiple-views.html

  • , , , , , getClientBoundingRect, scissor

    : THREE.js?

  • , .

    <canvas id="c1"></canvas>
    <canvas id="c2"></canvas>
    <script>
    var webglCanvas = document.createElement("canvas");
    var canvas1 = document.getElementById("c1");
    var ctx1 = canvas1.getContext("2d");
    var canvas2 = document.getElementById("c1");
    var ctx2 = canvas1.getContext("2d");
    

    ... webglCanvas ...

    // copy scene to canvas1
    ctx1.drawImage(webglCanvas, 0, 0);
    

    ... webglCanvas ...

    // copy scene to canvas2
    ctx2.drawImage(webglCanvas, 0, 0);
    

    ( : Windows Chrome26, FF20, , )

  • OffscreenCanvas, transferToImageBitmap .. (: ​​ 2018/1/8, Firefox)

const one = document.getElementById("one").getContext("bitmaprenderer"); 
const two = document.getElementById("two").getContext("bitmaprenderer");

const offscreen = new OffscreenCanvas(256, 256);
constr gl = offscreen.getContext('webgl');

// ... some drawing for the first canvas using the gl context ...
gl.clearColor(1,0,0,1);
gl.clear(gl.COLOR_BUFFER_BIT);

// Commit rendering to the first canvas
let bitmapOne = offscreen.transferToImageBitmap();
one.transferImageBitmap(bitmapOne);

// ... some more drawing for the second canvas using the gl context ...
gl.clearColor(0,1,0,1);
gl.clear(gl.COLOR_BUFFER_BIT);

// Commit rendering to the second canvas 
let bitmapTwo = offscreen.transferToImageBitmap();
two.transferImageBitmap(bitmapTwo);
<canvas id="one"></canvas>
<canvas id="two"></canvas>
Hide result
+7

Source: https://habr.com/ru/post/1537427/


All Articles