Browse Source

Added support for alphaTest to Sprites.

alteredq 12 years ago
parent
commit
73922dc797

+ 10 - 0
build/three.js

@@ -11612,6 +11612,8 @@ THREE.Sprite = function ( parameters ) {
 	this.uvOffset = new THREE.Vector2( 0, 0 );
 	this.uvScale  = new THREE.Vector2( 1, 1 );
 
+	this.alphaTest = 0;
+
 };
 
 THREE.Sprite.prototype = Object.create( THREE.Object3D.prototype );
@@ -34517,6 +34519,8 @@ THREE.SpritePlugin = function ( ) {
 		_sprite.uniforms.fogFar 		  	  = _gl.getUniformLocation( _sprite.program, "fogFar" );
 		_sprite.uniforms.fogColor 		  	  = _gl.getUniformLocation( _sprite.program, "fogColor" );
 
+		_sprite.uniforms.alphaTest 		  	  = _gl.getUniformLocation( _sprite.program, "alphaTest" );
+
 	};
 
 	this.render = function ( scene, camera, viewportWidth, viewportHeight ) {
@@ -34629,6 +34633,8 @@ THREE.SpritePlugin = function ( ) {
 
 			if ( sprite.map && sprite.map.image && sprite.map.image.width ) {
 
+				_gl.uniform1f( uniforms.alphaTest, sprite.alphaTest );
+
 				if ( sprite.useScreenCoordinates ) {
 
 					_gl.uniform1i( uniforms.useScreenCoordinates, 1 );
@@ -35205,12 +35211,16 @@ THREE.ShaderSprite = {
 			"uniform float fogDensity;",
 			"uniform float fogNear;",
 			"uniform float fogFar;",
+			"uniform float alphaTest;",
 
 			"varying vec2 vUV;",
 
 			"void main() {",
 
 				"vec4 texture = texture2D( map, vUV );",
+
+				"if ( texture.a < alphaTest ) discard;",
+
 				"gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );",
 
 				"if ( fogType > 0 ) {",

+ 13 - 13
build/three.min.js

@@ -259,7 +259,7 @@ THREE.LOD.prototype.update=function(a){if(1<this.LODs.length){a.matrixWorldInver
 !1}};THREE.LOD.prototype.clone=function(){};
 THREE.Sprite=function(a){THREE.Object3D.call(this);a=a||{};this.color=void 0!==a.color?new THREE.Color(a.color):new THREE.Color(16777215);this.map=void 0!==a.map?a.map:new THREE.Texture;this.blending=void 0!==a.blending?a.blending:THREE.NormalBlending;this.blendSrc=void 0!==a.blendSrc?a.blendSrc:THREE.SrcAlphaFactor;this.blendDst=void 0!==a.blendDst?a.blendDst:THREE.OneMinusSrcAlphaFactor;this.blendEquation=void 0!==a.blendEquation?a.blendEquation:THREE.AddEquation;this.useScreenCoordinates=void 0!==
 a.useScreenCoordinates?a.useScreenCoordinates:!0;this.mergeWith3D=void 0!==a.mergeWith3D?a.mergeWith3D:!this.useScreenCoordinates;this.affectedByDistance=void 0!==a.affectedByDistance?a.affectedByDistance:!this.useScreenCoordinates;this.scaleByViewport=void 0!==a.scaleByViewport?a.scaleByViewport:!this.affectedByDistance;this.alignment=a.alignment instanceof THREE.Vector2?a.alignment:THREE.SpriteAlignment.center.clone();this.fog=void 0!==a.fog?a.fog:!1;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=Object.create(THREE.Object3D.prototype);THREE.Sprite.prototype.updateMatrix=function(){this.matrix.setPosition(this.position);this.rotation3d.set(0,0,this.rotation);this.matrix.setRotationFromEuler(this.rotation3d);if(1!==this.scale.x||1!==this.scale.y)this.matrix.scale(this.scale),this.boundRadiusScale=Math.max(this.scale.x,this.scale.y);this.matrixWorldNeedsUpdate=!0};
+0;this.opacity=1;this.uvOffset=new THREE.Vector2(0,0);this.uvScale=new THREE.Vector2(1,1);this.alphaTest=0};THREE.Sprite.prototype=Object.create(THREE.Object3D.prototype);THREE.Sprite.prototype.updateMatrix=function(){this.matrix.setPosition(this.position);this.rotation3d.set(0,0,this.rotation);this.matrix.setRotationFromEuler(this.rotation3d);if(1!==this.scale.x||1!==this.scale.y)this.matrix.scale(this.scale),this.boundRadiusScale=Math.max(this.scale.x,this.scale.y);this.matrixWorldNeedsUpdate=!0};
 THREE.Sprite.prototype.clone=function(a){void 0===a&&(a=new THREE.Sprite({}));a.color.copy(this.color);a.map=this.map;a.blending=this.blending;a.useScreenCoordinates=this.useScreenCoordinates;a.mergeWith3D=this.mergeWith3D;a.affectedByDistance=this.affectedByDistance;a.scaleByViewport=this.scaleByViewport;a.alignment=this.alignment;a.fog=this.fog;a.rotation3d.copy(this.rotation3d);a.rotation=this.rotation;a.opacity=this.opacity;a.uvOffset.copy(this.uvOffset);a.uvScale.copy(this.uvScale);THREE.Object3D.prototype.clone.call(this,
 a);return a};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);THREE.Scene=function(){THREE.Object3D.call(this);this.overrideMaterial=this.fog=null;this.matrixAutoUpdate=!1;this.__objects=[];this.__lights=[];this.__objectsAdded=[];this.__objectsRemoved=[]};THREE.Scene.prototype=Object.create(THREE.Object3D.prototype);
@@ -751,18 +751,18 @@ l.__lights,null,w,C,r));s=l.__webglObjectsImmediate;p=0;for(q=s.length;p<q;p++)C
 THREE.SpritePlugin=function(){function a(a,b){return a.z!==b.z?b.z-a.z:b.id-a.id}var b,c,d,e,f,g,h,i,j;this.init=function(a){b=a.context;c=a;d=new Float32Array(16);e=new Uint16Array(6);a=0;d[a++]=-1;d[a++]=-1;d[a++]=0;d[a++]=0;d[a++]=1;d[a++]=-1;d[a++]=1;d[a++]=0;d[a++]=1;d[a++]=1;d[a++]=1;d[a++]=1;d[a++]=-1;d[a++]=1;d[a++]=0;d[a++]=1;a=0;e[a++]=0;e[a++]=1;e[a++]=2;e[a++]=0;e[a++]=2;e[a++]=3;f=b.createBuffer();g=b.createBuffer();b.bindBuffer(b.ARRAY_BUFFER,f);b.bufferData(b.ARRAY_BUFFER,d,b.STATIC_DRAW);
 b.bindBuffer(b.ELEMENT_ARRAY_BUFFER,g);b.bufferData(b.ELEMENT_ARRAY_BUFFER,e,b.STATIC_DRAW);var a=THREE.ShaderSprite.sprite,m=b.createProgram(),n=b.createShader(b.FRAGMENT_SHADER),o=b.createShader(b.VERTEX_SHADER);b.shaderSource(n,a.fragmentShader);b.shaderSource(o,a.vertexShader);b.compileShader(n);b.compileShader(o);b.attachShader(m,n);b.attachShader(m,o);b.linkProgram(m);h=m;i={};j={};i.position=b.getAttribLocation(h,"position");i.uv=b.getAttribLocation(h,"uv");j.uvOffset=b.getUniformLocation(h,
 "uvOffset");j.uvScale=b.getUniformLocation(h,"uvScale");j.rotation=b.getUniformLocation(h,"rotation");j.scale=b.getUniformLocation(h,"scale");j.alignment=b.getUniformLocation(h,"alignment");j.color=b.getUniformLocation(h,"color");j.map=b.getUniformLocation(h,"map");j.opacity=b.getUniformLocation(h,"opacity");j.useScreenCoordinates=b.getUniformLocation(h,"useScreenCoordinates");j.affectedByDistance=b.getUniformLocation(h,"affectedByDistance");j.screenPosition=b.getUniformLocation(h,"screenPosition");
-j.modelViewMatrix=b.getUniformLocation(h,"modelViewMatrix");j.projectionMatrix=b.getUniformLocation(h,"projectionMatrix");j.fogType=b.getUniformLocation(h,"fogType");j.fogDensity=b.getUniformLocation(h,"fogDensity");j.fogNear=b.getUniformLocation(h,"fogNear");j.fogFar=b.getUniformLocation(h,"fogFar");j.fogColor=b.getUniformLocation(h,"fogColor")};this.render=function(d,e,n,o){var p=d.__webglSprites,q=p.length;if(q){var t=i,r=j,C=o/n,n=0.5*n,w=0.5*o,s=!0;b.useProgram(h);b.enableVertexAttribArray(t.position);
-b.enableVertexAttribArray(t.uv);b.disable(b.CULL_FACE);b.enable(b.BLEND);b.depthMask(!0);b.bindBuffer(b.ARRAY_BUFFER,f);b.vertexAttribPointer(t.position,2,b.FLOAT,!1,16,0);b.vertexAttribPointer(t.uv,2,b.FLOAT,!1,16,8);b.bindBuffer(b.ELEMENT_ARRAY_BUFFER,g);b.uniformMatrix4fv(r.projectionMatrix,!1,e._projectionMatrixArray);b.activeTexture(b.TEXTURE0);b.uniform1i(r.map,0);var H=t=0,z=d.fog;z?(b.uniform3f(r.fogColor,z.color.r,z.color.g,z.color.b),z instanceof THREE.Fog?(b.uniform1f(r.fogNear,z.near),
-b.uniform1f(r.fogFar,z.far),b.uniform1i(r.fogType,1),H=t=1):z instanceof THREE.FogExp2&&(b.uniform1f(r.fogDensity,z.density),b.uniform1i(r.fogType,2),H=t=2)):(b.uniform1i(r.fogType,0),H=t=0);for(var u,y=[],z=0;z<q;z++)u=p[z],u.visible&&0!==u.opacity&&(u.useScreenCoordinates?u.z=-u.position.z:(u._modelViewMatrix.multiply(e.matrixWorldInverse,u.matrixWorld),u.z=-u._modelViewMatrix.elements[14]));p.sort(a);for(z=0;z<q;z++)if(u=p[z],u.visible&&0!==u.opacity&&u.map&&u.map.image&&u.map.image.width)u.useScreenCoordinates?
-(b.uniform1i(r.useScreenCoordinates,1),b.uniform3f(r.screenPosition,(u.position.x-n)/n,(w-u.position.y)/w,Math.max(0,Math.min(1,u.position.z)))):(b.uniform1i(r.useScreenCoordinates,0),b.uniform1i(r.affectedByDistance,u.affectedByDistance?1:0),b.uniformMatrix4fv(r.modelViewMatrix,!1,u._modelViewMatrix.elements)),e=d.fog&&u.fog?H:0,t!==e&&(b.uniform1i(r.fogType,e),t=e),e=1/(u.scaleByViewport?o:1),y[0]=e*C*u.scale.x,y[1]=e*u.scale.y,b.uniform2f(r.uvScale,u.uvScale.x,u.uvScale.y),b.uniform2f(r.uvOffset,
-u.uvOffset.x,u.uvOffset.y),b.uniform2f(r.alignment,u.alignment.x,u.alignment.y),b.uniform1f(r.opacity,u.opacity),b.uniform3f(r.color,u.color.r,u.color.g,u.color.b),b.uniform1f(r.rotation,u.rotation),b.uniform2fv(r.scale,y),u.mergeWith3D&&!s?(b.enable(b.DEPTH_TEST),s=!0):!u.mergeWith3D&&s&&(b.disable(b.DEPTH_TEST),s=!1),c.setBlending(u.blending,u.blendEquation,u.blendSrc,u.blendDst),c.setTexture(u.map,0),b.drawElements(b.TRIANGLES,6,b.UNSIGNED_SHORT,0);b.enable(b.CULL_FACE);b.enable(b.DEPTH_TEST);
-b.depthMask(!0)}}};
-THREE.DepthPassPlugin=function(){this.enabled=!1;this.renderTarget=null;var a,b,c,d,e,f,g=new THREE.Frustum,h=new THREE.Matrix4;this.init=function(g){a=g.context;b=g;var g=THREE.ShaderLib.depthRGBA,h=THREE.UniformsUtils.clone(g.uniforms);c=new THREE.ShaderMaterial({fragmentShader:g.fragmentShader,vertexShader:g.vertexShader,uniforms:h});d=new THREE.ShaderMaterial({fragmentShader:g.fragmentShader,vertexShader:g.vertexShader,uniforms:h,morphTargets:!0});e=new THREE.ShaderMaterial({fragmentShader:g.fragmentShader,vertexShader:g.vertexShader,
-uniforms:h,skinning:!0});f=new THREE.ShaderMaterial({fragmentShader:g.fragmentShader,vertexShader:g.vertexShader,uniforms:h,morphTargets:!0,skinning:!0});c._shadowPass=!0;d._shadowPass=!0;e._shadowPass=!0;f._shadowPass=!0};this.render=function(a,b){this.enabled&&this.update(a,b)};this.update=function(i,j){var l,m,n,o,p,q;a.clearColor(1,1,1,1);a.disable(a.BLEND);b.setDepthTest(!0);b.autoUpdateScene&&i.updateMatrixWorld();j._viewMatrixArray||(j._viewMatrixArray=new Float32Array(16));j._projectionMatrixArray||
-(j._projectionMatrixArray=new Float32Array(16));j.matrixWorldInverse.getInverse(j.matrixWorld);j.matrixWorldInverse.flattenToArray(j._viewMatrixArray);j.projectionMatrix.flattenToArray(j._projectionMatrixArray);h.multiply(j.projectionMatrix,j.matrixWorldInverse);g.setFromMatrix(h);b.setRenderTarget(this.renderTarget);b.clear();q=i.__webglObjects;l=0;for(m=q.length;l<m;l++)if(n=q[l],p=n.object,n.render=!1,p.visible&&(!(p instanceof THREE.Mesh||p instanceof THREE.ParticleSystem)||!p.frustumCulled||
-g.contains(p)))p._modelViewMatrix.multiply(j.matrixWorldInverse,p.matrixWorld),n.render=!0;var t;l=0;for(m=q.length;l<m;l++)if(n=q[l],n.render&&(p=n.object,n=n.buffer,!(p instanceof THREE.ParticleSystem)||p.customDepthMaterial))(t=p.material instanceof THREE.MeshFaceMaterial?p.material.materials[0]:p.material)&&b.setMaterialFaces(p.material),o=0<p.geometry.morphTargets.length&&t.morphTargets,t=p instanceof THREE.SkinnedMesh&&t.skinning,o=p.customDepthMaterial?p.customDepthMaterial:t?o?f:e:o?d:c,n instanceof
-THREE.BufferGeometry?b.renderBufferDirect(j,i.__lights,null,o,n,p):b.renderBuffer(j,i.__lights,null,o,n,p);q=i.__webglObjectsImmediate;l=0;for(m=q.length;l<m;l++)n=q[l],p=n.object,p.visible&&(p._modelViewMatrix.multiply(j.matrixWorldInverse,p.matrixWorld),b.renderImmediateObject(j,i.__lights,null,c,p));l=b.getClearColor();m=b.getClearAlpha();a.clearColor(l.r,l.g,l.b,m);a.enable(a.BLEND)}};
+j.modelViewMatrix=b.getUniformLocation(h,"modelViewMatrix");j.projectionMatrix=b.getUniformLocation(h,"projectionMatrix");j.fogType=b.getUniformLocation(h,"fogType");j.fogDensity=b.getUniformLocation(h,"fogDensity");j.fogNear=b.getUniformLocation(h,"fogNear");j.fogFar=b.getUniformLocation(h,"fogFar");j.fogColor=b.getUniformLocation(h,"fogColor");j.alphaTest=b.getUniformLocation(h,"alphaTest")};this.render=function(d,e,n,o){var p=d.__webglSprites,q=p.length;if(q){var t=i,r=j,C=o/n,n=0.5*n,w=0.5*o,
+s=!0;b.useProgram(h);b.enableVertexAttribArray(t.position);b.enableVertexAttribArray(t.uv);b.disable(b.CULL_FACE);b.enable(b.BLEND);b.depthMask(!0);b.bindBuffer(b.ARRAY_BUFFER,f);b.vertexAttribPointer(t.position,2,b.FLOAT,!1,16,0);b.vertexAttribPointer(t.uv,2,b.FLOAT,!1,16,8);b.bindBuffer(b.ELEMENT_ARRAY_BUFFER,g);b.uniformMatrix4fv(r.projectionMatrix,!1,e._projectionMatrixArray);b.activeTexture(b.TEXTURE0);b.uniform1i(r.map,0);var H=t=0,z=d.fog;z?(b.uniform3f(r.fogColor,z.color.r,z.color.g,z.color.b),
+z instanceof THREE.Fog?(b.uniform1f(r.fogNear,z.near),b.uniform1f(r.fogFar,z.far),b.uniform1i(r.fogType,1),H=t=1):z instanceof THREE.FogExp2&&(b.uniform1f(r.fogDensity,z.density),b.uniform1i(r.fogType,2),H=t=2)):(b.uniform1i(r.fogType,0),H=t=0);for(var u,y=[],z=0;z<q;z++)u=p[z],u.visible&&0!==u.opacity&&(u.useScreenCoordinates?u.z=-u.position.z:(u._modelViewMatrix.multiply(e.matrixWorldInverse,u.matrixWorld),u.z=-u._modelViewMatrix.elements[14]));p.sort(a);for(z=0;z<q;z++)if(u=p[z],u.visible&&0!==
+u.opacity&&u.map&&u.map.image&&u.map.image.width)b.uniform1f(r.alphaTest,u.alphaTest),u.useScreenCoordinates?(b.uniform1i(r.useScreenCoordinates,1),b.uniform3f(r.screenPosition,(u.position.x-n)/n,(w-u.position.y)/w,Math.max(0,Math.min(1,u.position.z)))):(b.uniform1i(r.useScreenCoordinates,0),b.uniform1i(r.affectedByDistance,u.affectedByDistance?1:0),b.uniformMatrix4fv(r.modelViewMatrix,!1,u._modelViewMatrix.elements)),e=d.fog&&u.fog?H:0,t!==e&&(b.uniform1i(r.fogType,e),t=e),e=1/(u.scaleByViewport?
+o:1),y[0]=e*C*u.scale.x,y[1]=e*u.scale.y,b.uniform2f(r.uvScale,u.uvScale.x,u.uvScale.y),b.uniform2f(r.uvOffset,u.uvOffset.x,u.uvOffset.y),b.uniform2f(r.alignment,u.alignment.x,u.alignment.y),b.uniform1f(r.opacity,u.opacity),b.uniform3f(r.color,u.color.r,u.color.g,u.color.b),b.uniform1f(r.rotation,u.rotation),b.uniform2fv(r.scale,y),u.mergeWith3D&&!s?(b.enable(b.DEPTH_TEST),s=!0):!u.mergeWith3D&&s&&(b.disable(b.DEPTH_TEST),s=!1),c.setBlending(u.blending,u.blendEquation,u.blendSrc,u.blendDst),c.setTexture(u.map,
+0),b.drawElements(b.TRIANGLES,6,b.UNSIGNED_SHORT,0);b.enable(b.CULL_FACE);b.enable(b.DEPTH_TEST);b.depthMask(!0)}}};
+THREE.DepthPassPlugin=function(){this.enabled=!1;this.renderTarget=null;var a,b,c,d,e,f,g=new THREE.Frustum,h=new THREE.Matrix4;this.init=function(g){a=g.context;b=g;var g=THREE.ShaderLib.depthRGBA,h=THREE.UniformsUtils.clone(g.uniforms);c=new THREE.ShaderMaterial({fragmentShader:g.fragmentShader,vertexShader:g.vertexShader,uniforms:h});d=new THREE.ShaderMaterial({fragmentShader:g.fragmentShader,vertexShader:g.vertexShader,uniforms:h,morphTargets:!0});e=new THREE.ShaderMaterial({fragmentShader:g.fragmentShader,
+vertexShader:g.vertexShader,uniforms:h,skinning:!0});f=new THREE.ShaderMaterial({fragmentShader:g.fragmentShader,vertexShader:g.vertexShader,uniforms:h,morphTargets:!0,skinning:!0});c._shadowPass=!0;d._shadowPass=!0;e._shadowPass=!0;f._shadowPass=!0};this.render=function(a,b){this.enabled&&this.update(a,b)};this.update=function(i,j){var l,m,n,o,p,q;a.clearColor(1,1,1,1);a.disable(a.BLEND);b.setDepthTest(!0);b.autoUpdateScene&&i.updateMatrixWorld();j._viewMatrixArray||(j._viewMatrixArray=new Float32Array(16));
+j._projectionMatrixArray||(j._projectionMatrixArray=new Float32Array(16));j.matrixWorldInverse.getInverse(j.matrixWorld);j.matrixWorldInverse.flattenToArray(j._viewMatrixArray);j.projectionMatrix.flattenToArray(j._projectionMatrixArray);h.multiply(j.projectionMatrix,j.matrixWorldInverse);g.setFromMatrix(h);b.setRenderTarget(this.renderTarget);b.clear();q=i.__webglObjects;l=0;for(m=q.length;l<m;l++)if(n=q[l],p=n.object,n.render=!1,p.visible&&(!(p instanceof THREE.Mesh||p instanceof THREE.ParticleSystem)||
+!p.frustumCulled||g.contains(p)))p._modelViewMatrix.multiply(j.matrixWorldInverse,p.matrixWorld),n.render=!0;var t;l=0;for(m=q.length;l<m;l++)if(n=q[l],n.render&&(p=n.object,n=n.buffer,!(p instanceof THREE.ParticleSystem)||p.customDepthMaterial))(t=p.material instanceof THREE.MeshFaceMaterial?p.material.materials[0]:p.material)&&b.setMaterialFaces(p.material),o=0<p.geometry.morphTargets.length&&t.morphTargets,t=p instanceof THREE.SkinnedMesh&&t.skinning,o=p.customDepthMaterial?p.customDepthMaterial:
+t?o?f:e:o?d:c,n instanceof THREE.BufferGeometry?b.renderBufferDirect(j,i.__lights,null,o,n,p):b.renderBuffer(j,i.__lights,null,o,n,p);q=i.__webglObjectsImmediate;l=0;for(m=q.length;l<m;l++)n=q[l],p=n.object,p.visible&&(p._modelViewMatrix.multiply(j.matrixWorldInverse,p.matrixWorld),b.renderImmediateObject(j,i.__lights,null,c,p));l=b.getClearColor();m=b.getClearAlpha();a.clearColor(l.r,l.g,l.b,m);a.enable(a.BLEND)}};
 THREE.ShaderFlares={lensFlareVertexTexture:{vertexShader:"uniform vec3 screenPosition;\nuniform vec2 scale;\nuniform float rotation;\nuniform int renderType;\nuniform sampler2D occlusionMap;\nattribute vec2 position;\nattribute vec2 uv;\nvarying vec2 vUV;\nvarying float vVisibility;\nvoid main() {\nvUV = uv;\nvec2 pos = position;\nif( renderType == 2 ) {\nvec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) ) +\ntexture2D( occlusionMap, vec2( 0.5, 0.1 ) ) +\ntexture2D( occlusionMap, vec2( 0.9, 0.1 ) ) +\ntexture2D( occlusionMap, vec2( 0.9, 0.5 ) ) +\ntexture2D( occlusionMap, vec2( 0.9, 0.9 ) ) +\ntexture2D( occlusionMap, vec2( 0.5, 0.9 ) ) +\ntexture2D( occlusionMap, vec2( 0.1, 0.9 ) ) +\ntexture2D( occlusionMap, vec2( 0.1, 0.5 ) ) +\ntexture2D( occlusionMap, vec2( 0.5, 0.5 ) );\nvVisibility = (       visibility.r / 9.0 ) *\n( 1.0 - visibility.g / 9.0 ) *\n(       visibility.b / 9.0 ) *\n( 1.0 - visibility.a / 9.0 );\npos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;\npos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;\n}\ngl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\n}",fragmentShader:"precision mediump float;\nuniform sampler2D map;\nuniform float opacity;\nuniform int renderType;\nuniform vec3 color;\nvarying vec2 vUV;\nvarying float vVisibility;\nvoid main() {\nif( renderType == 0 ) {\ngl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );\n} else if( renderType == 1 ) {\ngl_FragColor = texture2D( map, vUV );\n} else {\nvec4 texture = texture2D( map, vUV );\ntexture.a *= opacity * vVisibility;\ngl_FragColor = texture;\ngl_FragColor.rgb *= color;\n}\n}"},
 lensFlare:{vertexShader:"uniform vec3 screenPosition;\nuniform vec2 scale;\nuniform float rotation;\nuniform int renderType;\nattribute vec2 position;\nattribute vec2 uv;\nvarying vec2 vUV;\nvoid main() {\nvUV = uv;\nvec2 pos = position;\nif( renderType == 2 ) {\npos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;\npos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;\n}\ngl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\n}",fragmentShader:"precision mediump float;\nuniform sampler2D map;\nuniform sampler2D occlusionMap;\nuniform float opacity;\nuniform int renderType;\nuniform vec3 color;\nvarying vec2 vUV;\nvoid main() {\nif( renderType == 0 ) {\ngl_FragColor = vec4( texture2D( map, vUV ).rgb, 0.0 );\n} else if( renderType == 1 ) {\ngl_FragColor = texture2D( map, vUV );\n} else {\nfloat visibility = texture2D( occlusionMap, vec2( 0.5, 0.1 ) ).a +\ntexture2D( occlusionMap, vec2( 0.9, 0.5 ) ).a +\ntexture2D( occlusionMap, vec2( 0.5, 0.9 ) ).a +\ntexture2D( occlusionMap, vec2( 0.1, 0.5 ) ).a;\nvisibility = ( 1.0 - visibility / 4.0 );\nvec4 texture = texture2D( map, vUV );\ntexture.a *= opacity * visibility;\ngl_FragColor = texture;\ngl_FragColor.rgb *= color;\n}\n}"}};
 THREE.ShaderSprite={sprite:{vertexShader:"uniform int useScreenCoordinates;\nuniform int affectedByDistance;\nuniform vec3 screenPosition;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform float rotation;\nuniform vec2 scale;\nuniform vec2 alignment;\nuniform vec2 uvOffset;\nuniform vec2 uvScale;\nattribute vec2 position;\nattribute vec2 uv;\nvarying vec2 vUV;\nvoid main() {\nvUV = uvOffset + uv * uvScale;\nvec2 alignedPosition = position + alignment;\nvec2 rotatedPosition;\nrotatedPosition.x = ( cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y ) * scale.x;\nrotatedPosition.y = ( sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y ) * scale.y;\nvec4 finalPosition;\nif( useScreenCoordinates != 0 ) {\nfinalPosition = vec4( screenPosition.xy + rotatedPosition, screenPosition.z, 1.0 );\n} else {\nfinalPosition = projectionMatrix * modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\nfinalPosition.xy += rotatedPosition * ( affectedByDistance == 1 ? 1.0 : finalPosition.z );\n}\ngl_Position = finalPosition;\n}",
-fragmentShader:"precision mediump float;\nuniform vec3 color;\nuniform sampler2D map;\nuniform float opacity;\nuniform int fogType;\nuniform vec3 fogColor;\nuniform float fogDensity;\nuniform float fogNear;\nuniform float fogFar;\nvarying vec2 vUV;\nvoid main() {\nvec4 texture = texture2D( map, vUV );\ngl_FragColor = vec4( color * texture.xyz, texture.a * opacity );\nif ( fogType > 0 ) {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat fogFactor = 0.0;\nif ( fogType == 1 ) {\nfogFactor = smoothstep( fogNear, fogFar, depth );\n} else {\nconst float LOG2 = 1.442695;\nfloat fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );\nfogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );\n}\ngl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n}\n}"}};
+fragmentShader:"precision mediump float;\nuniform vec3 color;\nuniform sampler2D map;\nuniform float opacity;\nuniform int fogType;\nuniform vec3 fogColor;\nuniform float fogDensity;\nuniform float fogNear;\nuniform float fogFar;\nuniform float alphaTest;\nvarying vec2 vUV;\nvoid main() {\nvec4 texture = texture2D( map, vUV );\nif ( texture.a < alphaTest ) discard;\ngl_FragColor = vec4( color * texture.xyz, texture.a * opacity );\nif ( fogType > 0 ) {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat fogFactor = 0.0;\nif ( fogType == 1 ) {\nfogFactor = smoothstep( fogNear, fogFar, depth );\n} else {\nconst float LOG2 = 1.442695;\nfloat fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );\nfogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );\n}\ngl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n}\n}"}};

