From ceca2a0fc45ff56a19cafe01921c32732266ad83 Mon Sep 17 00:00:00 2001 From: aardgoose Date: Thu, 18 Aug 2016 20:58:55 +0100 Subject: [PATCH 1/4] use separate render lists for each scene to avoid array resize and RenderItem creation every frame when multiple differently sized scenes are repeatedly rendered with the same renderer. Exhibited by the rtt example. --- src/renderers/WebGLRenderer.js | 56 ++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index dfa454b0b805d6..602e8ae8618c21 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -39,6 +39,19 @@ import { Color } from '../math/Color'; * @author tschw */ +function RenderList () { + + Array.call( this ); + this.liveEntries = 0; + +} + +RenderList.prototype = Object.assign( Object.create( Array.prototype ), { + + constructor: RenderList + +} ); + function WebGLRenderer( parameters ) { console.log( 'THREE.WebGLRenderer', REVISION ); @@ -57,10 +70,8 @@ function WebGLRenderer( parameters ) { var lights = []; - var opaqueObjects = []; - var opaqueObjectsLastIndex = - 1; - var transparentObjects = []; - var transparentObjectsLastIndex = - 1; + var opaqueObjects = null; + var transparentObjects = null; var morphInfluences = new Float32Array( 8 ); @@ -546,10 +557,8 @@ function WebGLRenderer( parameters ) { this.dispose = function() { - transparentObjects = []; - transparentObjectsLastIndex = -1; - opaqueObjects = []; - opaqueObjectsLastIndex = -1; + transparentObjects = null; + opaqueObjects = null; _canvas.removeEventListener( 'webglcontextlost', onContextLost, false ); @@ -1146,8 +1155,25 @@ function WebGLRenderer( parameters ) { lights.length = 0; - opaqueObjectsLastIndex = - 1; - transparentObjectsLastIndex = - 1; + if ( scene._opaqueObjects === undefined ) { + + scene._opaqueObjects = new RenderList(); + + } + + opaqueObjects = scene._opaqueObjects; + + if ( scene._transparentObjects === undefined ) { + + scene._transparentObjects = new RenderList(); + + } + + transparentObjects = scene._transparentObjects; + + + opaqueObjects.liveEntries = 0; + transparentObjects.liveEntries = 0; sprites.length = 0; lensFlares.length = 0; @@ -1157,8 +1183,8 @@ function WebGLRenderer( parameters ) { projectObject( scene, camera ); - opaqueObjects.length = opaqueObjectsLastIndex + 1; - transparentObjects.length = transparentObjectsLastIndex + 1; + opaqueObjects.length = opaqueObjects.liveEntries; + transparentObjects.length = transparentObjects.liveEntries; if ( _this.sortObjects === true ) { @@ -1285,25 +1311,23 @@ function WebGLRenderer( parameters ) { function pushRenderItem( object, geometry, material, z, group ) { - var array, index; + var array; // allocate the next position in the appropriate array if ( material.transparent ) { array = transparentObjects; - index = ++ transparentObjectsLastIndex; } else { array = opaqueObjects; - index = ++ opaqueObjectsLastIndex; } // recycle existing render item or grow the array - var renderItem = array[ index ]; + var renderItem = array[ array.liveEntries ++ ]; if ( renderItem !== undefined ) { From c854a3bc71bde2dc7267d639c4f74711c5edce88 Mon Sep 17 00:00:00 2001 From: aardgoose Date: Fri, 19 Aug 2016 09:38:33 +0100 Subject: [PATCH 2/4] avoid polluting scene objects, attach render lists to WebGLRenderer object --- src/renderers/WebGLRenderer.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 602e8ae8618c21..0c1b0dcd919987 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -73,6 +73,9 @@ function WebGLRenderer( parameters ) { var opaqueObjects = null; var transparentObjects = null; + var opaqueRenderLists = []; + var transparentRenderLists = []; + var morphInfluences = new Float32Array( 8 ); var sprites = []; @@ -557,8 +560,11 @@ function WebGLRenderer( parameters ) { this.dispose = function() { - transparentObjects = null; opaqueObjects = null; + transparentObjects = null; + + opaqueRenderLists = []; + transparentRenderLists = []; _canvas.removeEventListener( 'webglcontextlost', onContextLost, false ); @@ -1155,21 +1161,22 @@ function WebGLRenderer( parameters ) { lights.length = 0; - if ( scene._opaqueObjects === undefined ) { + if ( opaqueRenderLists[ scene.id ] === undefined ) { - scene._opaqueObjects = new RenderList(); + opaqueRenderLists[ scene.id ] = new RenderList(); } - opaqueObjects = scene._opaqueObjects; + opaqueObjects = opaqueRenderLists[ scene.id ]; + - if ( scene._transparentObjects === undefined ) { + if ( transparentRenderLists[ scene.id ] === undefined ) { - scene._transparentObjects = new RenderList(); + transparentRenderLists[ scene.id ] = new RenderList(); } - transparentObjects = scene._transparentObjects; + transparentObjects = transparentRenderLists[ scene.id ]; opaqueObjects.liveEntries = 0; From 109f7ab9256a4dfc28cf47039231b5379dadcf90 Mon Sep 17 00:00:00 2001 From: aardgoose Date: Sun, 21 Aug 2016 16:37:05 +0100 Subject: [PATCH 3/4] revised renderlist to use properties and don't sub class array - it doesnt work, --- src/renderers/WebGLRenderer.js | 47 ++++++++++++---------------------- 1 file changed, 17 insertions(+), 30 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 2398131e6b3bcc..49865b4ab40065 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -39,19 +39,6 @@ import { Color } from '../math/Color'; * @author tschw */ -function RenderList () { - - Array.call( this ); - this.liveEntries = 0; - -} - -RenderList.prototype = Object.assign( Object.create( Array.prototype ), { - - constructor: RenderList - -} ); - function WebGLRenderer( parameters ) { console.log( 'THREE.WebGLRenderer', REVISION ); @@ -73,9 +60,6 @@ function WebGLRenderer( parameters ) { var opaqueObjects = null; var transparentObjects = null; - var opaqueRenderLists = []; - var transparentRenderLists = []; - var morphInfluences = new Float32Array( 8 ); var sprites = []; @@ -563,9 +547,6 @@ function WebGLRenderer( parameters ) { opaqueObjects = null; transparentObjects = null; - opaqueRenderLists = []; - transparentRenderLists = []; - _canvas.removeEventListener( 'webglcontextlost', onContextLost, false ); }; @@ -618,6 +599,16 @@ function WebGLRenderer( parameters ) { } + function onSceneDispose( event ) { + + var scene = event.target; + + scene.removeEventListener( 'dispose', onSceneDispose ); + + properties.delete( scene ); + + } + // Buffer rendering this.renderBufferImmediate = function ( object, program, material ) { @@ -1163,23 +1154,19 @@ function WebGLRenderer( parameters ) { lights.length = 0; - if ( opaqueRenderLists[ scene.id ] === undefined ) { + var sceneProperties = properties.get( scene ); - opaqueRenderLists[ scene.id ] = new RenderList(); - - } - - opaqueObjects = opaqueRenderLists[ scene.id ]; + if ( sceneProperties.opaqueRenderList === undefined ) { + sceneProperties.opaqueRenderList = []; + sceneProperties.transparentRenderList = []; - if ( transparentRenderLists[ scene.id ] === undefined ) { - - transparentRenderLists[ scene.id ] = new RenderList(); + scene.addEventListener( 'dispose', onSceneDispose ); } - transparentObjects = transparentRenderLists[ scene.id ]; - + opaqueObjects = sceneProperties.opaqueRenderList; + transparentObjects = sceneProperties.transparentRenderList; opaqueObjects.liveEntries = 0; transparentObjects.liveEntries = 0; From 19955a4ed4acd0d71032a0db0dc5501da83d38c4 Mon Sep 17 00:00:00 2001 From: aardgoose Date: Fri, 26 Aug 2016 16:33:44 +0100 Subject: [PATCH 4/4] add dispose method the Object3D --- src/core/Object3D.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/core/Object3D.js b/src/core/Object3D.js index 7ef6e276e261e8..d7f52e45e533a3 100644 --- a/src/core/Object3D.js +++ b/src/core/Object3D.js @@ -720,6 +720,12 @@ Object.assign( Object3D.prototype, EventDispatcher.prototype, { return this; + }, + + dispose: function () { + + this.dispatchEvent( { type: 'dispose' } ); + } } );