提交 8349b07b 编写于 作者: T Takahiro

Remove MultiMaterial from WebGLDeferredRenderer

上级 8e4507d1
......@@ -67,8 +67,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
var _lightPrePass = false;
var _cacheKeepAlive = false;
var _invisibleMaterial = new THREE.ShaderMaterial( { visible: false } );
var _tmpMaterial = new THREE.ShaderMaterial( { visible: false } );
var _tmpVector3 = new THREE.Vector3();
// scene/material/light cache for deferred rendering.
......@@ -80,13 +79,12 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
var _lightScenesCache = {};
var _lightFullscreenScenesCache = {};
// originalMaterial.uuid -> deferredMaterial
// (no mapping from children of MultiMaterial)
// object.material.uuid -> deferredMaterial or
// object.material[ n ].uuid -> deferredMaterial
var _normalDepthMaterialsCache = {};
var _normalDepthShininessMaterialsCache = {};
var _colorMaterialsCache = {};
var _reconstructionMaterialsCache = {};
var _invisibleMultiMaterialsCache = {};
// originalLight.uuid -> deferredLight
var _deferredLightsCache = {};
......@@ -97,8 +95,8 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
var _removeThresholdCount = 60;
// object.uuid -> originalMaterial
// deferred materials.uuid -> originalMaterial
// deferredMaterials.uuid -> object.material or
// deferredMaterials.uuid -> object.material[ n ]
// save before render and release after render.
var _originalMaterialsTable = {};
......@@ -106,6 +104,11 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
// save before render and release after render.
var _originalOnBeforeRendersTable = {};
// object.material.uuid -> object.material.visible or
// object.material[ i ].uuid -> object.material[ i ].visible or
// save before render and release after render.
var _originalVisibleTable = {};
// external properties
this.renderer = undefined;
......@@ -328,70 +331,73 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
}
function getMaterialFromCacheOrCreate( originalMaterial, cache, func ) {
function getMaterialFromCacheOrCreate( originalMaterial, cache, createFunc, updateFunc ) {
var data = cache[ originalMaterial.uuid ];
if ( data === undefined ) {
data = createCacheData();
data.material = createFunc( originalMaterial );
cache[ originalMaterial.uuid ] = data;
var material;
}
if ( originalMaterial.isMultiMaterial === true ) {
data.used = true;
var materials = [];
updateFunc( data.material, originalMaterial );
for ( var i = 0, il = originalMaterial.materials.length; i < il; i ++ ) {
_originalMaterialsTable[ data.material.uuid ] = originalMaterial;
materials.push( func( originalMaterial.materials[ i ] ) );
return data.material;
}
}
material = new THREE.MultiMaterial( materials );
function overrideMaterialAndOnBeforeRender( object, getMaterialFunc, onBeforeRender ) {
} else {
if ( object.material === undefined ) return;
if ( Array.isArray( object.material ) ) {
material = func( originalMaterial );
for ( var i = 0, il = object.material.length; i < il; i ++ ) {
object.material[ i ] = getMaterialFunc( object.material[ i ] );
}
data.material = material;
} else {
cache[ originalMaterial.uuid ] = data;
object.material = getMaterialFunc( object.material );
}
return data.material;
object.onBeforeRender = onBeforeRender;
}
function setMaterialNormalDepth( object ) {
function restoreOriginalMaterial( object ) {
if ( object.material === undefined ) return;
var originalMaterial = _originalMaterialsTable[ object.uuid ];
var material = getNormalDepthMaterial( originalMaterial );
_originalMaterialsTable[ material.uuid ] = originalMaterial;
if ( Array.isArray( object.material ) ) {
if ( material.isMultiMaterial === true ) {
for ( var i = 0, il = object.material.length; i < il; i ++ ) {
for ( var i = 0, il = material.materials.length; i < il; i ++ ) {
_originalMaterialsTable[ material.materials[ i ].uuid ] = originalMaterial.materials[ i ];
updateDeferredNormalDepthMaterial( material.materials[ i ], originalMaterial.materials[ i ] );
object.material[ i ] = _originalMaterialsTable[ object.material[ i ].uuid ];
}
} else {
updateDeferredNormalDepthMaterial( material, originalMaterial );
object.material = _originalMaterialsTable[ object.material.uuid ];
}
object.material = material;
object.onBeforeRender = updateDeferredNormalDepthUniforms;
}
function setMaterialNormalDepth( object ) {
overrideMaterialAndOnBeforeRender( object, getNormalDepthMaterial, updateDeferredNormalDepthUniforms );
}
......@@ -400,7 +406,8 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
return getMaterialFromCacheOrCreate(
originalMaterial,
( _lightPrePass ) ? _normalDepthShininessMaterialsCache : _normalDepthMaterialsCache,
createDeferredNormalDepthMaterial
createDeferredNormalDepthMaterial,
updateDeferredNormalDepthMaterial
);
}
......@@ -448,30 +455,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
function setMaterialColor( object ) {
if ( object.material === undefined ) return;
var originalMaterial = _originalMaterialsTable[ object.uuid ];
var material = getColorMaterial( originalMaterial );
_originalMaterialsTable[ material.uuid ] = originalMaterial;
if ( originalMaterial.isMultiMaterial === true ) {
for ( var i = 0, il = originalMaterial.materials.length; i < il; i ++ ) {
_originalMaterialsTable[ material.materials[ i ].uuid ] = originalMaterial.materials[ i ];
updateDeferredColorMaterial( material.materials[ i ], originalMaterial.materials[ i ] );
}
} else {
updateDeferredColorMaterial( material, originalMaterial );
}
object.material = material;
object.onBeforeRender = updateDeferredColorUniforms;
overrideMaterialAndOnBeforeRender( object, getColorMaterial, updateDeferredColorUniforms );
}
......@@ -480,7 +464,8 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
return getMaterialFromCacheOrCreate(
originalMaterial,
_colorMaterialsCache,
createDeferredColorMaterial
createDeferredColorMaterial,
updateDeferredColorMaterial
);
}
......@@ -551,48 +536,24 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
function setMaterialReconstruction( object ) {
if ( object.material === undefined ) return;
var originalMaterial = _originalMaterialsTable[ object.uuid ];
if ( originalMaterial.transparent === true ) {
object.material = originalMaterial;
object.onBeforeRender = _originalOnBeforeRendersTable[ object.uuid ];
return;
}
var material = getReconstructionMaterial( originalMaterial );
_originalMaterialsTable[ material.uuid ] = originalMaterial;
overrideMaterialAndOnBeforeRender( object, getReconstructionMaterial, updateDeferredReconstructionUniforms );
if ( originalMaterial.isMultiMaterial === true ) {
for ( var i = 0, il = originalMaterial.materials.length; i < il; i ++ ) {
_originalMaterialsTable[ material.materials[ i ].uuid ] = originalMaterial.materials[ i ];
updateDeferredReconstructionMaterial( material.materials[ i ], originalMaterial.materials[ i ] );
}
}
function getReconstructionMaterial( originalMaterial ) {
} else {
if ( originalMaterial.transparent === true ) {
updateDeferredReconstructionMaterial( material, originalMaterial );
_originalMaterialsTable[ originalMaterial.uuid ] = originalMaterial;
return originalMaterial;
}
object.material = material;
object.onBeforeRender = updateDeferredReconstructionUniforms;
}
function getReconstructionMaterial( originalMaterial ) {
return getMaterialFromCacheOrCreate(
originalMaterial,
_reconstructionMaterialsCache,
createDeferredReconstructionMaterial
createDeferredReconstructionMaterial,
updateDeferredReconstructionMaterial
);
}
......@@ -622,65 +583,72 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
function updateDeferredReconstructionUniforms( renderer, scene, camera, geometry, material, group ) {
if ( material.transparent === true ) {
// 'this' is object here because this method is set as object.onBefore()
var onBeforeRender = _originalOnBeforeRendersTable[ this.uuid ];
if ( onBeforeRender ) {
onBeforeRender.call( this, renderer, scene, camera, geometry, material, group );
}
return;
}
updateDeferredColorUniforms( renderer, scene, camera, geometry, material, group );
material.uniforms.samplerLight.value = _compLight.renderTarget2.texture;
}
function setMaterialForwardRendering( object ) {
function setVisibleForForwardRendering( object ) {
if ( object.material === undefined ) return;
var originalMaterial = _originalMaterialsTable[ object.uuid ];
if ( Array.isArray( object.material ) ) {
if ( originalMaterial.isMultiMaterial === true ) {
for ( var i = 0, il = object.material.length; i < il; i ++ ) {
var material = getInvisibleMultiMaterial( originalMaterial );
if ( _originalVisibleTable[ object.material[ i ].uuid ] === undefined ) {
for ( var i = 0, il = originalMaterial.materials.length; i < il; i ++ ) {
_originalVisibleTable[ object.material[ i ].uuid ] = object.material[ i ].visible;
object.material[ i ].visible = object.material[ i ].transparent && object.material[ i ].visible;
material.materials[ i ] = getForwardRenderingMaterial( originalMaterial.materials[ i ] );
}
}
object.material = material;
} else {
object.material = getForwardRenderingMaterial( originalMaterial );
if ( _originalVisibleTable[ object.material.uuid ] === undefined ) {
}
_originalVisibleTable[ object.material.uuid ] = object.material.visible;
object.material.visible = object.material.transparent && object.material.visible;
object.onBeforeRender = _originalOnBeforeRendersTable[ object.uuid ];
}
function getInvisibleMultiMaterial( originalMaterial ) {
}
return getMaterialFromCacheOrCreate(
originalMaterial,
_invisibleMultiMaterialsCache,
createInvisibleMaterial
);
}
}
function createInvisibleMaterial( originalMaterial ) {
function restoreVisible( object ) {
return _invisibleMaterial;
if ( object.material === undefined ) return;
}
if ( Array.isArray( object.material ) ) {
function getForwardRenderingMaterial( originalMaterial ) {
for ( var i = 0, il = object.material.length; i < il; i ++ ) {
if ( originalMaterial.transparent === true && originalMaterial.visible === true ) {
object.material[ i ].visible = _originalVisibleTable[ object.material[ i ].uuid ];
return originalMaterial;
}
} else {
return _invisibleMaterial;
object.material.visible = _originalVisibleTable[ object.material.uuid ];
}
......@@ -761,11 +729,12 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
data = createCacheData();
data.material = createDeferredLightMaterial( light.userData.originalLight );
cache[ light.uuid ] = data;
}
data.used = true;
return data.material;
}
......@@ -784,7 +753,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
function createDeferredLightMesh( light, geometry ) {
var mesh = new THREE.Mesh( geometry, _invisibleMaterial );
var mesh = new THREE.Mesh( geometry, _tmpMaterial );
mesh.userData.originalLight = light;
......@@ -973,21 +942,22 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
}
function saveOriginalMaterialAndCheckTransparency( object ) {
function saveOriginalOnBeforeRenderAndCheckTransparency( object ) {
if ( object.material === undefined ) return;
_originalMaterialsTable[ object.uuid ] = object.material;
_originalOnBeforeRendersTable[ object.uuid ] = object.onBeforeRender;
// _hasTransparentObject is used only for Classic Deferred Rendering
if ( _hasTransparentObject || _lightPrePass ) return;
if ( object.material.isMultiMaterial === true ) {
if ( ! object.visible ) return;
if ( Array.isArray( object.material ) ) {
for ( var i = 0, il = object.material.materials.length; i < il; i ++ ) {
for ( var i = 0, il = object.material.length; i < il; i ++ ) {
if ( object.material.materials[ i ].transparent === true ) {
if ( object.material[ i ].visible === true && object.material[ i ].transparent === true ) {
_hasTransparentObject = true;
break;
......@@ -998,17 +968,16 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
} else {
if ( object.material.transparent === true ) _hasTransparentObject = true;
if ( object.material.visible === true && object.material.transparent === true ) _hasTransparentObject = true;
}
}
function restoreOriginalMaterial( object ) {
function restoreOriginalOnBeforeRender( object ) {
if ( object.material === undefined ) return;
object.material = _originalMaterialsTable[ object.uuid ];
object.onBeforeRender = _originalOnBeforeRendersTable[ object.uuid ];
}
......@@ -1023,11 +992,12 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
data = createCacheData();
data.light = createDeferredLight( object );
_deferredLightsCache[ object.uuid ] = data;
}
data.used = true;
var light = data.light;
if ( light === null ) return;
......@@ -1225,7 +1195,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
function cleanupTable( table ) {
var keys = Object.keys( cache );
var keys = Object.keys( table );
for ( var i = 0, il = keys.length; i < il; i ++ ) {
......@@ -1245,13 +1215,13 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
cleanupCache( _normalDepthShininessMaterialsCache );
cleanupCache( _colorMaterialsCache );
cleanupCache( _reconstructionMaterialsCache );
cleanupCache( _invisibleMultiMaterialsCache );
cleanupCache( _classicDeferredLightMaterialsCache );
cleanupCache( _lightPrePassMaterialsCache );
cleanupCache( _deferredLightsCache );
cleanupTable( _originalMaterialsTable );
cleanupTable( _originalOnBeforeRendersTable );
cleanupTable( _originalVisibleTable );
}
......@@ -1289,6 +1259,8 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
_compNormalDepth.render();
scene.traverse( restoreOriginalMaterial );
}
/*
......@@ -1317,6 +1289,8 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
_compColor.render();
scene.traverse( restoreOriginalMaterial );
}
/*
......@@ -1397,6 +1371,8 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
_gl.disable( _gl.STENCIL_TEST );
scene.traverse( restoreOriginalMaterial );
}
/*
......@@ -1426,7 +1402,8 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
if ( ! _lightPrePass && _hasTransparentObject ) {
scene.traverse( setMaterialForwardRendering );
scene.traverse( setVisibleForForwardRendering );
scene.traverse( restoreOriginalOnBeforeRender );
_passForward.scene = scene;
_passForward.camera = camera;
......@@ -1440,6 +1417,12 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
_compFinal.render();
if ( ! _lightPrePass && _hasTransparentObject ) {
scene.traverse( restoreVisible );
}
}
// external APIs
......@@ -1504,7 +1487,7 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
_hasTransparentObject = false;
scene.traverse( saveOriginalMaterialAndCheckTransparency );
scene.traverse( saveOriginalOnBeforeRenderAndCheckTransparency );
updateDeferredCommonUniforms( camera );
......@@ -1524,7 +1507,9 @@ THREE.WebGLDeferredRenderer = function ( parameters ) {
renderFinal( scene, camera );
scene.traverse( restoreOriginalMaterial );
scene.traverse( restoreOriginalOnBeforeRender );
cleanupCaches();
scene.autoUpdate = currentSceneAutoUpdate;
this.renderer.autoClearColor = currentAutoClearColor;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册