|
@@ -101,9 +101,13 @@ class Renderer {
|
|
this._renderObjectFunction = null;
|
|
this._renderObjectFunction = null;
|
|
this._currentRenderObjectFunction = null;
|
|
this._currentRenderObjectFunction = null;
|
|
|
|
|
|
|
|
+ this._handleObjectFunction = this._renderObjectDirect;
|
|
|
|
+
|
|
this._initialized = false;
|
|
this._initialized = false;
|
|
this._initPromise = null;
|
|
this._initPromise = null;
|
|
|
|
|
|
|
|
+ this._compilationPromises = null;
|
|
|
|
+
|
|
// backwards compatibility
|
|
// backwards compatibility
|
|
|
|
|
|
this.shadowMap = {
|
|
this.shadowMap = {
|
|
@@ -176,9 +180,125 @@ class Renderer {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- async compile( /*scene, camera*/ ) {
|
|
|
|
|
|
+ async compileAsync( scene, camera, targetScene = null ) {
|
|
|
|
+
|
|
|
|
+ if ( this._initialized === false ) await this.init();
|
|
|
|
+
|
|
|
|
+ // preserve render tree
|
|
|
|
+
|
|
|
|
+ const nodeFrame = this._nodes.nodeFrame;
|
|
|
|
+
|
|
|
|
+ const previousRenderId = nodeFrame.renderId;
|
|
|
|
+ const previousRenderContext = this._currentRenderContext;
|
|
|
|
+ const previousRenderObjectFunction = this._currentRenderObjectFunction;
|
|
|
|
+ const previousCompilationPromises = this._compilationPromises;
|
|
|
|
+
|
|
|
|
+ //
|
|
|
|
+
|
|
|
|
+ const sceneRef = ( scene.isScene === true ) ? scene : _scene;
|
|
|
|
+
|
|
|
|
+ if ( targetScene === null ) targetScene = scene;
|
|
|
|
+
|
|
|
|
+ const renderTarget = this._renderTarget;
|
|
|
|
+ const renderContext = this._renderContexts.get( targetScene, camera, renderTarget );
|
|
|
|
+ const activeMipmapLevel = this._activeMipmapLevel;
|
|
|
|
+
|
|
|
|
+ const compilationPromises = [];
|
|
|
|
+
|
|
|
|
+ this._currentRenderContext = renderContext;
|
|
|
|
+ this._currentRenderObjectFunction = this.renderObject;
|
|
|
|
+
|
|
|
|
+ this._handleObjectFunction = this._createObjectPipeline;
|
|
|
|
+
|
|
|
|
+ this._compilationPromises = compilationPromises;
|
|
|
|
+
|
|
|
|
+ nodeFrame.renderId ++;
|
|
|
|
+
|
|
|
|
+ //
|
|
|
|
+
|
|
|
|
+ nodeFrame.update();
|
|
|
|
|
|
- console.warn( 'THREE.Renderer: .compile() is not implemented yet.' );
|
|
|
|
|
|
+ //
|
|
|
|
+
|
|
|
|
+ renderContext.depth = this.depth;
|
|
|
|
+ renderContext.stencil = this.stencil;
|
|
|
|
+
|
|
|
|
+ //
|
|
|
|
+
|
|
|
|
+ sceneRef.onBeforeRender( this, scene, camera, renderTarget );
|
|
|
|
+
|
|
|
|
+ //
|
|
|
|
+
|
|
|
|
+ const renderList = this._renderLists.get( scene, camera );
|
|
|
|
+ renderList.begin();
|
|
|
|
+
|
|
|
|
+ this._projectObject( scene, camera, 0, renderList );
|
|
|
|
+
|
|
|
|
+ // include lights from target scene
|
|
|
|
+ if ( targetScene !== scene ) {
|
|
|
|
+
|
|
|
|
+ targetScene.traverseVisible( function ( object ) {
|
|
|
|
+
|
|
|
|
+ if ( object.isLight && object.layers.test( camera.layers ) ) {
|
|
|
|
+
|
|
|
|
+ renderList.pushLight( object );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ } );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ renderList.finish();
|
|
|
|
+
|
|
|
|
+ //
|
|
|
|
+
|
|
|
|
+ if ( renderTarget !== null ) {
|
|
|
|
+
|
|
|
|
+ this._textures.updateRenderTarget( renderTarget, activeMipmapLevel );
|
|
|
|
+
|
|
|
|
+ const renderTargetData = this._textures.get( renderTarget );
|
|
|
|
+
|
|
|
|
+ renderContext.textures = renderTargetData.textures;
|
|
|
|
+ renderContext.depthTexture = renderTargetData.depthTexture;
|
|
|
|
+
|
|
|
|
+ } else {
|
|
|
|
+
|
|
|
|
+ renderContext.textures = null;
|
|
|
|
+ renderContext.depthTexture = null;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //
|
|
|
|
+
|
|
|
|
+ this._nodes.updateScene( sceneRef );
|
|
|
|
+
|
|
|
|
+ //
|
|
|
|
+
|
|
|
|
+ this._background.update( sceneRef, renderList, renderContext );
|
|
|
|
+
|
|
|
|
+ // process render lists
|
|
|
|
+
|
|
|
|
+ const opaqueObjects = renderList.opaque;
|
|
|
|
+ const transparentObjects = renderList.transparent;
|
|
|
|
+ const lightsNode = renderList.lightsNode;
|
|
|
|
+
|
|
|
|
+ if ( opaqueObjects.length > 0 ) this._renderObjects( opaqueObjects, camera, sceneRef, lightsNode );
|
|
|
|
+ if ( transparentObjects.length > 0 ) this._renderObjects( transparentObjects, camera, sceneRef, lightsNode );
|
|
|
|
+
|
|
|
|
+ // restore render tree
|
|
|
|
+
|
|
|
|
+ nodeFrame.renderId = previousRenderId;
|
|
|
|
+
|
|
|
|
+ this._currentRenderContext = previousRenderContext;
|
|
|
|
+ this._currentRenderObjectFunction = previousRenderObjectFunction;
|
|
|
|
+ this._compilationPromises = previousCompilationPromises;
|
|
|
|
+
|
|
|
|
+ this._handleObjectFunction = this._renderObjectDirect;
|
|
|
|
+
|
|
|
|
+ // wait for all promises setup by backends awaiting compilation/linking/pipeline creation to complete
|
|
|
|
+
|
|
|
|
+ await Promise.all( compilationPromises );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -995,16 +1115,16 @@ class Renderer {
|
|
if ( material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false ) {
|
|
if ( material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false ) {
|
|
|
|
|
|
material.side = BackSide;
|
|
material.side = BackSide;
|
|
- this._renderObjectDirect( object, material, scene, camera, lightsNode, 'backSide' ); // create backSide pass id
|
|
|
|
|
|
+ this._handleObjectFunction( object, material, scene, camera, lightsNode, 'backSide' ); // create backSide pass id
|
|
|
|
|
|
material.side = FrontSide;
|
|
material.side = FrontSide;
|
|
- this._renderObjectDirect( object, material, scene, camera, lightsNode ); // use default pass id
|
|
|
|
|
|
+ this._handleObjectFunction( object, material, scene, camera, lightsNode ); // use default pass id
|
|
|
|
|
|
material.side = DoubleSide;
|
|
material.side = DoubleSide;
|
|
|
|
|
|
} else {
|
|
} else {
|
|
|
|
|
|
- this._renderObjectDirect( object, material, scene, camera, lightsNode );
|
|
|
|
|
|
+ this._handleObjectFunction( object, material, scene, camera, lightsNode );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1048,10 +1168,28 @@ class Renderer {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ _createObjectPipeline( object, material, scene, camera, lightsNode, passId ) {
|
|
|
|
+
|
|
|
|
+ const renderObject = this._objects.get( object, material, scene, camera, lightsNode, this._currentRenderContext, passId );
|
|
|
|
+
|
|
|
|
+ //
|
|
|
|
+
|
|
|
|
+ this._nodes.updateBefore( renderObject );
|
|
|
|
+
|
|
|
|
+ //
|
|
|
|
+
|
|
|
|
+ this._nodes.updateForRender( renderObject );
|
|
|
|
+ this._geometries.updateForRender( renderObject );
|
|
|
|
+ this._bindings.updateForRender( renderObject );
|
|
|
|
+
|
|
|
|
+ this._pipelines.getForRender( renderObject, this._compilationPromises );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
|
|
get compute() {
|
|
get compute() {
|
|
|
|
|
|
- return this.computeAsync;
|
|
|
|
|
|
+ console.warn( 'THREE.Renderer: compile() is deprecated and will be removed in r170, use compileAsync instead.' ); // @deprecated, r170
|
|
|
|
+ return this.compileAsync;
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|