Skip to content

Commit

Permalink
Adding RenderBundles and Group.static
Browse files Browse the repository at this point in the history
  • Loading branch information
sunag committed May 23, 2024
1 parent 1a46e3d commit 777d2ee
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 85 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
class RenderBundle {

constructor( scene, camera, name = '' ) {
constructor( scene, camera ) {

this.name = name;
this.scene = scene;
this.camera = camera;

Expand Down
38 changes: 38 additions & 0 deletions examples/jsm/renderers/common/RenderBundles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import ChainMap from './ChainMap.js';
import RenderBundle from './RenderBundle.js';

class RenderBundles {

constructor() {

this.lists = new ChainMap();

}

get( scene, camera ) {

const lists = this.lists;
const keys = [ scene, camera ];

let list = lists.get( keys );

if ( list === undefined ) {

list = new RenderBundle( scene, camera );
lists.set( keys, list );

}

return list;

}

dispose() {

this.lists = new ChainMap();

}

}

export default RenderBundles;
9 changes: 9 additions & 0 deletions examples/jsm/renderers/common/RenderList.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class RenderList {

this.opaque = [];
this.transparent = [];
this.bundles = [];

this.lightsNode = new LightsNode( [] );
this.lightsArray = [];
Expand All @@ -71,6 +72,8 @@ class RenderList {

this.opaque.length = 0;
this.transparent.length = 0;
this.bundles.length = 0;

this.lightsArray.length = 0;

this.occlusionQueryCount = 0;
Expand Down Expand Up @@ -135,6 +138,12 @@ class RenderList {

}

pushBundle( group ) {

this.bundles.push( group );

}

pushLight( light ) {

this.lightsArray.push( light );
Expand Down
131 changes: 73 additions & 58 deletions examples/jsm/renderers/common/Renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import ClippingContext from './ClippingContext.js';
import { Scene, Frustum, Matrix4, Vector2, Vector3, Vector4, DoubleSide, BackSide, FrontSide, SRGBColorSpace, NoColorSpace, NoToneMapping, LinearFilter, LinearSRGBColorSpace, RenderTarget, HalfFloatType, RGBAFormat } from 'three';
import { NodeMaterial } from '../../nodes/Nodes.js';
import QuadMesh from '../../objects/QuadMesh.js';
import RenderBundles from './RenderBundles.js';

const _scene = new Scene();
const _drawingBufferSize = new Vector2();
Expand Down Expand Up @@ -87,6 +88,7 @@ class Renderer {
this._bindings = null;
this._objects = null;
this._pipelines = null;
this._bundles = null;
this._renderLists = null;
this._renderContexts = null;
this._textures = null;
Expand Down Expand Up @@ -172,6 +174,7 @@ class Renderer {
this._bindings = new Bindings( backend, this._nodes, this._textures, this._attributes, this._pipelines, this.info );
this._objects = new RenderObjects( this, this._nodes, this._geometries, this._pipelines, this._bindings, this.info );
this._renderLists = new RenderLists();
this._bundles = new RenderBundles();
this._renderContexts = new RenderContexts();

//
Expand Down Expand Up @@ -327,68 +330,74 @@ class Renderer {

}

_renderBundle( renderBundle ) {
_renderBundle( bundle, sceneRef, lightsNode ) {

const { scene, camera } = renderBundle;
const { object, camera, renderList } = bundle;

const renderBundleData = this.backend.get( renderBundle );
const renderContext = this._currentRenderContext;
const renderContextData = this.backend.get( renderContext );

const renderBundleNeedsUpdate = renderBundleData.renderContexts === undefined || renderBundle.needsUpdate === true;
//

if ( renderBundleNeedsUpdate ) {
const renderBundle = this._bundles.get( object, camera );

renderBundleData.renderContexts = undefined;
const renderBundleData = this.backend.get( renderBundle );
if ( renderBundleData.renderContexts === undefined ) renderBundleData.renderContexts = new Set();

this._currentRenderBundle = renderBundle;
//

this.render( scene, camera );
const renderBundleNeedsUpdate = renderBundleData.renderContexts.has( renderContext ) === false || object.needsUpdate === true;

this._currentRenderBundle = null;
renderBundleData.renderContexts.add( renderContext );

renderBundle.needsUpdate = false;
if ( renderBundleNeedsUpdate ) {

}
if ( renderContextData.renderObjects === undefined || object.needsUpdate === true ) {

const nodeFrame = this._nodes.nodeFrame;

if ( renderBundleData.renderContexts !== undefined ) {
renderContextData.renderObjects = [];
renderContextData.renderBundles = [];
renderContextData.scene = sceneRef;
renderContextData.camera = camera;
renderContextData.renderId = nodeFrame.renderId;

for ( let i = 0; i < renderBundleData.renderContexts.length; i ++ ) {
renderContextData.registerBundlesPhase = true;

const renderContext = renderBundleData.renderContexts[ i ];
const renderContextData = this.backend.get( renderContext );
}

const scene = renderContextData.scene;
const camera = renderContextData.camera;
this._currentRenderBundle = renderBundle;

this._nodes.nodeFrame.renderId = renderContextData.renderId;
//
const opaqueObjects = renderList.opaque;

if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld();
if ( opaqueObjects.length > 0 ) this._renderObjects( opaqueObjects, camera, sceneRef, lightsNode );

if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
this._currentRenderBundle = null;

//

this.backend.beginRender( renderContext );
object.needsUpdate = false;

for ( let i = 0, l = renderContextData.renderObjects.length; i < l; i ++ ) {
} else {

const renderObject = renderContextData.renderObjects[ i ];
const renderContext = this._currentRenderContext;
const renderContextData = this.backend.get( renderContext );

this._nodes.updateBefore( renderObject );
for ( let i = 0, l = renderContextData.renderObjects.length; i < l; i ++ ) {

//
const renderObject = renderContextData.renderObjects[ i ];

renderObject.object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, renderObject.object.matrixWorld );
renderObject.object.normalMatrix.getNormalMatrix( renderObject.object.modelViewMatrix );
this._nodes.updateBefore( renderObject );

this._nodes.updateForRender( renderObject );
this._bindings.updateForRender( renderObject );
//

this.backend.draw( renderObject, this.info );
renderObject.object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, renderObject.object.matrixWorld );
renderObject.object.normalMatrix.getNormalMatrix( renderObject.object.modelViewMatrix );

}
this._nodes.updateForRender( renderObject );
this._bindings.updateForRender( renderObject );

this.backend.finishRender( renderContext );
this.backend.draw( renderObject, this.info );

}

Expand Down Expand Up @@ -526,31 +535,6 @@ class Renderer {

if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();


if ( this._currentRenderBundle !== null ) {

const renderBundleData = this.backend.get( this._currentRenderBundle );

if ( renderBundleData.renderContexts === undefined ) renderBundleData.renderContexts = [];

renderBundleData.renderContexts.push( renderContext );

const renderContextData = this.backend.get( renderContext );

if ( renderContextData.renderObjects === undefined || this._currentRenderBundle.needsUpdate === true ) {

renderContextData.renderObjects = [];
renderContextData.renderBundles = [];
renderContextData.scene = scene;
renderContextData.camera = camera;
renderContextData.renderId = nodeFrame.renderId;

renderContextData.registerBundlesPhase = true;

}

}

//

let viewport = this._viewport;
Expand Down Expand Up @@ -658,8 +642,10 @@ class Renderer {

const opaqueObjects = renderList.opaque;
const transparentObjects = renderList.transparent;
const bundles = renderList.bundles;
const lightsNode = renderList.lightsNode;

if ( bundles.length > 0 ) this._renderBundles( bundles, sceneRef, lightsNode );
if ( opaqueObjects.length > 0 ) this._renderObjects( opaqueObjects, camera, sceneRef, lightsNode );
if ( transparentObjects.length > 0 ) this._renderObjects( transparentObjects, camera, sceneRef, lightsNode );

Expand Down Expand Up @@ -1288,6 +1274,25 @@ class Renderer {

}

if ( object.static === true ) {

const baseRenderList = renderList;

// replace render list
renderList = this._renderLists.get( object, camera );

renderList.begin();

baseRenderList.pushBundle( {
object,
camera,
renderList,
} );

renderList.finish();

}

const children = object.children;

for ( let i = 0, l = children.length; i < l; i ++ ) {
Expand All @@ -1298,6 +1303,16 @@ class Renderer {

}

_renderBundles( bundles, sceneRef, lightsNode ) {

for ( const bundle of bundles ) {

this._renderBundle( bundle, sceneRef, lightsNode );

}

}

_renderObjects( renderList, camera, scene, lightsNode ) {

// process renderable objects
Expand Down
29 changes: 4 additions & 25 deletions examples/webgpu_renderbundle.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,9 @@
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
import RenderBundle from 'three/addons/renderers/RenderBundle.js';
import { MeshToonNodeMaterial } from 'three/nodes';

let camera, scene, renderer, renderBundle;
let camera, scene, renderer;
let controls, stats;
let gui;
let geometries, group;
Expand Down Expand Up @@ -155,6 +154,7 @@
function initRegularMesh( count ) {

group = new THREE.Group();
group.static = api.renderBundle;

for ( let i = 0; i < count; i ++ ) {

Expand Down Expand Up @@ -209,7 +209,6 @@
// scene

scene = new THREE.Scene();

scene.background = new THREE.Color( 0xc1c1c1 );

const light = new THREE.DirectionalLight( 0xffffff, 3.4 );
Expand All @@ -223,14 +222,6 @@
initGeometries();
initMesh( count );


if ( api.renderBundle ) {

renderBundle = new RenderBundle( scene, camera );

}


controls = new OrbitControls( camera, renderer.domElement );
controls.autoRotate = true;
controls.autoRotateSpeed = 1.0;
Expand Down Expand Up @@ -264,9 +255,6 @@

window.addEventListener( 'resize', onWindowResize );




function onWindowResize() {

const width = window.innerWidth;
Expand All @@ -276,27 +264,18 @@
camera.updateProjectionMatrix();

renderer.setSize( width, height );
renderBundle.needsUpdate = true;
group.needsUpdate = true;

}


async function animate() {

animateMeshes();

controls.update();

const renderTimeAverage = performance.now();
if ( api.renderBundle ) {

renderer._renderBundle( renderBundle );

} else {

renderer.render( scene, camera );

}
renderer.render( scene, camera );

// push only the last 60 render times
renderTimeAverages.push( performance.now() - renderTimeAverage );
Expand Down

0 comments on commit 777d2ee

Please sign in to comment.