Pārlūkot izejas kodu

In the middle of lens flares

Mikael Emtinger 14 gadi atpakaļ
vecāks
revīzija
9ee4c267b1
3 mainītis faili ar 285 papildinājumiem un 54 dzēšanām
  1. 4 4
      src/lights/LensFlare.js
  2. 231 49
      src/renderers/WebGLRenderer.js
  3. 50 1
      src/renderers/WebGLShaders.js

+ 4 - 4
src/lights/LensFlare.js

@@ -2,7 +2,7 @@
  * @author Mikael Emtinger
  * @author Mikael Emtinger
  */
  */
  
  
-THREE.LensFlare = function ( material, size ) {
+THREE.LensFlare = function ( texture, size ) {
 
 
 	THREE.Object3D.call( this );
 	THREE.Object3D.call( this );
 
 
@@ -10,7 +10,7 @@ THREE.LensFlare = function ( material, size ) {
 	this.lensFlares = [];
 	this.lensFlares = [];
 	this.customUpdateCallback = undefined;
 	this.customUpdateCallback = undefined;
 
 
-	this.addLensFlare( material, size, 0 );
+	this.add( texture, size, 0 );
 };
 };
 
 
 THREE.LensFlare.prototype = new THREE.Object3D();
 THREE.LensFlare.prototype = new THREE.Object3D();
@@ -22,11 +22,11 @@ THREE.LensFlare.prototype.supr = THREE.Object3D.prototype;
  * Add: adds another flare 
  * Add: adds another flare 
  */
  */
 
 
-THREE.LensFlare.prototype.add = function( material, size, distance ) {
+THREE.LensFlare.prototype.add = function( texture, size, distance ) {
 	
 	
 	distance = Math.min( distance, Math.max( 0, distance ));
 	distance = Math.min( distance, Math.max( 0, distance ));
 
 
-	lensFlares.push( { material: material, size: size, distance: distance, position: new THREE.Vector3() } );
+	this.lensFlares.push( { texture: texture, size: size, distance: distance, position: new THREE.Vector3() } );
 }
 }
 
 
 
 

+ 231 - 49
src/renderers/WebGLRenderer.js

@@ -68,12 +68,14 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 	// parameters defaults
 	// parameters defaults
 
 
+	stencil = true,
 	antialias = true,
 	antialias = true,
 	clearColor = new THREE.Color( 0x000000 ),
 	clearColor = new THREE.Color( 0x000000 ),
 	clearAlpha = 0;
 	clearAlpha = 0;
 
 
 	if ( parameters ) {
 	if ( parameters ) {
 
 
+		if ( parameters.stencil != undefined ) stencil = parameters.stencil;
 		if ( parameters.antialias !== undefined ) antialias = parameters.antialias;
 		if ( parameters.antialias !== undefined ) antialias = parameters.antialias;
 		if ( parameters.clearColor !== undefined ) clearColor.setHex( parameters.clearColor );
 		if ( parameters.clearColor !== undefined ) clearColor.setHex( parameters.clearColor );
 		if ( parameters.clearAlpha !== undefined ) clearAlpha = parameters.clearAlpha;
 		if ( parameters.clearAlpha !== undefined ) clearAlpha = parameters.clearAlpha;
@@ -85,45 +87,226 @@ THREE.WebGLRenderer = function ( parameters ) {
 	this.autoClear = true;
 	this.autoClear = true;
 	this.sortObjects = true;
 	this.sortObjects = true;
 
 
-	initGL( antialias, clearColor, clearAlpha );
+	initGL( antialias, clearColor, clearAlpha, stencil );
 
 
 	this.context = _gl;
 	this.context = _gl;
 
 
 
 
-	// create shadow polygons
+	// prepare stencil shadow polygon
 
 
-	var _shadow   = {};
-	var vertices = [];
-	var faces    = [];
+	if( stencil ) {
+		
+		var _stencilShadow      = {};
+		
+		_stencilShadow.vertices = new Float32Array( 12 );
+		_stencilShadow.faces    = new Uint16Array( 6 );
+		_stencilShadow.darkness = 0.5;
+		
+		_stencilShadow.vertices[ 0 * 3 + 0 ] = -2; _stencilShadow.vertices[ 0 * 3 + 1 ] = -1; _stencilShadow.vertices[ 0 * 3 + 2 ] = -1;
+		_stencilShadow.vertices[ 1 * 3 + 0 ] =  2; _stencilShadow.vertices[ 1 * 3 + 1 ] = -1; _stencilShadow.vertices[ 1 * 3 + 2 ] = -1;
+		_stencilShadow.vertices[ 2 * 3 + 0 ] =  2; _stencilShadow.vertices[ 2 * 3 + 1 ] =  1; _stencilShadow.vertices[ 2 * 3 + 2 ] = -1;
+		_stencilShadow.vertices[ 3 * 3 + 0 ] = -2; _stencilShadow.vertices[ 3 * 3 + 1 ] =  1; _stencilShadow.vertices[ 3 * 3 + 2 ] = -1;
+		
+		_stencilShadow.faces[ 0 ] = 0; _stencilShadow.faces[ 1 ] = 1; _stencilShadow.faces[ 2 ] = 2;
+		_stencilShadow.faces[ 3 ] = 0; _stencilShadow.faces[ 4 ] = 2; _stencilShadow.faces[ 5 ] = 3;
+	
+	
+		_stencilShadow.vertexBuffer  = _gl.createBuffer();
+		_stencilShadow.elementBuffer = _gl.createBuffer();
+		
+		_gl.bindBuffer( _gl.ARRAY_BUFFER, _stencilShadow.vertexBuffer );
+		_gl.bufferData( _gl.ARRAY_BUFFER,  _stencilShadow.vertices, _gl.STATIC_DRAW );
+	
+		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _stencilShadow.elementBuffer );
+		_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _stencilShadow.faces, _gl.STATIC_DRAW );
+		
 	
 	
-	vertices[ 0 * 3 + 0 ] = -2; vertices[ 0 * 3 + 1 ] = -1; vertices[ 0 * 3 + 2 ] = -1;
-	vertices[ 1 * 3 + 0 ] =  2; vertices[ 1 * 3 + 1 ] = -1; vertices[ 1 * 3 + 2 ] = -1;
-	vertices[ 2 * 3 + 0 ] =  2; vertices[ 2 * 3 + 1 ] =  1; vertices[ 2 * 3 + 2 ] = -1;
-	vertices[ 3 * 3 + 0 ] = -2; vertices[ 3 * 3 + 1 ] =  1; vertices[ 3 * 3 + 2 ] = -1;
+		_stencilShadow.program = _gl.createProgram();
 	
 	
-	faces[ 0 ] = 0; faces[ 1 ] = 1; faces[ 2 ] = 2;
-	faces[ 3 ] = 0; faces[ 4 ] = 2; faces[ 5 ] = 3;
+		_gl.attachShader( _stencilShadow.program, getShader( "fragment", THREE.ShaderLib.shadowPost.fragmentShader ));
+		_gl.attachShader( _stencilShadow.program, getShader( "vertex",   THREE.ShaderLib.shadowPost.vertexShader   ));
+	
+		_gl.linkProgram( _stencilShadow.program );
+	
+		_stencilShadow.vertexLocation     = _gl.getAttribLocation ( _stencilShadow.program, "position"         );
+		_stencilShadow.projectionLocation = _gl.getUniformLocation( _stencilShadow.program, "projectionMatrix" );
+		_stencilShadow.darknessLocation   = _gl.getUniformLocation( _stencilShadow.program, "darkness"         );
+	}
+	
+	
+	// prepare lens flare
+	
+	var _lensFlare = {};
+	var i;
+	
+	_lensFlare.vertices     = new Float32Array( 8 + 8 );
+	_lensFlare.faces        = new Uint16Array( 6 );
+	_lensFlare.transparency = 0.5;
+	
+	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;
+
+	_lensFlare.vertexBuffer  = _gl.createBuffer();
+	_lensFlare.elementBuffer = _gl.createBuffer();
+	_lensFlare.tempTexture   = _gl.createTexture();
+	
+	_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 );
 
 
-	_shadow.vertexBuffer  = _gl.createBuffer();
-	_shadow.elementBuffer = _gl.createBuffer();
-	
-	_gl.bindBuffer( _gl.ARRAY_BUFFER, _shadow.vertexBuffer );
-	_gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( vertices ), _gl.STATIC_DRAW );
+	_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 );
+
+
+	_lensFlare.program = _gl.createProgram();
+
+	_gl.attachShader( _lensFlare.program, getShader( "fragment", THREE.ShaderLib.lensFlare.fragmentShader ));
+	_gl.attachShader( _lensFlare.program, getShader( "vertex",   THREE.ShaderLib.lensFlare.vertexShader   ));
+
+	_gl.linkProgram( _lensFlare.program );
+
+	_lensFlare.attributes = {};
+	_lensFlare.uniforms = {};
+	_lensFlare.attributes.vertex       = _gl.getAttribLocation ( _lensFlare.program, "position" );
+	_lensFlare.attributes.uv           = _gl.getAttribLocation ( _lensFlare.program, "UV" );
+	_lensFlare.uniforms.map            = _gl.getUniformLocation( _lensFlare.program, "map" );
+	_lensFlare.uniforms.opacity        = _gl.getUniformLocation( _lensFlare.program, "opacity" );
+	_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.uniforms.renderPink     = _gl.getUniformLocation( _lensFlare.program, "renderPink" );
+
+	/*
+	 * 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( scene, camera, renderTarget ) {
+		
+		var object, geometryGroup, material;
+		var o, ol = scene.__webglLensFlares.length;
+		var tempPosition = new THREE.Vector3();
+		var invAspect = _viewportHeight / _viewportWidth;
+		var halfViewportWidth = _viewportWidth * 0.5;
+		var halfViewportHeight = _viewportHeight * 0.5;
+		var size = 16 / _viewportHeight;
+		var restoreScale = [ size * invAspect, size ];
+		var screenPosition = [ 1, 1, 0 ];
+		var screenPositionPixels = [ 1, 1 ];
+
+		// set lensflare program
+
+		if( _oldProgram !== _lensFlare.program ) {
+			
+			_gl.useProgram( _lensFlare.program );
+			_oldProgram = _lensFlare.program;
+		}
+
+
+		// loop through all lens flares to update their occlusion and positions
+		// setup gl and common used attribs/unforms
+
+		_gl.uniform1i( _lensFlare.uniforms.map, 0 );
+		_gl.activeTexture( _gl.TEXTURE0 );
+		
+		_gl.uniform1f( _lensFlare.uniforms.opacity, 1 );
+		_gl.uniform1f( _lensFlare.uniforms.rotation, 0 );
+		_gl.uniform2fv( _lensFlare.uniforms.scale, restoreScale );
+
+		_gl.bindBuffer( _gl.ARRAY_BUFFER, _lensFlare.vertexBuffer );
+		_gl.vertexAttribPointer( _lensFlare.attributes.vertex, 2, _gl.FLOAT, false, 2 * 8, 0 );
+		_gl.vertexAttribPointer( _lensFlare.attributes.uv, 2, _gl.FLOAT, false, 2 * 8, 8 );
+
+		_gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
+
+		_gl.cullFace( _gl.BACK );
+		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.elementBuffer );
+
+
+		for( o = 0; o < ol; o++ ) {
+			
+			// calc object screen position
+			
+			object = scene.__webglLensFlares[ o ].object;
+			
+			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[ 0 ] = tempPosition.x;
+			screenPosition[ 1 ] = tempPosition.y;
+			screenPosition[ 2 ] = tempPosition.z;
+			
+			screenPositionPixels[ 0 ] = screenPosition[ 0 ] * halfViewportWidth + halfViewportWidth;
+			screenPositionPixels[ 1 ] = screenPosition[ 1 ] * halfViewportHeight + halfViewportHeight;
+
+			// todo: viewport culling
+			// save current RGB to temp texture
+			
+			_gl.copyTexSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, screenPositionPixels[ 0 ] - 8, screenPositionPixels[ 1 ] - 8, 16, 16 );
 
 
-	_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _shadow.elementBuffer );
-	_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, new Uint16Array( faces ), _gl.STATIC_DRAW );
 	
 	
+			// render pink quad
 
 
-	_shadow.program = _gl.createProgram();
+			_gl.uniform3fv( _lensFlare.uniforms.screenPosition, screenPosition );
+			_gl.uniform1i( _lensFlare.uniforms.renderPink, 1 );
 
 
-	_gl.attachShader( _shadow.program, getShader( "fragment", THREE.ShaderLib.shadowPost.fragmentShader ));
-	_gl.attachShader( _shadow.program, getShader( "vertex",   THREE.ShaderLib.shadowPost.vertexShader   ));
+			_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
 
 
-	_gl.linkProgram( _shadow.program );
 
 
-	_shadow.vertexLocation     = _gl.getAttribLocation ( _shadow.program, "position"         );
-	_shadow.projectionLocation = _gl.getUniformLocation( _shadow.program, "projectionMatrix" );
+			// restore graphics
+		
+			screenPosition[ 2 ] = 0;
+		
+			_gl.uniform1i( _lensFlare.uniforms.renderPink, 0 );
+			_gl.uniform3fv( _lensFlare.uniforms.screenPosition, screenPosition );
+
+			_gl.disable( _gl.DEPTH_TEST );
+			_gl.depthMask( false );
+
+			_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
+
+
+			
+			
+			// copy existing -> temp texture
+			// render pink quad
+			// read back pixles
+			// copy temp -> back
+			// call flare update
+			// render flares			
+			
+			
+
+		}
+		
+	}
+
 
 
 
 
 	this.setSize = function ( width, height ) {
 	this.setSize = function ( width, height ) {
@@ -187,6 +370,11 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 	};
 	};
 
 
+	this.setStencilShadowDarkness = function( value ) {
+		
+		_stencilShadow.darkness = value;
+	};
+
 
 
 	function setupLights ( program, lights ) {
 	function setupLights ( program, lights ) {
 
 
@@ -2528,14 +2716,14 @@ THREE.WebGLRenderer = function ( parameters ) {
 		
 		
 		if( scene.__webglLensFlares.length ) {
 		if( scene.__webglLensFlares.length ) {
 			
 			
-			renderLensFlares( scene, renderTarget );
+			renderLensFlares( scene, camera, renderTarget );
 		
 		
 		}
 		}
 
 
 
 
 		// render stencil shadows
 		// render stencil shadows
 
 
-		if( scene.__webglShadowVolumes.length && scene.lights.length ) {
+		if( stencil && scene.__webglShadowVolumes.length && scene.lights.length ) {
 
 
 			renderStencilShadows( scene );
 			renderStencilShadows( scene );
 		
 		
@@ -2553,19 +2741,7 @@ THREE.WebGLRenderer = function ( parameters ) {
 	};
 	};
 
 
 
 
-	/*
-	 * 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() {
-		
-		
-	}
+	
 
 
 
 
 	/*
 	/*
@@ -2596,8 +2772,9 @@ THREE.WebGLRenderer = function ( parameters ) {
 		
 		
 		var l, ll = scene.lights.length;
 		var l, ll = scene.lights.length;
 		var p;
 		var p;
-		var light, lights = scene.lights, geometryGroup;
+		var light, lights = scene.lights;
 		var dirLight = [];			
 		var dirLight = [];			
+		var object, geometryGroup, material;
 		var	program;
 		var	program;
 		var p_uniforms;
 		var p_uniforms;
 	    var m_uniforms;
 	    var m_uniforms;
@@ -2679,20 +2856,21 @@ THREE.WebGLRenderer = function ( parameters ) {
 		// draw darkening polygon	
 		// draw darkening polygon	
 
 
 		_oldBlending = "";
 		_oldBlending = "";
-		_oldProgram = _shadow.program;
+		_oldProgram = _stencilShadow.program;
 
 
-		_gl.useProgram( _shadow.program );
-		_gl.uniformMatrix4fv( _shadow.projectionLocation, false, _projectionMatrixArray );
+		_gl.useProgram( _stencilShadow.program );
+		_gl.uniformMatrix4fv( _stencilShadow.projectionLocation, false, _projectionMatrixArray );
+		_gl.uniform1f( _stencilShadow.darknessLocation, _stencilShadow.darkness );
 		
 		
-		_gl.bindBuffer( _gl.ARRAY_BUFFER, _shadow.vertexBuffer );
-		_gl.vertexAttribPointer( _shadow.vertexLocation, 3, _gl.FLOAT, false, 0, 0 );
-		_gl.enableVertexAttribArray( _shadow.vertexLocation );
+		_gl.bindBuffer( _gl.ARRAY_BUFFER, _stencilShadow.vertexBuffer );
+		_gl.vertexAttribPointer( _stencilShadow.vertexLocation, 3, _gl.FLOAT, false, 0, 0 );
+		_gl.enableVertexAttribArray( _stencilShadow.vertexLocation );
 
 
 		_gl.enable( _gl.BLEND );
 		_gl.enable( _gl.BLEND );
 		_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
 		_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
 		_gl.blendEquation( _gl.FUNC_ADD );
 		_gl.blendEquation( _gl.FUNC_ADD );
 			
 			
-		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _shadow.elementBuffer );
+		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _stencilShadow.elementBuffer );
 		_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
 		_gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
 
 
 
 
@@ -2820,6 +2998,10 @@ THREE.WebGLRenderer = function ( parameters ) {
 				}
 				}
 			}
 			}
 
 
+		} else if ( object instanceof THREE.LensFlare ) {
+			
+			addBuffer( scene.__webglLensFlares, undefined, object );
+			
 		} else if ( object instanceof THREE.Ribbon ) {
 		} else if ( object instanceof THREE.Ribbon ) {
 
 
 			geometry = object.geometry;
 			geometry = object.geometry;
@@ -3122,11 +3304,11 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 	};
 	};
 
 
-	function initGL ( antialias, clearColor, clearAlpha ) {
+	function initGL ( antialias, clearColor, clearAlpha, stencil ) {
 
 
 		try {
 		try {
 
 
-			if ( ! ( _gl = _canvas.getContext( 'experimental-webgl', { antialias: antialias, stencil:true } ) ) ) {
+			if ( ! ( _gl = _canvas.getContext( 'experimental-webgl', { antialias: antialias, stencil: stencil } ) ) ) {
 
 
 				throw 'Error creating WebGL context.';
 				throw 'Error creating WebGL context.';
 
 

+ 50 - 1
src/renderers/WebGLShaders.js

@@ -556,6 +556,52 @@ THREE.UniformsLib = {
 
 
 THREE.ShaderLib = {
 THREE.ShaderLib = {
 
 
+	'lensFlare': {
+		
+		vertexShader: [
+
+			"uniform 	vec3 	screenPosition;",
+			"uniform	vec2	scale;",
+			"uniform	float	rotation;",
+			"attribute 	vec2 	position;",
+			"attribute  vec2	UV;",
+			"varying	vec2	vUV;",
+	
+			"void main(void)",
+			"{",
+				"vUV = UV;",
+
+				"vec2 pos;",
+				"pos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;",
+				"pos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;",
+				"gl_Position = vec4(( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );",
+			"}"
+
+		].join( "\n" ),
+		
+		fragmentShader: [
+		
+			"#ifdef GL_ES",
+				"precision highp float;",
+			"#endif",		
+
+			"uniform	sampler2D	map;",
+			"uniform    int         renderPink;",
+			"varying	vec2		vUV;",
+	
+			"void main( void )",
+			"{",
+				"if( renderPink == 1 ) {",
+					"gl_FragColor = vec4( 1.0, 0.0, 1.0, 1.0 );",
+				"} else {",
+					"gl_FragColor = texture2D( map, vUV );",
+				"}",
+			"}"
+		].join( "\n" )
+
+	},
+
+
 	'shadowPost': {
 	'shadowPost': {
 		
 		
 		vertexShader: [
 		vertexShader: [
@@ -575,10 +621,13 @@ THREE.ShaderLib = {
 			"#ifdef GL_ES",
 			"#ifdef GL_ES",
 				"precision highp float;",
 				"precision highp float;",
 			"#endif",		
 			"#endif",		
+
+			"uniform 	float 	darkness;",
+
 	
 	
 			"void main( void )",
 			"void main( void )",
 			"{",
 			"{",
-				"gl_FragColor = vec4( 0, 0, 0, 0.5 );",
+				"gl_FragColor = vec4( 0, 0, 0, darkness );",
 			"}"
 			"}"
 
 
 		].join( "\n" )
 		].join( "\n" )