提交 982ce5ba 编写于 作者: A alteredq

Added forgotten file.

上级 ebf93289
/**
* @author mikael emtinger / http://gomo.se/
* @author alteredq / http://alteredqualia.com/
*/
THREE.LensFlarePlugin = function ( ) {
var _gl, _renderer, _lensFlare = {};
this.init = function ( renderer ) {
_gl = renderer.context;
_renderer = renderer;
_lensFlare.vertices = new Float32Array( 8 + 8 );
_lensFlare.faces = new Uint16Array( 6 );
var i = 0;
_lensFlare.vertices[ i++ ] = -1; _lensFlare.vertices[ i++ ] = -1; // vertex
_lensFlare.vertices[ i++ ] = 0; _lensFlare.vertices[ i++ ] = 0; // uv... etc.
_lensFlare.vertices[ i++ ] = 1; _lensFlare.vertices[ i++ ] = -1;
_lensFlare.vertices[ i++ ] = 1; _lensFlare.vertices[ i++ ] = 0;
_lensFlare.vertices[ i++ ] = 1; _lensFlare.vertices[ i++ ] = 1;
_lensFlare.vertices[ i++ ] = 1; _lensFlare.vertices[ i++ ] = 1;
_lensFlare.vertices[ i++ ] = -1; _lensFlare.vertices[ i++ ] = 1;
_lensFlare.vertices[ i++ ] = 0; _lensFlare.vertices[ i++ ] = 1;
i = 0;
_lensFlare.faces[ i++ ] = 0; _lensFlare.faces[ i++ ] = 1; _lensFlare.faces[ i++ ] = 2;
_lensFlare.faces[ i++ ] = 0; _lensFlare.faces[ i++ ] = 2; _lensFlare.faces[ i++ ] = 3;
// buffers
_lensFlare.vertexBuffer = _gl.createBuffer();
_lensFlare.elementBuffer = _gl.createBuffer();
_gl.bindBuffer( _gl.ARRAY_BUFFER, _lensFlare.vertexBuffer );
_gl.bufferData( _gl.ARRAY_BUFFER, _lensFlare.vertices, _gl.STATIC_DRAW );
_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.elementBuffer );
_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.faces, _gl.STATIC_DRAW );
// textures
_lensFlare.tempTexture = _gl.createTexture();
_lensFlare.occlusionTexture = _gl.createTexture();
_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
_gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGB, 16, 16, 0, _gl.RGB, _gl.UNSIGNED_BYTE, null );
_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, _gl.NEAREST );
_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.NEAREST );
_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );
_gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, 16, 16, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, null );
_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, _gl.NEAREST );
_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.NEAREST );
if ( _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ) <= 0 ) {
_lensFlare.hasVertexTexture = false;
_lensFlare.program = createProgram( THREE.ShaderFlares[ "lensFlare" ] );
} else {
_lensFlare.hasVertexTexture = true;
_lensFlare.program = createProgram( THREE.ShaderFlares[ "lensFlareVertexTexture" ] );
}
_lensFlare.attributes = {};
_lensFlare.uniforms = {};
_lensFlare.attributes.vertex = _gl.getAttribLocation ( _lensFlare.program, "position" );
_lensFlare.attributes.uv = _gl.getAttribLocation ( _lensFlare.program, "uv" );
_lensFlare.uniforms.renderType = _gl.getUniformLocation( _lensFlare.program, "renderType" );
_lensFlare.uniforms.map = _gl.getUniformLocation( _lensFlare.program, "map" );
_lensFlare.uniforms.occlusionMap = _gl.getUniformLocation( _lensFlare.program, "occlusionMap" );
_lensFlare.uniforms.opacity = _gl.getUniformLocation( _lensFlare.program, "opacity" );
_lensFlare.uniforms.color = _gl.getUniformLocation( _lensFlare.program, "color" );
_lensFlare.uniforms.scale = _gl.getUniformLocation( _lensFlare.program, "scale" );
_lensFlare.uniforms.rotation = _gl.getUniformLocation( _lensFlare.program, "rotation" );
_lensFlare.uniforms.screenPosition = _gl.getUniformLocation( _lensFlare.program, "screenPosition" );
_lensFlare.attributesEnabled = false;
};
/*
* Render lens flares
* Method: renders 16x16 0xff00ff-colored points scattered over the light source area,
* reads these back and calculates occlusion.
* Then _lensFlare.update_lensFlares() is called to re-position and
* update transparency of flares. Then they are rendered.
*
*/
this.render = function ( scene, camera, viewportWidth, viewportHeight ) {
var _flaresList = scene.__webglFlares;
var object;
var o, ol = _flaresList.length;
var f, fl, flare;
var tempPosition = new THREE.Vector3();
var invAspect = viewportHeight / viewportWidth;
var halfViewportWidth = viewportWidth * 0.5;
var halfViewportHeight = viewportHeight * 0.5;
var size = 16 / viewportHeight;
var scale = new THREE.Vector2( size * invAspect, size );
var screenPosition = new THREE.Vector3( 1, 1, 0 );
var screenPositionPixels = new THREE.Vector2( 1, 1 );
var uniforms = _lensFlare.uniforms;
var attributes = _lensFlare.attributes;
// set _lensFlare program and reset blending
_gl.useProgram( _lensFlare.program );
if ( ! _lensFlare.attributesEnabled ) {
_gl.enableVertexAttribArray( _lensFlare.attributes.vertex );
_gl.enableVertexAttribArray( _lensFlare.attributes.uv );
_lensFlare.attributesEnabled = true;
}
// loop through all lens flares to update their occlusion and positions
// setup gl and common used attribs/unforms
_gl.uniform1i( uniforms.occlusionMap, 0 );
_gl.uniform1i( uniforms.map, 1 );
_gl.bindBuffer( _gl.ARRAY_BUFFER, _lensFlare.vertexBuffer );
_gl.vertexAttribPointer( attributes.vertex, 2, _gl.FLOAT, false, 2 * 8, 0 );
_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 2 * 8, 8 );
_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.elementBuffer );
_gl.disable( _gl.CULL_FACE );
_gl.depthMask( false );
for ( o = 0; o < ol; o ++ ) {
size = 16 / viewportHeight;
scale.set( size * invAspect, size );
// calc object screen position
object = _flaresList[ o ];
tempPosition.set( object.matrixWorld.n14, object.matrixWorld.n24, object.matrixWorld.n34 );
camera.matrixWorldInverse.multiplyVector3( tempPosition );
camera.projectionMatrix.multiplyVector3( tempPosition );
// setup arrays for gl programs
screenPosition.copy( tempPosition )
screenPositionPixels.x = screenPosition.x * halfViewportWidth + halfViewportWidth;
screenPositionPixels.y = screenPosition.y * halfViewportHeight + halfViewportHeight;
// screen cull
if ( _lensFlare.hasVertexTexture || (
screenPositionPixels.x > 0 &&
screenPositionPixels.x < viewportWidth &&
screenPositionPixels.y > 0 &&
screenPositionPixels.y < viewportHeight ) ) {
// save current RGB to temp texture
_gl.activeTexture( _gl.TEXTURE1 );
_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
_gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGB, screenPositionPixels.x - 8, screenPositionPixels.y - 8, 16, 16, 0 );
// render pink quad
_gl.uniform1i( uniforms.renderType, 0 );
_gl.uniform2f( uniforms.scale, scale.x, scale.y );
_gl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );
_gl.disable( _gl.BLEND );
_gl.enable( _gl.DEPTH_TEST );
_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
// copy result to occlusionMap
_gl.activeTexture( _gl.TEXTURE0 );
_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );
_gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, screenPositionPixels.x - 8, screenPositionPixels.y - 8, 16, 16, 0 );
// restore graphics
_gl.uniform1i( uniforms.renderType, 1 );
_gl.disable( _gl.DEPTH_TEST );
_gl.activeTexture( _gl.TEXTURE1 );
_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
// update object positions
object.positionScreen.copy( screenPosition )
if ( object.customUpdateCallback ) {
object.customUpdateCallback( object );
} else {
object.updateLensFlares();
}
// render flares
_gl.uniform1i( uniforms.renderType, 2 );
_gl.enable( _gl.BLEND );
for ( f = 0, fl = object.lensFlares.length; f < fl; f ++ ) {
flare = object.lensFlares[ f ];
if ( flare.opacity > 0.001 && flare.scale > 0.001 ) {
screenPosition.x = flare.x;
screenPosition.y = flare.y;
screenPosition.z = flare.z;
size = flare.size * flare.scale / viewportHeight;
scale.x = size * invAspect;
scale.y = size;
_gl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );
_gl.uniform2f( uniforms.scale, scale.x, scale.y );
_gl.uniform1f( uniforms.rotation, flare.rotation );
_gl.uniform1f( uniforms.opacity, flare.opacity );
_gl.uniform3f( uniforms.color, flare.color.r, flare.color.g, flare.color.b );
_renderer.setBlending( flare.blending );
_renderer.setTexture( flare.texture, 1 );
_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
}
}
}
}
// restore gl
_gl.enable( _gl.CULL_FACE );
_gl.enable( _gl.DEPTH_TEST );
_gl.depthMask( true );
};
function createProgram ( shader ) {
var program = _gl.createProgram();
var fragmentShader = _gl.createShader( _gl.FRAGMENT_SHADER );
var vertexShader = _gl.createShader( _gl.VERTEX_SHADER );
_gl.shaderSource( fragmentShader, shader.fragmentShader );
_gl.shaderSource( vertexShader, shader.vertexShader );
_gl.compileShader( fragmentShader );
_gl.compileShader( vertexShader );
_gl.attachShader( program, fragmentShader );
_gl.attachShader( program, vertexShader );
_gl.linkProgram( program );
return program;
};
};
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册