From 8f319e4a2c7af16435d0bbe6ae90f2a7e34af631 Mon Sep 17 00:00:00 2001 From: Takahiro Date: Sat, 18 Feb 2017 19:00:24 -0800 Subject: [PATCH] Remove MultiMaterial from OutlineEffect --- examples/js/effects/OutlineEffect.js | 151 ++++++++++----------------- 1 file changed, 53 insertions(+), 98 deletions(-) diff --git a/examples/js/effects/OutlineEffect.js b/examples/js/effects/OutlineEffect.js index e5384ba218..7d9da9f73e 100644 --- a/examples/js/effects/OutlineEffect.js +++ b/examples/js/effects/OutlineEffect.js @@ -13,11 +13,11 @@ * * // How to set outline parameters for each material * material.outlineParameters = { - * thickNess: 0.01, // this paremeter won't work for MultiMaterial - * color: new THREE.Color( 0x888888 ), // this paremeter won't work for MultiMaterial - * alpha: 0.8, // this paremeter won't work for MultiMaterial + * thickNess: 0.01, + * color: new THREE.Color( 0x888888 ), + * alpha: 0.8, * visible: true, - * keepAlive: true // this paremeter won't work for Material in materials of MultiMaterial + * keepAlive: true * }; * * TODO @@ -35,8 +35,8 @@ THREE.OutlineEffect = function ( renderer, parameters ) { var defaultAlpha = parameters.defaultAlpha !== undefined ? parameters.defaultAlpha : 1.0; var defaultKeepAlive = parameters.defaultKeepAlive !== undefined ? parameters.defaultKeepAlive : false; - // object.material.uuid -> outlineMaterial - // (no mapping from children of MultiMaterial) + // object.material.uuid -> outlineMaterial or + // object.material[ n ].uuid -> outlineMaterial // save at the outline material creation and release // if it's unused removeThresholdCount frames // unless keepAlive is true. @@ -44,8 +44,8 @@ THREE.OutlineEffect = function ( renderer, parameters ) { var removeThresholdCount = 60; - // outlineMaterial.uuid (or object.uuid for invisibleMaterial) -> originalMaterial - // including children of MultiMaterial. + // outlineMaterial.uuid -> object.material or + // outlineMaterial.uuid -> object.material[ n ] // save before render and release after render. var originalMaterials = {}; @@ -55,8 +55,6 @@ THREE.OutlineEffect = function ( renderer, parameters ) { //this.cache = cache; // for debug - var invisibleMaterial = new THREE.ShaderMaterial( { visible: false } ); - // copied from WebGLPrograms and removed some materials var shaderIDs = { MeshBasicMaterial: 'basic', @@ -139,6 +137,12 @@ THREE.OutlineEffect = function ( renderer, parameters ) { ].join( "\n" ); + function createInvisibleMaterial() { + + return new THREE.ShaderMaterial( { name: 'invisible', visible: false } ); + + } + function createMaterial( originalMaterial ) { var shaderID = shaderIDs[ originalMaterial.type ]; @@ -162,7 +166,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) { console.warn( 'THREE.OutlineEffect requires both vec3 position and normal attributes in vertex shader, ' + 'does not draw outline for ' + originalMaterial.name + '(uuid:' + originalMaterial.uuid + ') material.' ); - return invisibleMaterial; + return createInvisibleMaterial(); } @@ -173,7 +177,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) { } else { - return invisibleMaterial; + return createInvisibleMaterial(); } @@ -195,7 +199,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) { if ( ! /vec3\s+transformed\s*=/.test( originalVertexShader ) && ! /#include\s+/.test( originalVertexShader ) ) defines.DECLARE_TRANSFORMED = true; - var material = new THREE.ShaderMaterial( { + return new THREE.ShaderMaterial( { defines: defines, uniforms: uniforms, vertexShader: vertexShader, @@ -207,73 +211,61 @@ THREE.OutlineEffect = function ( renderer, parameters ) { fog: false } ); - return material; - - } - - function createMultiMaterial( originalMaterial ) { - - var materials = []; - - for ( var i = 0, il = originalMaterial.materials.length; i < il; i ++ ) { - - materials.push( createMaterial( originalMaterial.materials[ i ] ) ); - - } - - return new THREE.MultiMaterial( materials ); - } - function setOutlineMaterial( object ) { - - if ( object.material === undefined ) return; + function getOutlineMaterialFromCache( originalMaterial ) { - var data = cache[ object.material.uuid ]; + var data = cache[ originalMaterial.uuid ]; if ( data === undefined ) { data = { - material: object.material.isMultiMaterial === true ? createMultiMaterial( object.material ) : createMaterial( object.material ), + material: createMaterial( originalMaterial ), used: true, keepAlive: defaultKeepAlive, count: 0 }; - cache[ object.material.uuid ] = data; + cache[ originalMaterial.uuid ] = data; } - var outlineMaterial = data.material; data.used = true; - var uuid = outlineMaterial !== invisibleMaterial ? outlineMaterial.uuid : object.uuid; - originalMaterials[ uuid ] = object.material; + return data.material; - if ( object.material.isMultiMaterial === true ) { + } - for ( var i = 0, il = object.material.materials.length; i < il; i ++ ) { + function getOutlineMaterial( originalMaterial ) { - // originalMaterial of leaf material of MultiMaterial is used only for - // updating outlineMaterial. so need not to save for invisibleMaterial. - if ( outlineMaterial.materials[ i ] !== invisibleMaterial ) { + var outlineMaterial = getOutlineMaterialFromCache( originalMaterial ); - originalMaterials[ outlineMaterial.materials[ i ].uuid ] = object.material.materials[ i ]; + originalMaterials[ outlineMaterial.uuid ] = originalMaterial; - } + updateOutlineMaterial( outlineMaterial, originalMaterial ); - } + return outlineMaterial; + + } + + function setOutlineMaterial( object ) { + + if ( object.material === undefined ) return; - updateOutlineMultiMaterial( outlineMaterial, object.material ); + if ( Array.isArray( object.material ) ) { + + for ( var i = 0, il = object.material.length; i < il; i ++ ) { + + object.material[ i ] = getOutlineMaterial( object.material[ i ] ); + + } } else { - updateOutlineMaterial( outlineMaterial, object.material ); + object.material = getOutlineMaterial( object.material ); } - object.material = outlineMaterial; - originalOnBeforeRenders[ object.uuid ] = object.onBeforeRender; object.onBeforeRender = onBeforeRender; @@ -283,31 +275,29 @@ THREE.OutlineEffect = function ( renderer, parameters ) { if ( object.material === undefined ) return; - var originalMaterial = originalMaterials[ object.material.uuid ]; + if ( Array.isArray( object.material ) ) { + + for ( var i = 0, il = object.material.length; i < il; i ++ ) { - if ( originalMaterial === undefined ) { + object.material[ i ] = originalMaterials[ object.material[ i ].uuid ]; + + } - originalMaterial = originalMaterials[ object.uuid ]; + } else { - if ( originalMaterial === undefined ) return; + object.material = originalMaterials[ object.material.uuid ]; } - object.material = originalMaterial; object.onBeforeRender = originalOnBeforeRenders[ object.uuid ]; } function onBeforeRender( renderer, scene, camera, geometry, material, group ) { - // check some things before updating just in case - - if ( material === invisibleMaterial ) return; - - if ( material.isMultiMaterial === true ) return; - var originalMaterial = originalMaterials[ material.uuid ]; + // just in case if ( originalMaterial === undefined ) return; updateUniforms( material, originalMaterial ); @@ -332,7 +322,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) { function updateOutlineMaterial( material, originalMaterial ) { - if ( material === invisibleMaterial ) return; + if ( material.name === 'invisible' ) return; var outlineParameters = originalMaterial.outlineParameters; @@ -354,8 +344,7 @@ THREE.OutlineEffect = function ( renderer, parameters ) { material.transparent = ( outlineParameters.alpha !== undefined && outlineParameters.alpha < 1.0 ) ? true : originalMaterial.transparent; - // cache[ originalMaterial.uuid ] is undefined if originalMaterial is in materials of MultiMaterial - if ( outlineParameters.keepAlive !== undefined && cache[ originalMaterial.uuid ] !== undefined ) cache[ originalMaterial.uuid ].keepAlive = outlineParameters.keepAlive; + if ( outlineParameters.keepAlive !== undefined ) cache[ originalMaterial.uuid ].keepAlive = outlineParameters.keepAlive; } else { @@ -368,40 +357,6 @@ THREE.OutlineEffect = function ( renderer, parameters ) { } - function updateOutlineMultiMaterial( material, originalMaterial ) { - - if ( material === invisibleMaterial ) return; - - var outlineParameters = originalMaterial.outlineParameters; - - if ( outlineParameters !== undefined ) { - - if ( originalMaterial.visible === false ) { - - material.visible = false; - - } else { - - material.visible = ( outlineParameters.visible !== undefined ) ? outlineParameters.visible : true; - - } - - if ( outlineParameters.keepAlive !== undefined ) cache[ originalMaterial.uuid ].keepAlive = outlineParameters.keepAlive; - - } else { - - material.visible = originalMaterial.visible; - - } - - for ( var i = 0, il = material.materials.length; i < il; i ++ ) { - - updateOutlineMaterial( material.materials[ i ], originalMaterial.materials[ i ] ); - - } - - } - function cleanupCache() { var keys; -- GitLab