提交 615f8720 编写于 作者: M Mikael Emtinger

Added sprite support. See Sprite.js for details. No support for custom shader at this point.

上级 5ef9e045
因为 它太大了无法显示 source diff 。你可以改为 查看blob
/*
* Sprite
*/
THREE.Sprite = function( parameters ) {
THREE.Object3D.call( this );
if( parameters.material !== undefined ) {
this.material = parameters.material;
this.map = undefined;
this.blending = material.blending;
} else if( parameters.map !== undefined ) {
this.map = parameters.map instanceof THREE.Texture ? parameters.map : ImageUtils.loadTexture( parameters.map );
this.material = undefined;
this.blending = parameters.blending !== undefined ? parameters.blending : THREE.NormalBlending;
}
this.useScreenCoordinates = parameters.useScreenCoordinates !== undefined ? parameters.useScreenCoordinates : true;
this.mergeWith3D = parameters.mergeWith3D !== undefined ? parameters.mergeWith3D : false;
this.affectedByDistance = parameters.affectedByDistance !== undefined ? parameters.affectedByDistance : !parameters.useScreenCoordinates;
this.alignment = parameters.alignment instanceof THREE.Vector2 ? parameters.alignment : THREE.SpriteAlignment.center;
this.rotation3d = this.rotation;
this.rotation = 0;
this.opacity = 1;
this.uvOffset = new THREE.Vector2( 0, 0 );
this.uvScale = new THREE.Vector2( 1, 1 );
}
THREE.Sprite.prototype = new THREE.Object3D();
THREE.Sprite.prototype.constructor = THREE.ShadowVolume;
THREE.Sprite.prototype.supr = THREE.Object3D.prototype;
/*
* Custom update matrix
*/
THREE.Sprite.prototype.updateMatrix = function () {
this.matrix.setPosition( this.position );
this.rotation3d.set( 0, 0, this.rotation );
this.matrix.setRotationFromEuler( this.rotation3d );
if ( this.scale.x !== 1 || this.scale.y !== 1 ) {
this.scale3d.set( this.scale.x, this.scale.y, 1 );
this.matrix.scale( this.scale3d );
this.boundRadiusScale = Math.max( this.scale.x, this.scale.y );
}
this.matrixWorldNeedsUpdate = true;
};
/*
* Alignment
*/
THREE.SpriteAlignment = {};
THREE.SpriteAlignment.topLeft = new THREE.Vector2( 1, -1 );
THREE.SpriteAlignment.topCenter = new THREE.Vector2( 0, -1 );
THREE.SpriteAlignment.topRight = new THREE.Vector2( -1, -1 );
THREE.SpriteAlignment.centerLeft = new THREE.Vector2( 1, 0 );
THREE.SpriteAlignment.center = new THREE.Vector2( 0, 0 );
THREE.SpriteAlignment.centerRight = new THREE.Vector2( -1, 0 );
THREE.SpriteAlignment.bottomLeft = new THREE.Vector2( 1, 1 );
THREE.SpriteAlignment.bottomCenter = new THREE.Vector2( 0, 1 );
THREE.SpriteAlignment.bottomRight = new THREE.Vector2( -1, 1 );
......@@ -254,16 +254,20 @@ THREE.WebGLRenderer = function ( parameters ) {
_sprite.attributes = {};
_sprite.uniforms = {};
_sprite.attributes.vertex = _gl.getAttribLocation ( _sprite.program, "position" );
_sprite.attributes.uv = _gl.getAttribLocation ( _sprite.program, "UV" );
_sprite.uniforms.map = _gl.getUniformLocation( _sprite.program, "map" );
_sprite.uniforms.opacity = _gl.getUniformLocation( _sprite.program, "opacity" );
_sprite.uniforms.scale = _gl.getUniformLocation( _sprite.program, "scale" );
_sprite.uniforms.rotation = _gl.getUniformLocation( _sprite.program, "rotation" );
_sprite.uniforms.screenPosition = _gl.getUniformLocation( _sprite.program, "screenPosition" );
_sprite.attributes.position = _gl.getAttribLocation ( _sprite.program, "position" );
_sprite.attributes.uv = _gl.getAttribLocation ( _sprite.program, "uv" );
_sprite.uniforms.uvOffset = _gl.getUniformLocation( _sprite.program, "uvOffset" );
_sprite.uniforms.uvScale = _gl.getUniformLocation( _sprite.program, "uvScale" );
_sprite.uniforms.rotation = _gl.getUniformLocation( _sprite.program, "rotation" );
_sprite.uniforms.scale = _gl.getUniformLocation( _sprite.program, "scale" );
_sprite.uniforms.alignment = _gl.getUniformLocation( _sprite.program, "alignment" );
_sprite.uniforms.map = _gl.getUniformLocation( _sprite.program, "map" );
_sprite.uniforms.opacity = _gl.getUniformLocation( _sprite.program, "opacity" );
_sprite.uniforms.useScreenCoordinates = _gl.getUniformLocation( _sprite.program, "useScreenCoordinates" );
_sprite.uniforms.affectedByDistance = _gl.getUniformLocation( _sprite.program, "affectedByDistance" );
_sprite.uniforms.screenPosition = _gl.getUniformLocation( _sprite.program, "screenPosition" );
_sprite.uniforms.modelViewMatrix = _gl.getUniformLocation( _sprite.program, "modelViewMatrix" );
_sprite.uniforms.projectionMatrix = _gl.getUniformLocation( _sprite.program, "projectionMatrix" );
......@@ -3125,12 +3129,11 @@ THREE.WebGLRenderer = function ( parameters ) {
}
}
// render 2d
if ( scene.__webglSprites.length ) {
renderSprites( scene );
renderSprites( scene, camera );
}
......@@ -3142,6 +3145,7 @@ THREE.WebGLRenderer = function ( parameters ) {
}
// render lens flares
if ( scene.__webglLensFlares.length ) {
......@@ -3300,6 +3304,130 @@ THREE.WebGLRenderer = function ( parameters ) {
}
/*
* Render sprites
*
*/
function renderSprites( scene, camera ) {
var o, ol, object;
var attributes = _sprite.attributes;
var uniforms = _sprite.uniforms;
var anyCustom = false;
var invAspect = _viewportHeight / _viewportWidth;
var size, scale = [];
var screenPosition;
var halfViewportWidth = _viewportWidth * 0.5;
var halfViewportHeight = _viewportHeight * 0.5;
var mergeWith3D = true;
// setup gl
_gl.useProgram( _sprite.program );
_currentProgram = _sprite.program;
_oldBlending = "";
_gl.disable( _gl.CULL_FACE );
_gl.bindBuffer( _gl.ARRAY_BUFFER, _sprite.vertexBuffer );
_gl.vertexAttribPointer( attributes.position, 2, _gl.FLOAT, false, 2 * 8, 0 );
_gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 2 * 8, 8 );
_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _sprite.elementBuffer );
_gl.uniformMatrix4fv( uniforms.projectionMatrix, false, _projectionMatrixArray );
_gl.activeTexture( _gl.TEXTURE0 );
_gl.uniform1i( uniforms.map, 0 );
_gl.depthMask( false );
// render all non-custom shader sprites
for( o = 0, ol = scene.__webglSprites.length; o < ol; o++ ) {
object = scene.__webglSprites[ o ];
if( object.material === undefined ) {
if( object.map && object.map.image && object.map.image.width ) {
if( object.useScreenCoordinates ) {
_gl.uniform1i( uniforms.useScreenCoordinates, 1 );
_gl.uniform3f( uniforms.screenPosition, ( object.position.x - halfViewportWidth ) / halfViewportWidth,
( halfViewportHeight - object.position.y ) / halfViewportHeight,
object.position.z );
} else {
object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
_gl.uniform1i( uniforms.useScreenCoordinates, 0 );
_gl.uniform1i( uniforms.affectedByDistance, object.affectedByDistance ? 1 : 0 );
_gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, object._modelViewMatrixArray );
}
size = object.map.image.width / ( object.affectedByDistance ? 1 : _viewportHeight );
scale[ 0 ] = size * invAspect;
scale[ 1 ] = size;
_gl.uniform2f( uniforms.uvScale, object.uvScale.x, object.uvScale.y );
_gl.uniform2f( uniforms.uvOffset, object.uvOffset.x, object.uvOffset.y );
_gl.uniform2f( uniforms.alignment, object.alignment.x, object.alignment.y );
_gl.uniform1f( uniforms.opacity, object.opacity );
_gl.uniform1f( uniforms.rotation, object.rotation );
_gl.uniform2fv( uniforms.scale, scale );
if( object.mergeWith3D && !mergeWith3D ) {
_gl.enable( _gl.DEPTH_TEST );
mergeWith3D = true;
} else if( !object.mergeWith3D && mergeWith3D ) {
_gl.disable( _gl.DEPTH_TEST );
mergeWith3D = false;
}
setBlending( object.blending );
setTexture( object.map, 0 );
_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
}
} else {
anyCustom = true;
}
}
// loop through all custom
/* if( anyCustom ) {
}
*/
// restore gl
_gl.enable( _gl.CULL_FACE );
_gl.enable( _gl.DEPTH_TEST );
_gl.depthMask( _currentDepthMask );
}
/*
* Render lens flares
* Method: renders 16x16 0xff00ff-colored points scattered over the light source area,
......@@ -3383,16 +3511,18 @@ THREE.WebGLRenderer = function ( parameters ) {
// screen cull
if( screenPositionPixels[ 0 ] > 0 &&
if( _lensFlare.hasVertexTexture ||
( screenPositionPixels[ 0 ] > 0 &&
screenPositionPixels[ 0 ] < _viewportWidth &&
screenPositionPixels[ 1 ] > 0 &&
screenPositionPixels[ 1 ] < _viewportHeight ) {
screenPositionPixels[ 1 ] < _viewportHeight )) {
// save current RGB to temp texture
_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
_gl.copyTexSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, screenPositionPixels[ 0 ] - 8, screenPositionPixels[ 1 ] - 8, 16, 16 );
//_gl.copyTexSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, screenPositionPixels[ 0 ] - 8, screenPositionPixels[ 1 ] - 8, 16, 16 );
_gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGB, screenPositionPixels[ 0 ] - 8, screenPositionPixels[ 1 ] - 8, 16, 16, 0 );
// render pink quad
......@@ -3410,7 +3540,8 @@ THREE.WebGLRenderer = function ( parameters ) {
// copy result to occlusionMap
_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );
_gl.copyTexSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, screenPositionPixels[ 0 ] - 8, screenPositionPixels[ 1 ] - 8, 16, 16 );
//_gl.copyTexSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, screenPositionPixels[ 0 ] - 8, screenPositionPixels[ 1 ] - 8, 16, 16 );
_gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, screenPositionPixels[ 0 ] - 8, screenPositionPixels[ 1 ] - 8, 16, 16, 0 );
// restore graphics
......@@ -3665,7 +3796,13 @@ THREE.WebGLRenderer = function ( parameters ) {
addBufferImmediate( scene.__webglObjectsImmediate, object );
}/*else if ( object instanceof THREE.Particle ) {
} else if ( object instanceof THREE.Sprite ) {
scene.__webglSprites.push( object );
}
/*else if ( object instanceof THREE.Particle ) {
}*/
......@@ -3775,10 +3912,13 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( object == zobject ) {
scene.__webglObjects.splice( o, 1 );
return;
}
}
// add shadwos/sprites etc.
};
......
......@@ -602,13 +602,13 @@ THREE.ShaderLib = {
"texture2D( occlusionMap, vec2( 0.1, 0.9 )) +",
"texture2D( occlusionMap, vec2( 0.1, 0.5 )) +",
"texture2D( occlusionMap, vec2( 0.5, 0.5 ));",
/*
"vVisibility = ( visibility.r / 9.0 ) *",
"( 1.0 - visibility.g / 9.0 ) *",
"( visibility.b / 9.0 ) *",
"( 1.0 - visibility.a / 9.0 );",
*/
"vVisibility = ( 1.0 - visibility.a / 9.0 );",
// "vVisibility = ( 1.0 - visibility.a / 9.0 );",
"pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;",
"pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;",
......@@ -638,7 +638,8 @@ THREE.ShaderLib = {
"if( renderType == 0 ) {",
"gl_FragColor = vec4( texture2D( map, vUV ).rgb, 0.0 );",
// "gl_FragColor = vec4( texture2D( map, vUV ).rgb, 0.0 );",
"gl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );",
// restore
......@@ -741,25 +742,46 @@ THREE.ShaderLib = {
'sprite': {
vertexShader: [
"uniform vec3 screenPosition;",
"uniform vec2 scale;",
"uniform float rotation;",
"uniform int useScreenCoordinates;",
"uniform int affectedByDistance;",
"uniform vec3 screenPosition;",
"uniform mat4 modelViewMatrix;",
"uniform mat4 projectionMatrix;",
"uniform float rotation;",
"uniform vec2 scale;",
"uniform vec2 alignment;",
"uniform vec2 uvOffset;",
"uniform vec2 uvScale;",
"attribute vec2 position;",
"attribute vec2 UV;",
"attribute vec2 uv;",
"varying vec2 vUV;",
"void main(void)",
"{",
"vUV = UV;",
"vUV = uvOffset + uv * uvScale;",
"vec2 pos;",
"pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;",
"pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;",
"vec2 alignedPosition = position + alignment;",
"vec2 rotatedPosition;",
"rotatedPosition.x = ( cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y ) * scale.x;",
"rotatedPosition.y = ( sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y ) * scale.y;",
"vec4 finalPosition;",
"gl_Position = vec4(( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );",
"if( useScreenCoordinates != 0 ) {",
"finalPosition = vec4( screenPosition.xy + rotatedPosition, screenPosition.z, 1.0 );",
"} else {",
"finalPosition = projectionMatrix * modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );",
"finalPosition.xy += rotatedPosition * ( affectedByDistance == 1 ? 1.0 : finalPosition.z );",
"}",
"gl_Position = finalPosition;",
"}"
].join( "\n" ),
......@@ -780,6 +802,7 @@ THREE.ShaderLib = {
"vec4 color = texture2D( map, vUV );",
"color.a *= opacity;",
"gl_FragColor = color;",
// "gl_FragColor = vec4( 1.0, 0.0, 1.0, 1.0 );",
"}"
].join( "\n" )
......
......@@ -64,6 +64,7 @@ COMMON_FILES = [
'objects/Sound.js',
'objects/LOD.js',
'objects/ShadowVolume.js',
'objects/Sprite.js',
'scenes/Scene.js',
'scenes/Fog.js',
'scenes/FogExp2.js',
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册