提交 926f1be2 编写于 作者: M Mikael Emtinger

Initial add of lens flare

上级 66f657d8
/**
* @author Mikael Emtinger
*/
THREE.LensFlare = function ( material, size ) {
THREE.Object3D.call( this );
this.positionScreen = new THREE.Vector3();
this.lensFlares = [];
this.customUpdateCallback = undefined;
this.addLensFlare( material, size, 0 );
};
THREE.LensFlare.prototype = new THREE.Object3D();
THREE.LensFlare.prototype.constructor = THREE.LensFlare;
THREE.LensFlare.prototype.supr = THREE.Object3D.prototype;
/*
* Add: adds another flare
*/
THREE.LensFlare.prototype.add = function( material, size, distance ) {
distance = Math.min( distance, Math.max( 0, distance ));
lensFlares.push( { material: material, size: size, distance: distance, position: new THREE.Vector3() } );
}
/*
* Update lens flares update positions on all flares based on the screen position
* Set myLensFlare.customUpdateCallback to alter the flares in your project specific way.
*/
THREE.LensFlare.updateLensFlares = function() {
// todo: update lens halo positions here
}
...@@ -2524,159 +2524,186 @@ THREE.WebGLRenderer = function ( parameters ) { ...@@ -2524,159 +2524,186 @@ THREE.WebGLRenderer = function ( parameters ) {
} }
// render flares
if( scene.__webglLensFlares.length ) {
renderLensFlares( scene, renderTarget );
}
//////////////////////// stencil shadows begin ////////////////////// // render stencil shadows
// method: we're rendering the world in light, then the shadow
// volumes into the stencil and last a big darkening
// quad over the whole thing. This is NOT how you're
// supposed to do stencil shadows but is much faster
//
if( scene.__webglShadowVolumes.length && scene.lights.length ) { if( scene.__webglShadowVolumes.length && scene.lights.length ) {
renderStencilShadows( scene );
}
// Generate mipmap if we're using any kind of mipmap filtering
if ( renderTarget && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) {
updateRenderTargetMipmap( renderTarget );
}
};
/*
* Render lens flares
* Method: renders 9 0xff00ff-colored points scattered over the light source area,
* reads these back and calculates occlusion.
* Then LensFlare.updateLensFlares() is called to re-position and
* update transparency of flares. Then they are rendered.
*
*/
function renderLensFlares() {
}
/*
* Stencil Shadows
* method: we're rendering the world in light, then the shadow
* volumes into the stencil and last a big darkening
* quad over the whole thing. This is not how "you're
* supposed to" do stencil shadows but is much faster
*
*/
function renderStencilShadows( scene ) {
// setup stencil // setup stencil
_gl.enable( _gl.POLYGON_OFFSET_FILL ); _gl.enable( _gl.POLYGON_OFFSET_FILL );
_gl.polygonOffset( 0.1, 1.0 ); _gl.polygonOffset( 0.1, 1.0 );
_gl.enable( _gl.STENCIL_TEST ); _gl.enable( _gl.STENCIL_TEST );
_gl.depthMask( false ); _gl.depthMask( false );
_gl.colorMask( false, false, false, false ); _gl.colorMask( false, false, false, false );
_gl.stencilFunc( _gl.ALWAYS, 1, 0xFF );
_gl.stencilOpSeparate( _gl.BACK, _gl.KEEP, _gl.INCR, _gl.KEEP );
_gl.stencilOpSeparate( _gl.FRONT, _gl.KEEP, _gl.DECR, _gl.KEEP );
_gl.stencilFunc( _gl.ALWAYS, 1, 0xFF );
_gl.stencilOpSeparate( _gl.BACK, _gl.KEEP, _gl.INCR, _gl.KEEP );
_gl.stencilOpSeparate( _gl.FRONT, _gl.KEEP, _gl.DECR, _gl.KEEP );
// loop through all directional lights
var l, ll = scene.lights.length;
var p;
var light, lights = scene.lights, geometryGroup;
var dirLight = [];
var program;
var p_uniforms;
var m_uniforms;
var attributes;
var o, ol = scene.__webglShadowVolumes.length;
for( l = 0; l < ll; l++ ) {
// loop through all directional lights light = scene.lights[ l ];
var l, ll = scene.lights.length;
var p;
var light, geometryGroup;
var dirLight = [];
var program;
var p_uniforms;
var m_uniforms;
var attributes;
ol = scene.__webglShadowVolumes.length;
for( l = 0; l < ll; l++ ) { if( light instanceof THREE.DirectionalLight ) {
dirLight[ 0 ] = -light.position.x;
dirLight[ 1 ] = -light.position.y;
dirLight[ 2 ] = -light.position.z;
light = scene.lights[ l ]; // render all volumes
if( light instanceof THREE.DirectionalLight ) { for( o = 0; o < ol; o++ ) {
object = scene.__webglShadowVolumes[ o ].object;
geometryGroup = scene.__webglShadowVolumes[ o ].buffer;
material = object.materials[ 0 ];
dirLight[ 0 ] = -light.position.x;
dirLight[ 1 ] = -light.position.y;
dirLight[ 2 ] = -light.position.z;
if ( !material.program ) _this.initMaterial( material, lights, undefined, object );
// render all volumes
for ( o = 0; o < ol; o++ ) {
object = scene.__webglShadowVolumes[ o ].object;
geometryGroup = scene.__webglShadowVolumes[ o ].buffer;
material = object.materials[ 0 ];
program = material.program,
p_uniforms = program.uniforms,
m_uniforms = material.uniforms,
attributes = program.attributes;
if ( !material.program ) _this.initMaterial( material, lights, fog, object );
program = material.program,
p_uniforms = program.uniforms,
m_uniforms = material.uniforms,
attributes = program.attributes;
if( _oldProgram !== program ) {
_gl.useProgram( program );
_oldProgram = program;
if( _oldProgram !== program ) { _gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );
_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
_gl.useProgram( program ); _gl.uniform3fv( p_uniforms.directionalLightDirection, dirLight );
_oldProgram = program; }
_gl.uniformMatrix4fv( p_uniforms.projectionMatrix, false, _projectionMatrixArray );
_gl.uniformMatrix4fv( p_uniforms.viewMatrix, false, _viewMatrixArray );
_gl.uniform3fv( p_uniforms.directionalLightDirection, dirLight );
}
object.matrixWorld.flattenToArray( object._objectMatrixArray );
_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray );
object.matrixWorld.flattenToArray( object._objectMatrixArray );
//object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
_gl.uniformMatrix4fv( p_uniforms.objectMatrix, false, object._objectMatrixArray ); _gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer );
//_gl.uniformMatrix4fv( p_uniforms.modelViewMatrix, false, object._modelViewMatrixArray ); _gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLNormalBuffer );
_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLVertexBuffer ); _gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
_gl.vertexAttribPointer( attributes.position, 3, _gl.FLOAT, false, 0, 0 );
_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webGLNormalBuffer ); _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLFaceBuffer );
_gl.vertexAttribPointer( attributes.normal, 3, _gl.FLOAT, false, 0, 0 );
_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryGroup.__webGLFaceBuffer ); _gl.cullFace( _gl.FRONT );
_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );
_gl.cullFace( _gl.FRONT ); _gl.cullFace( _gl.BACK );
_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 ); _gl.drawElements( _gl.TRIANGLES, geometryGroup.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );
_gl.cullFace( _gl.BACK );
_gl.drawElements( _gl.TRIANGLES, geometryGroup.__webGLFaceCount, _gl.UNSIGNED_SHORT, 0 );
}
} }
} }
// draw darkening polygon
_gl.disable( _gl.POLYGON_OFFSET_FILL );
_gl.colorMask( true, true, true, true );
_gl.stencilFunc( _gl.NOTEQUAL, 0, 0xFF );
_gl.stencilOp( _gl.KEEP, _gl.KEEP, _gl.KEEP );
_gl.disable( _gl.DEPTH_TEST );
_gl.enable( _gl.BLEND );
_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
_gl.blendEquation( _gl.FUNC_ADD );
_oldBlending = "";
_oldProgram = _shadow.program;
_gl.useProgram( _shadow.program );
_gl.uniformMatrix4fv( _shadow.projectionLocation, false, _projectionMatrixArray );
_gl.bindBuffer( _gl.ARRAY_BUFFER, _shadow.vertexBuffer );
_gl.vertexAttribPointer( _shadow.vertexLocation, 3, _gl.FLOAT, false, 0, 0 );
_gl.enableVertexAttribArray( _shadow.vertexLocation );
_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _shadow.elementBuffer );
_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
// disable stencil
_gl.disable ( _gl.STENCIL_TEST );
_gl.enable ( _gl.DEPTH_TEST );
_gl.disable ( _gl.BLEND );
_gl.depthMask( true );
} }
// setup color+stencil
//////////////////////// stencil shadows end ////////////////////// _gl.disable( _gl.POLYGON_OFFSET_FILL );
_gl.colorMask( true, true, true, true );
_gl.stencilFunc( _gl.NOTEQUAL, 0, 0xFF );
_gl.stencilOp( _gl.KEEP, _gl.KEEP, _gl.KEEP );
_gl.disable( _gl.DEPTH_TEST );
// Generate mipmap if we're using any kind of mipmap filtering // draw darkening polygon
if ( renderTarget && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) { _oldBlending = "";
_oldProgram = _shadow.program;
updateRenderTargetMipmap( renderTarget ); _gl.useProgram( _shadow.program );
_gl.uniformMatrix4fv( _shadow.projectionLocation, false, _projectionMatrixArray );
_gl.bindBuffer( _gl.ARRAY_BUFFER, _shadow.vertexBuffer );
_gl.vertexAttribPointer( _shadow.vertexLocation, 3, _gl.FLOAT, false, 0, 0 );
_gl.enableVertexAttribArray( _shadow.vertexLocation );
} _gl.enable( _gl.BLEND );
_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
_gl.blendEquation( _gl.FUNC_ADD );
_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _shadow.elementBuffer );
_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
// disable stencil
_gl.disable ( _gl.STENCIL_TEST );
_gl.enable ( _gl.DEPTH_TEST );
_gl.disable ( _gl.BLEND );
_gl.depthMask( true );
}
};
function setupMatrices ( object, camera ) { function setupMatrices ( object, camera ) {
...@@ -2692,6 +2719,7 @@ THREE.WebGLRenderer = function ( parameters ) { ...@@ -2692,6 +2719,7 @@ THREE.WebGLRenderer = function ( parameters ) {
scene.__webglObjects = []; scene.__webglObjects = [];
scene.__webglObjectsImmediate = []; scene.__webglObjectsImmediate = [];
scene.__webglShadowVolumes = []; scene.__webglShadowVolumes = [];
scene.__webglLensFlares = [];
} }
while ( scene.__objectsAdded.length ) { while ( scene.__objectsAdded.length ) {
...@@ -2722,6 +2750,11 @@ THREE.WebGLRenderer = function ( parameters ) { ...@@ -2722,6 +2750,11 @@ THREE.WebGLRenderer = function ( parameters ) {
} }
for ( var o = 0, ol = scene.__webglLensFlares.length; o < ol; o ++ ) {
updateObject( scene.__webglLensFlares[ o ].object, scene );
}
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册