Skip to content

Commit

Permalink
Rebase, changed method name and signature
Browse files Browse the repository at this point in the history
  • Loading branch information
toji committed Dec 15, 2021
1 parent 0ee07fd commit 009bf20
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 80 deletions.
6 changes: 5 additions & 1 deletion examples/webgl_loader_gltf.html
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,11 @@

roughnessMipmapper.dispose();

renderer.compileTarget( scene, gltf.scene, function() {
// Calling compileAsync returns a promise that resolves when gltf.scene can be added
// to scene without unnecessary stalling on shader compiation. This helps the page
// stay responsive during startup.

renderer.compileAsync( gltf.scene, scene ).then( () => {

scene.add( gltf.scene );

Expand Down
11 changes: 10 additions & 1 deletion examples/webgl_loader_gltf_transmission.html
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,16 @@

mixer = new THREE.AnimationMixer( gltf.scene );
mixer.clipAction( gltf.animations[ 0 ] ).play();
scene.add( gltf.scene );

// Calling compileAsync returns a promise that resolves when gltf.scene can be added
// to scene without unnecessary stalling on shader compiation. This helps the page
// stay responsive during startup.

renderer.compileAsync( gltf.scene, scene ).then( () => {

scene.add( gltf.scene );

} );

} );

Expand Down
150 changes: 73 additions & 77 deletions src/renderers/WebGLRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -855,33 +855,31 @@ function WebGLRenderer( parameters = {} ) {

};

// compileTarget
// compileAsync

this.compileTarget = function ( scene, target, callback ) {
this.compileAsync = function ( scene, targetScene = null ) {

// temporary camera just for the compile
const camera = new Camera();
// If no explicit targetScene was given use the scene instead
if ( ! targetScene ) {

currentRenderState = renderStates.get( scene, camera );
currentRenderState.init();

// if no explicit target was given use the full scene
targetScene = scene;

if ( typeof target === 'unknown' ) {
}

target = scene;
currentRenderState = renderStates.get( targetScene );
currentRenderState.init();

}
renderStateStack.push( currentRenderState );

let foundTarget = scene === target;
let foundScene = scene === targetScene;

// Gather lights from both the scene and the new object that will be added
// to the scene.
scene.traverse( function ( object ) {
targetScene.traverseVisible( function ( object ) {

if ( object === target ) {
if ( object === scene ) {

foundTarget = true;
foundScene = true;

}

Expand All @@ -899,12 +897,11 @@ function WebGLRenderer( parameters = {} ) {

} );

// If the target wasn't already part of the scene, add any lights it
// If the scene wasn't already part of the targetScene, add any lights it
// contains as well.
if ( !foundScene ) {

if ( !foundTarget ) {

target.traverse( function ( object ) {
scene.traverseVisible( function ( object ) {

if ( object.isLight ) {

Expand All @@ -922,95 +919,94 @@ function WebGLRenderer( parameters = {} ) {

}

currentRenderState.setupLights( camera );
currentRenderState.setupLights( _this.physicallyCorrectLights );

const compiling = new Set();

// only initialize materials in the new object
// Only initialize materials in the new scene, not the targetScene.

target.traverse( function ( object ) {
scene.traverse( function ( object ) {

let material = object.material;
const material = object.material;

if ( material ) {

if ( Array.isArray( material ) ) {

for ( let i = 0; i < material.length; i ++ ) {

let material2 = material[ i ];

if ( compiling.has( material2 ) === false ) {

initMaterial( material2, scene, object );
compiling.add( material2 );

}
const material2 = material[ i ];

getProgram( material2, targetScene, object );
compiling.add( material2 );
}

} else if ( compiling.has( material ) === false ) {
} else {

initMaterial( material, scene, object );
getProgram( material, targetScene, object );
compiling.add( material );

}

}

} );

if ( typeof callback === 'undefined' ) return;

// if we've been given a callback, wait for all the materials in the new
// object to indicate that they're ready to be used before calling it

function checkMaterialsReady() {

compiling.forEach( function ( material ) {
currentRenderState = null;

const materialProperties = properties.get( material );
const program = materialProperties.program;
// Wait for all the materials in the new object to indicate that they're
// ready to be used before resolving the promise.

if ( program.isReady() ) {
return new Promise((resolve) => {

// remove any programs that report they're ready to use from the list
compiling.delete( material );
function checkMaterialsReady() {

compiling.forEach( function ( material ) {

const materialProperties = properties.get( material );
const program = materialProperties.currentProgram;

if ( program.isReady() ) {

// remove any programs that report they're ready to use from the list
compiling.delete( material );

}

} );

// once the list of compiling materials is empty, call the callback

if ( compiling.size === 0 ) {

resolve( scene );
return;

}

} );

// once the list of compiling materials is empty, call the callback

if ( compiling.size === 0 ) {

callback( target );
return;


// if some materials are still not ready, wait a bit and check again

setTimeout( checkMaterialsReady, 10 );

}

if ( extensions.get( 'KHR_parallel_shader_compile' ) !== null ) {

// If we can check the compilation status of the materials without
// blocking then do so right away.

checkMaterialsReady();

} else {

// Otherwise start by waiting a bit to give the materials we just
// initialized a chance to finish.

setTimeout( checkMaterialsReady, 10 );

}

// if some materials are still not ready, wait a bit and check again

setTimeout( checkMaterialsReady, 10 );

}

if ( extensions.get( 'KHR_parallel_shader_compile' ) !== null ) {

// if we can check the compilation status of the materials without
// blocking then do so right away.

checkMaterialsReady();

} else {

// otherwise start by waiting a bit to give the materials we just
// initialized a chance to finish.

setTimeout( checkMaterialsReady, 10 );
});

}
};

// Animation Loop
Expand Down
2 changes: 1 addition & 1 deletion src/renderers/webgl/WebGLPrograms.js
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities
rendererExtensionFragDepth: isWebGL2 || extensions.has( 'EXT_frag_depth' ),
rendererExtensionDrawBuffers: isWebGL2 || extensions.has( 'WEBGL_draw_buffers' ),
rendererExtensionShaderTextureLod: isWebGL2 || extensions.has( 'EXT_shader_texture_lod' ),
rendererExtensionShaderTextureLod: extensions.has( 'KHR_parallel_shader_compile' ),
rendererExtensionParallelShaderCompile: extensions.has( 'KHR_parallel_shader_compile' ),

customProgramCacheKey: material.customProgramCacheKey()

Expand Down

0 comments on commit 009bf20

Please sign in to comment.