javascript - Is it possible to enable unbounded number of renderers in THREE.js? -


in order avoid xy problem, let me explain i'm coming from. plot large number of waveforms stacked on top of each other using same time axis, using three.js. waveforms three.line's , implementing zoom/pan/scaling of these waveforms modifying view bounds of orthographic camera.

my initial attempt @ accomplishing lead me create multiple canvas elements fixed height, stacked on top of each other, , attach three.webglrenderer each canvas. worked perfectly, until tried scaling past 15 or waveforms, three.js gave me warning "too many active webgl contexts", , started deleting old contexts.

i feel decent practice, considering it's same technique applied here: http://threejs.org/examples/#webgl_multiple_canvases_grid

in example, 4 webglrenderers created, 1 each canvas.

so, possible override warning somehow, , create unbounded number of canvas elements, each own renderer?

aside:

i have considered using 1 scene , positioning waveforms accordingly within it, , using multiple cameras approach similar http://threejs.org/examples/#webgl_multiple_views.

the problems two-fold:

(1) lose ability dom-manipulate , attach key , mouse listeners on per-waveform basis.

(2) solution doesn't seem scale either. once renderer's height passes somewhere around 6000px height, starts enter type of corrupt state , part of scene doesn't appear, rest of content appearing stretched compensate.

thanks can help!

you can use 1 non-scrolling full window size canvas, , place holders divs wave forms. 1 renderer have 1 scene per waveform , call renderer.setviewport , renderer.setscissor location of each div before rendering each scene.

effectively this

renderer.enablescissortest( true ); scenes.foreach( function( scene ) {    // element place holder want   // draw scene   var viewelement = scene.viewelement;    // position relative page's viewport   var rect = viewelement.getboundingclientrect();    // check if it's offscreen. if skip   if ( rect.bottom < 0 || rect.top  > renderer.domelement.clientheight ||      rect.right  < 0 || rect.left > renderer.domelement.clientwidth ) {     return;  // it's off screen   }    // set viewport   var width  = rect.right - rect.left;   var height = rect.bottom - rect.top;   var left   = rect.left;   var bottom = renderer.domelement.clientheight - rect.bottom - 1;    camera.aspect = width / height;   camera.updateprojectionmatrix();   renderer.setviewport( left, bottom, width, height );   renderer.setscissor( left, bottom, width, height );   renderer.render( scene, camera ); } ); renderer.enablescissortest( false ); 

example:

var canvas;    var scenes = [], camera, renderer, emptyscene;    init();  animate();    function init() {      canvas = document.getelementbyid( "c" );      camera = new three.perspectivecamera( 75, 1, 0.1, 100 );    camera.position.z = 1.5;      var geometries = [      new three.boxgeometry( 1, 1, 1 ),      new three.spheregeometry( 0.5, 12, 12 ),      new three.dodecahedrongeometry( 0.5 ),      new three.cylindergeometry( 0.5, 0.5, 1, 12 ),    ];      var template = document.getelementbyid("template").text;    var content = document.getelementbyid("content");      var emptyscene = new three.scene();      var numscenes = 100;      ( var ii =  0; ii < numscenes; ++ii ) {        var scene = new three.scene();        // make list item.      var element = document.createelement( "div" );      element.innerhtml = template;      element.classname = "list-item";        // element represents area      // want render scene      scene.element = element.queryselector(".scene");      content.appendchild(element);        // add 1 random mesh each scene      var geometry = geometries[ geometries.length * math.random() | 0 ];      var material = new three.meshlambertmaterial( { color: randcolor() } );        scene.add( new three.mesh( geometry, material ) );        light = new three.directionallight( 0xffffff );      light.position.set( 0.5, 0.8, 1 );      scene.add( light );        light = new three.directionallight( 0xffffff );      light.position.set( -0.5, -0.8, -1 );      scene.add( light );        scenes.push( scene );    }        renderer = new three.webglrenderer( { canvas: canvas, antialias: true } );    renderer.setclearcolor( 0xffffff );    }    function updatesize() {      var width = canvas.clientwidth;    var height = canvas.clientheight;      if ( canvas.width !== width || canvas.height != height ) {        renderer.setsize ( width, height, false );      }    }    function animate() {      render();      requestanimationframe( animate );  }    function render() {      updatesize();      renderer.setclearcolor( 0xffffff );    renderer.clear( true );    renderer.setclearcolor( 0xe0e0e0 );      renderer.enablescissortest( true );    scenes.foreach( function( scene ) {      // moves      scene.children[0].rotation.x = date.now() * 0.00111;      scene.children[0].rotation.z = date.now() * 0.001;        // element place holder want      // draw scene      var element = scene.element;        // position relative page's viewport      var rect = element.getboundingclientrect();        // check if it's offscreen. if skip      if ( rect.bottom < 0 || rect.top  > renderer.domelement.clientheight ||         rect.right  < 0 || rect.left > renderer.domelement.clientwidth ) {        return;  // it's off screen      }        // set viewport      var width  = rect.right - rect.left;      var height = rect.bottom - rect.top;      var left   = rect.left;      var bottom = renderer.domelement.clientheight - rect.bottom;        camera.aspect = width / height;      camera.updateprojectionmatrix();      renderer.setviewport( left, bottom, width, height );      renderer.setscissor( left, bottom, width, height );      renderer.render( scene, camera );      } );    renderer.enablescissortest( false );    }    function rand( min, max ) {    if ( max == undefined ) {      max = min;      min = 0;    }      return math.random() * ( max - min ) + min;  }    function randcolor() {    var colors = [ rand( 256 ), rand ( 256 ), rand( 256 ) ];    colors[ math.random() * 3 | 0 ] = 255;    return ( colors[0] << 16 ) |         ( colors[1] <<  8 ) |         ( colors[2] <<  0 ) ;  }
* {    box-sizing: border-box;    -moz-box-sizing: border-box;  }    body {    color: #000;    font-family:monospace;    font-size:13px;      background-color: #fff;    margin: 0px;  }      #content {    position: absolute;    top: 0px; width: 100%;    z-index: 1;    padding: 2em;  }    #c {    position: fixed;    left: 0px;    width: 100%;    height: 100%;  }    .list-item {    margin: 1em;    padding: 2em;    display: -webkit-flex;    display: flex;    flex-direction: row;    -webkit-flex-direction: row;  }    .list-item .scene {    width: 200px;    height: 200px;    flex: 0 0 auto;    -webkit-flex: 0 0 auto;  }  .list-item .description {    font-family: sans-serif;    font-size: large;    padding-left: 2em;    flex: 1 1 auto;    -webkit-flex: 1 1 auto;  }    @media screen , (max-width : 600px) {    #content {      width: 100%;    }    .list-item {      margin: 0.5em;      padding: 0.5em;      flex-direction: column;      -webkit-flex-direction: column;    }    .list-item .description {      padding-left: 0em;    }  }
<canvas id="c"></canvas>  <div id="content">  </div>  <script id="template" type="notjs">  			<div class="scene"></div>  			<div class="description">some random text object, scene, whatever</div>  </script>  <script src="//cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.min.js"></script>


Comments

Popular posts from this blog

python - TypeError: start must be a integer -

c# - DevExpress RepositoryItemComboBox BackColor property ignored -

django - Creating multiple model instances in DRF3 -