Doodle3D-Slicer/three.js-master/examples/js/renderers/plugins/DepthPassPlugin.js

231 lines
5.4 KiB
JavaScript
Raw Normal View History

2015-06-12 15:58:26 +02:00
/**
* @author alteredq / http://alteredqualia.com/
*/
THREE.DepthPassPlugin = function () {
this.enabled = false;
this.renderTarget = null;
var _gl,
_renderer,
_lights, _webglObjects, _webglObjectsImmediate,
_depthMaterial, _depthMaterialMorph, _depthMaterialSkin, _depthMaterialMorphSkin,
_frustum = new THREE.Frustum(),
_projScreenMatrix = new THREE.Matrix4(),
_renderList = [];
this.init = function ( renderer, lights, webglObjects, webglObjectsImmediate ) {
_gl = renderer.context;
_renderer = renderer;
_lights = lights;
_webglObjects = webglObjects;
_webglObjectsImmediate = webglObjectsImmediate;
var depthShader = THREE.ShaderLib[ "depthRGBA" ];
var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
_depthMaterial = new THREE.ShaderMaterial( {
fragmentShader: depthShader.fragmentShader,
vertexShader: depthShader.vertexShader,
uniforms: depthUniforms
} );
_depthMaterialMorph = new THREE.ShaderMaterial( {
fragmentShader: depthShader.fragmentShader,
vertexShader: depthShader.vertexShader,
uniforms: depthUniforms,
morphTargets: true
} );
_depthMaterialSkin = new THREE.ShaderMaterial( {
fragmentShader: depthShader.fragmentShader,
vertexShader: depthShader.vertexShader,
uniforms: depthUniforms,
skinning: true
} );
_depthMaterialMorphSkin = new THREE.ShaderMaterial( {
fragmentShader: depthShader.fragmentShader,
vertexShader: depthShader.vertexShader,
uniforms: depthUniforms,
morphTargets: true,
skinning: true
} );
_depthMaterial._shadowPass = true;
_depthMaterialMorph._shadowPass = true;
_depthMaterialSkin._shadowPass = true;
_depthMaterialMorphSkin._shadowPass = true;
};
this.render = function ( scene, camera ) {
if ( ! this.enabled ) return;
this.update( scene, camera );
};
this.update = function ( scene, camera ) {
var i, il, j, jl, n,
program, buffer, material,
webglObject, object, light,
renderList,
fog = null;
// set GL state for depth map
_gl.clearColor( 1, 1, 1, 1 );
_gl.disable( _gl.BLEND );
_renderer.state.setDepthTest( true );
// update scene
if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
// update camera matrices and frustum
camera.matrixWorldInverse.getInverse( camera.matrixWorld );
_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
_frustum.setFromMatrix( _projScreenMatrix );
// render depth map
_renderer.setRenderTarget( this.renderTarget );
_renderer.clear();
// set object matrices & frustum culling
_renderList.length = 0;
projectObject(scene, scene, camera);
// render regular objects
var objectMaterial, useMorphing, useSkinning;
for ( j = 0, jl = _renderList.length; j < jl; j ++ ) {
webglObject = _renderList[ j ];
object = webglObject.object;
buffer = webglObject.buffer;
// todo: create proper depth material for particles
if ( object instanceof THREE.PointCloud && ! object.customDepthMaterial ) continue;
objectMaterial = getObjectMaterial( object );
if ( objectMaterial ) _renderer.setMaterialFaces( object.material );
useMorphing = object.geometry.morphTargets !== undefined && object.geometry.morphTargets.length > 0 && objectMaterial.morphTargets;
useSkinning = object instanceof THREE.SkinnedMesh && objectMaterial.skinning;
if ( object.customDepthMaterial ) {
material = object.customDepthMaterial;
} else if ( useSkinning ) {
material = useMorphing ? _depthMaterialMorphSkin : _depthMaterialSkin;
} else if ( useMorphing ) {
material = _depthMaterialMorph;
} else {
material = _depthMaterial;
}
if ( buffer instanceof THREE.BufferGeometry ) {
_renderer.renderBufferDirect( camera, _lights, fog, material, buffer, object );
} else {
_renderer.renderBuffer( camera, _lights, fog, material, buffer, object );
}
}
// set matrices and render immediate objects
for ( j = 0, jl = _webglObjectsImmediate.length; j < jl; j ++ ) {
webglObject = _webglObjectsImmediate[ j ];
object = webglObject.object;
if ( object.visible ) {
object._modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
_renderer.renderImmediateObject( camera, _lights, fog, _depthMaterial, object );
}
}
// restore GL state
var clearColor = _renderer.getClearColor(),
clearAlpha = _renderer.getClearAlpha();
_gl.clearColor( clearColor.r, clearColor.g, clearColor.b, clearAlpha );
_gl.enable( _gl.BLEND );
};
function projectObject(scene, object,camera) {
if ( object.visible ) {
var webglObjects = _webglObjects[object.id];
if (webglObjects && (object.frustumCulled === false || _frustum.intersectsObject( object ) === true) ) {
for (var i = 0, l = webglObjects.length; i < l; i ++) {
var webglObject = webglObjects[i];
object._modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
_renderList.push(webglObject);
}
}
for (var i = 0, l = object.children.length; i < l; i ++) {
projectObject(scene, object.children[i], camera);
}
}
}
// For the moment just ignore objects that have multiple materials with different animation methods
// Only the first material will be taken into account for deciding which depth material to use
function getObjectMaterial( object ) {
return object.material instanceof THREE.MeshFaceMaterial
? object.material.materials[ 0 ]
: object.material;
};
};