+ 4 - 0
src/extras/renderers/plugins/SpritePlugin.js

@@ -74,6 +74,8 @@ THREE.SpritePlugin = function ( ) {
 		_sprite.uniforms.fogFar 		  	  = _gl.getUniformLocation( _sprite.program, "fogFar" );
 		_sprite.uniforms.fogColor 		  	  = _gl.getUniformLocation( _sprite.program, "fogColor" );
 
+		_sprite.uniforms.alphaTest 		  	  = _gl.getUniformLocation( _sprite.program, "alphaTest" );
+
 	};
 
 	this.render = function ( scene, camera, viewportWidth, viewportHeight ) {
@@ -186,6 +188,8 @@ THREE.SpritePlugin = function ( ) {
 
 			if ( sprite.map && sprite.map.image && sprite.map.image.width ) {
 
+				_gl.uniform1f( uniforms.alphaTest, sprite.alphaTest );
+
 				if ( sprite.useScreenCoordinates ) {
 
 					_gl.uniform1i( uniforms.useScreenCoordinates, 1 );

+ 4 - 0
src/extras/shaders/ShaderSprite.js

@@ -68,12 +68,16 @@ THREE.ShaderSprite = {
 			"uniform float fogDensity;",
 			"uniform float fogNear;",
 			"uniform float fogFar;",
+			"uniform float alphaTest;",
 
 			"varying vec2 vUV;",
 
 			"void main() {",
 
 				"vec4 texture = texture2D( map, vUV );",
+
+				"if ( texture.a < alphaTest ) discard;",
+
 				"gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );",
 
 				"if ( fogType > 0 ) {",

+ 2 - 0
src/objects/Sprite.js

@@ -33,6 +33,8 @@ THREE.Sprite = function ( parameters ) {
 	this.uvOffset = new THREE.Vector2( 0, 0 );
 	this.uvScale  = new THREE.Vector2( 1, 1 );
 
+	this.alphaTest = 0;
+
 };
 
 THREE.Sprite.prototype = Object.create( THREE.Object3D.prototype );