提交 3c455c2c 编写于 作者: T Takahiro 提交者: Mr.doob

Export OutlineDrawingPass from MMDHelper to make it reusable (#9868)

* Add BackFaceCullingOutlinePass

* Let MMDHelper use BackFaceCullingOutlinePass

* Change from BackFaceCullingOutlinePass to OutlineEffect

* Add OutlineEffect

* Correct comment

* Remove this.renderer from OutlineEffect to follow other Effects style

* Rename variables from tmp* to current*
上级 498c11d5
/**
* @author takahirox / http://github.com/takahirox/
*
* Reference: https://en.wikipedia.org/wiki/Cel_shading
*
* // How to set default outline parameters
* new THREE.OutlineEffect( renderer, {
* defaultThickNess: 0.01,
* defaultColor: new THREE.Color( 0x888888 ),
* defaultAlpha: 0.8
* } );
*
* // How to set outline parameters for each material
* material.outlineParameters = {
* thickNess: 0.01,
* color: new THREE.Color( 0x888888 ),
* alpha: 0.8,
* visible: true
* };
*
* TODO
* - shared material
* - support shader material without objectNormal in its vertexShader
*/
THREE.OutlineEffect = function ( renderer, parameters ) {
var _this = this;
parameters = parameters || {};
this.autoClear = parameters.autoClear !== undefined ? parameters.autoClear : true;
var defaultThickness = parameters.defaultThickness !== undefined ? parameters.defaultThickness : 0.003;
var defaultColor = parameters.defaultColor !== undefined ? parameters.defaultColor : new THREE.Color( 0x000000 );
var defaultAlpha = parameters.defaultAlpha !== undefined ? parameters.defaultAlpha : 1.0;
var invisibleMaterial = new THREE.ShaderMaterial( { visible: false } );
// copied from WebGLPrograms and removed some materials
var shaderIDs = {
MeshBasicMaterial: 'basic',
MeshLambertMaterial: 'lambert',
MeshPhongMaterial: 'phong',
MeshStandardMaterial: 'physical',
MeshPhysicalMaterial: 'physical'
};
var uniformsChunk = {
outlineThickness: { type: "f", value: defaultThickness },
outlineColor: { type: "c", value: defaultColor },
outlineAlpha: { type: "f", value: defaultAlpha }
};
var vertexShaderChunk = [
"uniform float outlineThickness;",
"vec4 calculateOutline( vec4 pos, vec3 objectNormal, vec4 skinned ) {",
" float thickness = outlineThickness;",
" float ratio = 1.0;", // TODO: support outline thickness ratio for each vertex
" vec4 pos2 = projectionMatrix * modelViewMatrix * vec4( skinned.xyz + objectNormal, 1.0 );",
// NOTE: subtract pos2 from pos because BackSide objectNormal is negative
" vec4 norm = normalize( pos - pos2 );",
" return pos + norm * thickness * pos.w * ratio;",
"}",
].join( "\n" );
var vertexShaderChunk2 = [
"#if ! defined( LAMBERT ) && ! defined( PHONG ) && ! defined( PHYSICAL )",
" #ifndef USE_ENVMAP",
" vec3 objectNormal = normalize( normal );",
" #ifdef FLIP_SIDED",
" objectNormal = -objectNormal;",
" #endif",
" #endif",
"#endif",
"#ifdef USE_SKINNING",
" gl_Position = calculateOutline( gl_Position, objectNormal, skinned );",
"#else",
" gl_Position = calculateOutline( gl_Position, objectNormal, vec4( transformed, 1.0 ) );",
"#endif",
].join( "\n" );
var fragmentShader = [
"#include <common>",
"#include <fog_pars_fragment>",
"uniform vec3 outlineColor;",
"uniform float outlineAlpha;",
"void main() {",
" gl_FragColor = vec4( outlineColor, outlineAlpha );",
" #include <fog_fragment>",
"}",
].join( "\n" );
function createMaterial ( originalMaterial ) {
var shaderID = shaderIDs[ originalMaterial.type ];
var originalUniforms, originalVertexShader;
var outlineParameters = originalMaterial.outlineParameters;
if ( shaderID !== undefined ) {
var shader = THREE.ShaderLib[ shaderID ];
originalUniforms = shader.uniforms;
originalVertexShader = shader.vertexShader;
} else if ( originalMaterial.isShaderMaterial === true ) {
originalUniforms = originalMaterial.uniforms;
originalVertexShader = originalMaterial.vertexShader;
} else {
return invisibleMaterial;
}
var uniforms = THREE.UniformsUtils.merge( [
originalUniforms,
uniformsChunk
] );
var vertexShader = originalVertexShader
// put vertexShaderChunk right before "void main() {...}"
.replace( /void\s+main\s*\(\s*\)/, vertexShaderChunk + '\nvoid main()' )
// put vertexShaderChunk2 the end of "void main() {...}"
// Note: here assums originalVertexShader ends with "}" of "void main() {...}"
.replace( /\}\s*$/, vertexShaderChunk2 + '\n}' )
// remove any light related lines
// Note: here is very sensitive to originalVertexShader
// TODO: consider safer way
.replace( /#include\s+<[\w_]*light[\w_]*>/g, '' );
var material = new THREE.ShaderMaterial( {
uniforms: THREE.UniformsUtils.clone( uniforms ),
vertexShader: vertexShader,
fragmentShader: fragmentShader,
side: THREE.BackSide,
//wireframe: true,
skinning: false,
morphTargets: false,
morphNormals: false,
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;
object.userData.originalMaterial = object.material;
if ( object.userData.outlineMaterial === undefined ) {
object.userData.outlineMaterial = object.material.type === 'MultiMaterial' ? createMultiMaterial( object.material ) : createMaterial( object.material );
}
if ( object.userData.outlineMaterial.type === 'MultiMaterial' ) {
updateOutlineMultiMaterial( object.userData.outlineMaterial, object.userData.originalMaterial );
} else {
updateOutlineMaterial( object.userData.outlineMaterial, object.userData.originalMaterial );
}
object.material = object.userData.outlineMaterial;
}
function updateOutlineMaterial ( material, originalMaterial ) {
if ( material === invisibleMaterial ) return;
var outlineParameters = originalMaterial.outlineParameters;
material.skinning = originalMaterial.skinning;
material.morphTargets = originalMaterial.morphTargets;
material.morphNormals = originalMaterial.morphNormals;
material.fog = originalMaterial.fog;
material.visible = originalMaterial.visible;
material.uniforms.outlineAlpha.value = originalMaterial.opacity;
if ( outlineParameters !== undefined ) {
if ( outlineParameters.thickness !== undefined ) material.uniforms.outlineThickness.value = outlineParameters.thickness;
if ( outlineParameters.color !== undefined ) material.uniforms.outlineColor.value.copy( outlineParameters.color );
if ( outlineParameters.alpha !== undefined ) material.uniforms.outlineAlpha.value = outlineParameters.alpha;
if ( outlineParameters.visible !== undefined ) material.visible = outlineParameters.visible;
}
if ( material.uniforms.outlineAlpha.value < 1.0 ) material.transparent = true;
}
function updateOutlineMultiMaterial ( material, originalMaterial ) {
var outlineParameters = originalMaterial.outlineParameters;
material.visible = originalMaterial.visible;
if ( outlineParameters !== undefined ) {
if ( outlineParameters.visible !== undefined ) material.visible = outlineParameters.visible;
}
for ( var i = 0, il = material.materials.length; i < il; i ++ ) {
updateOutlineMaterial( material.materials[ i ], originalMaterial.materials[ i ] );
}
}
function restoreOriginalMaterial ( object ) {
if ( object.userData.originalMaterial !== undefined ) object.material = object.userData.originalMaterial;
}
this.setSize = function ( width, height ) {
renderer.setSize( width, height );
};
this.render = function ( scene, camera, renderTarget, forceClear ) {
var currentAutoClear = renderer.autoClear;
renderer.autoClear = this.autoClear;
// 1. render normally
renderer.render( scene, camera, renderTarget, forceClear );
// 2. render outline
var currentSceneAutoUpdate = scene.autoUpdate;
var currentShadowMapEnabled = renderer.shadowMap.enabled;
scene.autoUpdate = false;
renderer.autoClear = false;
renderer.shadowMap.enabled = false;
scene.traverse( setOutlineMaterial );
renderer.render( scene, camera, renderTarget );
scene.traverse( restoreOriginalMaterial );
scene.autoUpdate = currentSceneAutoUpdate;
renderer.autoClear = currentAutoClear;
renderer.shadowMap.enabled = currentShadowMapEnabled;
};
};
......@@ -3,7 +3,11 @@
*
* Dependencies
* - charset-encoder-js https://github.com/takahirox/charset-encoder-js
* - ammo.js https://github.com/kripken/ammo.js
* - THREE.TGALoader
* - THREE.MMDPhysics
* - THREE.CCDIKSolver
* - THREE.OutlineEffect
*
*
* This loader loads and parses PMD/PMX and VMD binary files
......@@ -2336,7 +2340,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
var imageData = t.image.data !== undefined ? t.image : createImageData( t.image );
var uvs = geometry.faceVertexUvs[ 0 ].slice( m.faceOffset, m.faceOffset + m.faceNum );
m.textureTransparency = detectTextureTransparency( imageData, uvs );
if ( detectTextureTransparency( imageData, uvs ) ) m.transparent = true;
delete m.faceOffset;
delete m.faceNum;
......@@ -2392,9 +2396,14 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
};
m.uniforms.outlineThickness.value = p2.edgeFlag === 1 ? 0.003 : 0.0;
m.uniforms.outlineColor.value = new THREE.Color( 0.0, 0.0, 0.0 );
m.uniforms.outlineAlpha.value = 1.0;
m.outlineParameters = {
thickness: p2.edgeFlag === 1 ? 0.003 : 0.0,
color: new THREE.Color( 0.0, 0.0, 0.0 ),
alpha: 1.0
};
if ( m.outlineParameters.thickness === 0.0 ) m.outlineParameters.visible = false;
m.uniforms.toonMap.value = textures[ p2.toonIndex ];
m.uniforms.celShading.value = 1;
......@@ -2408,13 +2417,19 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
var uuid = loadTexture( n, { defaultTexturePath: isDefaultToonTexture( n ) } );
m.uniforms.toonMap.value = textures[ uuid ];
m.uniforms.hasToonTexture.value = 1;
}
} else {
m.uniforms.outlineThickness.value = p2.edgeSize / 300;
m.uniforms.outlineColor.value = new THREE.Color( p2.edgeColor[ 0 ], p2.edgeColor[ 1 ], p2.edgeColor[ 2 ] );
m.uniforms.outlineAlpha.value = p2.edgeColor[ 3 ];
m.outlineParameters = {
thickness: p2.edgeSize / 300,
color: new THREE.Color( p2.edgeColor[ 0 ], p2.edgeColor[ 1 ], p2.edgeColor[ 2 ] ),
alpha: p2.edgeColor[ 3 ]
};
if ( m.outlineParameters.thickness === 0.0 ) m.outlineParameters.visible = false;
m.uniforms.celShading.value = 1;
if ( p2.toonIndex === -1 ) {
......@@ -2472,7 +2487,7 @@ THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress
if ( m.uniforms.opacity.value !== e.diffuse[ 3 ] ) {
m.morphTransparency = true;
m.transparent = true;
}
......@@ -3558,148 +3573,22 @@ THREE.ShaderLib[ 'mmd' ] = {
uniforms: THREE.UniformsUtils.merge( [
THREE.UniformsLib[ "common" ],
THREE.UniformsLib[ "aomap" ],
THREE.UniformsLib[ "lightmap" ],
THREE.UniformsLib[ "emissivemap" ],
THREE.UniformsLib[ "bumpmap" ],
THREE.UniformsLib[ "normalmap" ],
THREE.UniformsLib[ "displacementmap" ],
THREE.UniformsLib[ "fog" ],
THREE.UniformsLib[ "lights" ],
THREE.ShaderLib[ 'phong' ].uniforms,
// MMD specific for toon mapping
{
"emissive" : { value: new THREE.Color( 0x000000 ) },
"specular" : { value: new THREE.Color( 0x111111 ) },
"shininess": { value: 30 }
},
// ---- MMD specific for cel shading(outline drawing and toon mapping)
{
"outlineDrawing" : { value: 0 },
"outlineThickness": { value: 0.0 },
"outlineColor" : { value: new THREE.Color( 0x000000 ) },
"outlineAlpha" : { value: 1.0 },
"celShading" : { value: 0 },
"toonMap" : { value: null },
"hasToonTexture" : { value: 0 }
"celShading" : { type: "i", value: 0 },
"toonMap" : { type: "t", value: null },
"hasToonTexture" : { type: "i", value: 0 }
}
// ---- MMD specific for cel shading(outline drawing and toon mapping)
] ),
vertexShader: [
"#define PHONG",
"varying vec3 vViewPosition;",
"#ifndef FLAT_SHADED",
" varying vec3 vNormal;",
"#endif",
vertexShader: THREE.ShaderLib[ 'phong' ].vertexShader,
THREE.ShaderChunk[ "common" ],
THREE.ShaderChunk[ "uv_pars_vertex" ],
THREE.ShaderChunk[ "uv2_pars_vertex" ],
THREE.ShaderChunk[ "displacementmap_pars_vertex" ],
THREE.ShaderChunk[ "envmap_pars_vertex" ],
THREE.ShaderChunk[ "color_pars_vertex" ],
THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
THREE.ShaderChunk[ "skinning_pars_vertex" ],
THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
THREE.ShaderChunk[ "logdepthbuf_pars_vertex" ],
THREE.ShaderChunk[ "clipping_planes_pars_vertex" ],
// put toon mapping logic right before "void main() {...}"
fragmentShader: THREE.ShaderLib[ 'phong' ].fragmentShader.replace( /void\s+main\s*\(\s*\)/, [
// ---- MMD specific for outline drawing
" uniform bool outlineDrawing;",
" uniform float outlineThickness;",
// ---- MMD specific for outline drawing
"void main() {",
THREE.ShaderChunk[ "uv_vertex" ],
THREE.ShaderChunk[ "uv2_vertex" ],
THREE.ShaderChunk[ "color_vertex" ],
THREE.ShaderChunk[ "beginnormal_vertex" ],
THREE.ShaderChunk[ "morphnormal_vertex" ],
THREE.ShaderChunk[ "skinbase_vertex" ],
THREE.ShaderChunk[ "skinnormal_vertex" ],
THREE.ShaderChunk[ "defaultnormal_vertex" ],
"#ifndef FLAT_SHADED", // Normal computed with derivatives when FLAT_SHADED
" vNormal = normalize( transformedNormal );",
"#endif",
THREE.ShaderChunk[ "begin_vertex" ],
THREE.ShaderChunk[ "displacementmap_vertex" ],
THREE.ShaderChunk[ "morphtarget_vertex" ],
THREE.ShaderChunk[ "skinning_vertex" ],
THREE.ShaderChunk[ "project_vertex" ],
THREE.ShaderChunk[ "logdepthbuf_vertex" ],
THREE.ShaderChunk[ "clipping_planes_vertex" ],
" vViewPosition = - mvPosition.xyz;",
THREE.ShaderChunk[ "worldpos_vertex" ],
THREE.ShaderChunk[ "envmap_vertex" ],
THREE.ShaderChunk[ "shadowmap_vertex" ],
// ---- MMD specific for outline drawing
" if ( outlineDrawing ) {",
" float thickness = outlineThickness;",
" float ratio = 1.0;", // TODO: support outline size ratio for each vertex
" vec4 epos = projectionMatrix * modelViewMatrix * skinned;",
" vec4 epos2 = projectionMatrix * modelViewMatrix * vec4( skinned.xyz + objectNormal, 1.0 );",
" vec4 enorm = normalize( epos2 - epos );",
" gl_Position = epos + enorm * thickness * epos.w * ratio;",
" }",
// ---- MMD specific for outline drawing
"}"
].join( "\n" ),
fragmentShader: [
"#define PHONG",
"uniform vec3 diffuse;",
"uniform vec3 emissive;",
"uniform vec3 specular;",
"uniform float shininess;",
"uniform float opacity;",
THREE.ShaderChunk[ "common" ],
THREE.ShaderChunk[ "packing" ],
THREE.ShaderChunk[ "color_pars_fragment" ],
THREE.ShaderChunk[ "uv_pars_fragment" ],
THREE.ShaderChunk[ "uv2_pars_fragment" ],
THREE.ShaderChunk[ "map_pars_fragment" ],
THREE.ShaderChunk[ "alphamap_pars_fragment" ],
THREE.ShaderChunk[ "aomap_pars_fragment" ],
THREE.ShaderChunk[ "lightmap_pars_fragment" ],
THREE.ShaderChunk[ "emissivemap_pars_fragment" ],
THREE.ShaderChunk[ "envmap_pars_fragment" ],
THREE.ShaderChunk[ "fog_pars_fragment" ],
THREE.ShaderChunk[ "bsdfs" ],
THREE.ShaderChunk[ "lights_pars" ],
THREE.ShaderChunk[ "lights_phong_pars_fragment" ],
THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
THREE.ShaderChunk[ "bumpmap_pars_fragment" ],
THREE.ShaderChunk[ "normalmap_pars_fragment" ],
THREE.ShaderChunk[ "specularmap_pars_fragment" ],
THREE.ShaderChunk[ "logdepthbuf_pars_fragment" ],
THREE.ShaderChunk[ "clipping_planes_pars_fragment" ],
// ---- MMD specific for cel shading
" uniform bool outlineDrawing;",
" uniform vec3 outlineColor;",
" uniform float outlineAlpha;",
" uniform bool celShading;",
" uniform sampler2D toonMap;",
" uniform bool hasToonTexture;",
......@@ -3738,52 +3627,9 @@ THREE.ShaderLib[ 'mmd' ] = {
"#define RE_Direct RE_Direct_BlinnMMD",
// ---- MMD specific for toon mapping
"void main() {",
// ---- MMD specific for outline drawing
" if ( outlineDrawing ) {",
" gl_FragColor = vec4( outlineColor, outlineAlpha );",
" return;",
" }",
// ---- MMD specific for outline drawing
THREE.ShaderChunk[ "clipping_planes_fragment" ],
"void main()",
" vec4 diffuseColor = vec4( diffuse, opacity );",
" ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );",
" vec3 totalEmissiveRadiance = emissive;",
THREE.ShaderChunk[ "logdepthbuf_fragment" ],
THREE.ShaderChunk[ "map_fragment" ],
THREE.ShaderChunk[ "color_fragment" ],
THREE.ShaderChunk[ "alphamap_fragment" ],
THREE.ShaderChunk[ "alphatest_fragment" ],
THREE.ShaderChunk[ "specularmap_fragment" ],
THREE.ShaderChunk[ "normal_flip" ],
THREE.ShaderChunk[ "normal_fragment" ],
THREE.ShaderChunk[ "emissivemap_fragment" ],
// accumulation
THREE.ShaderChunk[ "lights_phong_fragment" ],
THREE.ShaderChunk[ "lights_template" ],
// modulation
THREE.ShaderChunk[ "aomap_fragment" ],
"vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;",
THREE.ShaderChunk[ "envmap_fragment" ],
" gl_FragColor = vec4( outgoingLight, diffuseColor.a );",
THREE.ShaderChunk[ "premultiplied_alpha_fragment" ],
THREE.ShaderChunk[ "tonemapping_fragment" ],
THREE.ShaderChunk[ "encodings_fragment" ],
THREE.ShaderChunk[ "fog_fragment" ],
"}"
].join( "\n" )
].join( "\n" ) )
};
......@@ -3935,8 +3781,13 @@ THREE.MMDGrantSolver.prototype = {
THREE.MMDHelper = function ( renderer ) {
this.renderer = renderer;
this.outlineEffect = null;
this.effect = null;
this.autoClear = true;
this.meshes = [];
this.doAnimation = true;
......@@ -3959,15 +3810,10 @@ THREE.MMDHelper.prototype = {
init: function () {
this.initRender();
},
this.outlineEffect = new THREE.OutlineEffect( this.renderer );
initRender: function () {
this.renderer.autoClear = false;
this.renderer.autoClearColor = false;
this.renderer.autoClearDepth = false;
var size = this.renderer.getSize();
this.setSize( size.width, size.height );
},
......@@ -3990,6 +3836,12 @@ THREE.MMDHelper.prototype = {
},
setSize: function ( width, height ) {
this.outlineEffect.setSize( width, height );
},
/*
* Note: There may be a possibility that Outline wouldn't work well with Effect.
* In such a case, try to set doOutlineDrawing = false or
......@@ -4106,7 +3958,7 @@ THREE.MMDHelper.prototype = {
},
/*
* detect the longest duration among model, camera, and audio animation and then
* detect the longest duration among model, camera, and audio animations and then
* set it to them to sync.
* TODO: touching private properties ( ._actions and ._clip ) so consider better way
* to access them for safe and modularity.
......@@ -4298,187 +4150,135 @@ THREE.MMDHelper.prototype = {
render: function ( scene, camera ) {
this.renderer.clearColor();
this.renderer.clearDepth();
this.renderer.clear( true, true );
this.renderMain( scene, camera );
if ( this.doOutlineDrawing ) {
this.renderOutline( scene, camera );
}
},
renderMain: function ( scene, camera ) {
this.setupMainRendering();
this.callRender( scene, camera );
},
renderOutline: function () {
var invisibledObjects = [];
var setInvisible;
var restoreVisible;
return function renderOutline( scene, camera ) {
if ( this.effect === null ) {
var self = this;
if ( this.doOutlineDrawing ) {
if ( setInvisible === undefined ) {
this.outlineEffect.autoClear = this.autoClear;
this.outlineEffect.render( scene, camera );
setInvisible = function ( object ) {
} else {
if ( ! object.visible || ! object.layers.test( camera.layers ) ) return;
var currentAutoClear = this.renderer.autoClear;
this.renderer.autoClear = this.autoClear;
this.renderer.render( scene, camera );
this.renderer.autoClear = currentAutoClear;
// any types else to skip?
if ( object instanceof THREE.Scene ||
object instanceof THREE.Bone ||
object instanceof THREE.Light ||
object instanceof THREE.Camera ||
object instanceof THREE.Audio ||
object instanceof THREE.AudioListener ) return;
}
if ( object instanceof THREE.SkinnedMesh ) {
} else {
for ( var i = 0, il = self.meshes.length; i < il; i ++ ) {
var currentAutoClear = this.renderer.autoClear;
this.renderer.autoClear = this.autoClear;
if ( self.meshes[ i ] === object ) return;
if ( this.doOutlineDrawing ) {
}
this.renderWithEffectAndOutline( scene, camera );
}
} else {
object.layers.mask &= ~ camera.layers.mask;
invisibledObjects.push( object );
};
this.effect.render( scene, camera );
}
if ( restoreVisible === undefined ) {
restoreVisible = function () {
for ( var i = 0, il = invisibledObjects.length; i < il; i ++ ) {
invisibledObjects[ i ].layers.mask |= camera.layers.mask;
}
invisibledObjects.length = 0;
this.renderer.autoClear = currentAutoClear;
};
}
}
scene.traverse( setInvisible );
},
var tmpEnabled = this.renderer.shadowMap.enabled;
this.renderer.shadowMap.enabled = false;
/*
* Currently(r82 dev) there's no way to render with two Effects
* then attempt to get them to coordinately run by myself.
*
* What this method does
* 1. let OutlineEffect make outline materials (only once)
* 2. render normally with effect
* 3. set outline materials
* 4. render outline with effect
* 5. restore original materials
*/
renderWithEffectAndOutline: function ( scene, camera ) {
this.setupOutlineRendering();
this.callRender( scene, camera );
var hasOutlineMaterial = false;
this.renderer.shadowMap.enabled = tmpEnabled;
function checkIfObjectHasOutlineMaterial ( object ) {
restoreVisible();
if ( object.material === undefined ) return;
};
if ( object.userData.outlineMaterial !== undefined ) hasOutlineMaterial = true;
}(),
}
callRender: function ( scene, camera ) {
function setOutlineMaterial ( object ) {
if ( this.effect === null ) {
if ( object.material === undefined ) return;
this.renderer.render( scene, camera );
if ( object.userData.outlineMaterial === undefined ) return;
} else {
object.userData.originalMaterial = object.material;
this.effect.render( scene, camera );
object.material = object.userData.outlineMaterial;
}
},
function restoreOriginalMaterial ( object ) {
setupMainRendering: function () {
if ( object.material === undefined ) return;
for ( var i = 0; i < this.meshes.length; i++ ) {
if ( object.userData.originalMaterial === undefined ) return;
this.setupMainRenderingOneMesh( this.meshes[ i ] );
object.material = object.userData.originalMaterial;
}
},
return function renderWithEffectAndOutline( scene, camera ) {
setupMainRenderingOneMesh: function ( mesh ) {
hasOutlineMaterial = false;
for ( var i = 0; i < mesh.material.materials.length; i++ ) {
var forceClear = false;
var m = mesh.material.materials[ i ];
m.uniforms.outlineDrawing.value = 0;
m.visible = true;
scene.traverse( checkIfObjectHasOutlineMaterial );
if ( m.uniforms.opacity.value === 1.0 ) {
if ( ! hasOutlineMaterial ) {
m.side = THREE.FrontSide;
m.transparent = false;
this.outlineEffect.render( scene, camera );
} else {
forceClear = true;
m.side = THREE.DoubleSide;
m.transparent = true;
scene.traverse( checkIfObjectHasOutlineMaterial );
}
if ( m.textureTransparency === true || m.morphTransparency === true ) {
if ( hasOutlineMaterial ) {
m.transparent = true;
this.renderer.autoClear = this.autoClear || forceClear;
}
this.effect.render( scene, camera );
}
scene.traverse( setOutlineMaterial );
},
var currentShadowMapEnabled = this.renderer.shadowMap.enabled;
setupOutlineRendering: function () {
this.renderer.autoClear = false;
this.renderer.shadowMap.enabled = false;
for ( var i = 0; i < this.meshes.length; i++ ) {
this.effect.render( scene, camera );
this.setupOutlineRenderingOneMesh( this.meshes[ i ] );
this.renderer.shadowMap.enabled = currentShadowMapEnabled;
}
},
setupOutlineRenderingOneMesh: function ( mesh ) {
for ( var i = 0; i < mesh.material.materials.length; i++ ) {
var m = mesh.material.materials[ i ];
m.uniforms.outlineDrawing.value = 1;
m.side = THREE.BackSide;
if ( m.uniforms.outlineAlpha.value < 1.0 ) {
scene.traverse( restoreOriginalMaterial );
m.transparent = true;
}
if ( m.uniforms.outlineThickness.value === 0.0 ) {
} else {
m.visible = false;
this.outlineEffect.autoClear = this.autoClear || forceClear;
this.outlineEffect.render( scene, camera );
}
}
},
}(),
poseAsVpd: function ( mesh, vpd, params ) {
......
......@@ -37,8 +37,10 @@
<script src="js/libs/charsetencoder.min.js"></script>
<script src="js/libs/ammo.js"></script>
<script src="js/loaders/TGALoader.js"></script>
<script src="js/loaders/MMDLoader.js"></script>
<script src="js/effects/OutlineEffect.js"></script>
<script src="js/animation/CCDIKSolver.js"></script>
<script src="js/animation/MMDPhysics.js"></script>
......@@ -151,7 +153,7 @@
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
helper.setSize( window.innerWidth, window.innerHeight );
}
......@@ -185,7 +187,6 @@
} else {
renderer.clear();
renderer.render( scene, camera );
}
......
......@@ -40,8 +40,10 @@
<script src="js/libs/charsetencoder.min.js"></script>
<script src="js/libs/ammo.js"></script>
<script src="js/loaders/TGALoader.js"></script>
<script src="js/loaders/MMDLoader.js"></script>
<script src="js/effects/OutlineEffect.js"></script>
<script src="js/animation/CCDIKSolver.js"></script>
<script src="js/animation/MMDPhysics.js"></script>
......@@ -188,7 +190,7 @@
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
helper.setSize( window.innerWidth, window.innerHeight );
}
......@@ -218,7 +220,6 @@
} else {
renderer.clear();
renderer.render( scene, camera );
}
......
......@@ -37,8 +37,10 @@
<script src="js/libs/charsetencoder.min.js"></script>
<script src="js/libs/ammo.js"></script>
<script src="js/loaders/TGALoader.js"></script>
<script src="js/loaders/MMDLoader.js"></script>
<script src="js/effects/OutlineEffect.js"></script>
<script src="js/animation/CCDIKSolver.js"></script>
<script src="js/animation/MMDPhysics.js"></script>
......@@ -293,7 +295,7 @@
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
helper.setSize( window.innerWidth, window.innerHeight );
}
......@@ -326,7 +328,6 @@
} else {
renderer.clear();
renderer.render( scene, camera );
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册