Browse Source

Cleaned up god's ray example. Made background and sun color configurable.

alteredq 13 years ago
parent
commit
b0c25b7bb5
2 changed files with 254 additions and 123 deletions
  1. 83 19
      examples/js/ShaderGodRays.js
  2. 171 104
      examples/webgl_postprocessing_godrays.html

+ 83 - 19
examples/js/ShaderGodRays.js

@@ -6,7 +6,7 @@
  * Similar implementation to the one used by Crytek for CryEngine 2 [Sousa2008].
  * Similar implementation to the one used by Crytek for CryEngine 2 [Sousa2008].
  * Blurs a mask generated from the depth map along radial lines emanating from the light
  * Blurs a mask generated from the depth map along radial lines emanating from the light
  * source. The blur repeatedly applies a blur filter of increasing support but constant
  * source. The blur repeatedly applies a blur filter of increasing support but constant
- * sample count, to produce a blur filter with large support.
+ * sample count to produce a blur filter with large support.
  *
  *
  * My implementation performs 3 passes, similar to the implementation from Sousa. I found
  * My implementation performs 3 passes, similar to the implementation from Sousa. I found
  * just 6 samples per pass produced acceptible results. The blur is applied three times,
  * just 6 samples per pass produced acceptible results. The blur is applied three times,
@@ -42,31 +42,42 @@ THREE.ShaderGodRays = {
 	'godrays_generate': {
 	'godrays_generate': {
 
 
 		uniforms: {
 		uniforms: {
+
 			tInput: {
 			tInput: {
 				type: "t",
 				type: "t",
 				value: 0,
 				value: 0,
 				texture: null
 				texture: null
 			},
 			},
+
 			fStepSize: {
 			fStepSize: {
 				type: "f",
 				type: "f",
 				value: 1.0
 				value: 1.0
 			},
 			},
+
 			vSunPositionScreenSpace: {
 			vSunPositionScreenSpace: {
 				type: "v2",
 				type: "v2",
 				value: new THREE.Vector2( 0.5, 0.5 )
 				value: new THREE.Vector2( 0.5, 0.5 )
 			}
 			}
+
 		},
 		},
 
 
 		vertexShader: [
 		vertexShader: [
+
 			"varying vec2 vUv;",
 			"varying vec2 vUv;",
+
 			"void main() {",
 			"void main() {",
+
 				"vUv = vec2( uv.x, 1.0 - uv.y );",
 				"vUv = vec2( uv.x, 1.0 - uv.y );",
 				"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
 				"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
+
 			"}"
 			"}"
+
 		].join("\n"),
 		].join("\n"),
 
 
 		fragmentShader: [
 		fragmentShader: [
 
 
+			"#define TAPS_PER_PASS 6.0",
+
 			"varying vec2 vUv;",
 			"varying vec2 vUv;",
 
 
 			"uniform sampler2D tInput;",
 			"uniform sampler2D tInput;",
@@ -74,15 +85,19 @@ THREE.ShaderGodRays = {
 			"uniform vec2 vSunPositionScreenSpace;",
 			"uniform vec2 vSunPositionScreenSpace;",
 			"uniform float fStepSize;", // filter step size
 			"uniform float fStepSize;", // filter step size
 
 
-			"#define TAPS_PER_PASS 6.0",
-
 			"void main() {",
 			"void main() {",
+
 				// delta from current pixel to "sun" position
 				// delta from current pixel to "sun" position
-				"vec2 delta = (vSunPositionScreenSpace - vUv);",
-				"float dist = length(delta);",
+
+				"vec2 delta = vSunPositionScreenSpace - vUv;",
+				"float dist = length( delta );",
+
 				// Step vector (uv space)
 				// Step vector (uv space)
-				"vec2 stepv = fStepSize*delta/dist;",
+
+				"vec2 stepv = fStepSize * delta / dist;",
+
 				// Number of iterations between pixel and sun
 				// Number of iterations between pixel and sun
+
 				"float iters = dist/fStepSize;",
 				"float iters = dist/fStepSize;",
 
 
 				"vec2 uv = vUv.xy;",
 				"vec2 uv = vUv.xy;",
@@ -90,16 +105,20 @@ THREE.ShaderGodRays = {
 
 
 				// Unrolling didnt do much on my hardware (ATI Mobility Radeon 3450),
 				// Unrolling didnt do much on my hardware (ATI Mobility Radeon 3450),
 				// so i've just left the loop
 				// so i've just left the loop
-				"for (float i = 0.0; i < TAPS_PER_PASS; i+=1.0 ) {",
+
+				"for ( float i = 0.0; i < TAPS_PER_PASS; i += 1.0 ) {",
+
 					// Accumulate samples, making sure we dont walk past the light source.
 					// Accumulate samples, making sure we dont walk past the light source.
 
 
-					// The check for uv.y<1 would not be necessary with "border" UV wrap
+					// The check for uv.y < 1 would not be necessary with "border" UV wrap
 					// mode, with a black border colour. I don't think this is currently
 					// mode, with a black border colour. I don't think this is currently
 					// exposed by three.js. As a result there might be artifacts when the
 					// exposed by three.js. As a result there might be artifacts when the
 					// sun is to the left, right or bottom of screen as these cases are
 					// sun is to the left, right or bottom of screen as these cases are
 					// not specifically handled.
 					// not specifically handled.
-					"col += (i <= iters && uv.y<1. ? texture2D( tInput, uv ).r : .0) ;",
+
+					"col += ( i <= iters && uv.y < 1.0 ? texture2D( tInput, uv ).r : 0.0 );",
 					"uv += stepv;",
 					"uv += stepv;",
+
 				"}",
 				"}",
 
 
 				// Should technically be dividing by 'iters', but 'TAPS_PER_PASS' smooths out
 				// Should technically be dividing by 'iters', but 'TAPS_PER_PASS' smooths out
@@ -108,8 +127,10 @@ THREE.ShaderGodRays = {
 				// TAPS_PER_PASS is greater than the number of samples actually accumulated.
 				// TAPS_PER_PASS is greater than the number of samples actually accumulated.
 				// When the result is inverted (in the shader 'godrays_combine', this produces
 				// When the result is inverted (in the shader 'godrays_combine', this produces
 				// a slight bright spot at the position of the sun, even when it is occluded.
 				// a slight bright spot at the position of the sun, even when it is occluded.
+
 				"gl_FragColor = vec4( col/TAPS_PER_PASS );",
 				"gl_FragColor = vec4( col/TAPS_PER_PASS );",
-				"gl_FragColor.a = 1.;",
+				"gl_FragColor.a = 1.0;",
+
 			"}"
 			"}"
 
 
 		].join("\n")
 		].join("\n")
@@ -120,35 +141,46 @@ THREE.ShaderGodRays = {
 	 * Additively applies god rays from texture tGodRays to a background (tColors).
 	 * Additively applies god rays from texture tGodRays to a background (tColors).
 	 * fGodRayIntensity attenuates the god rays.
 	 * fGodRayIntensity attenuates the god rays.
 	 */
 	 */
+
 	'godrays_combine': {
 	'godrays_combine': {
 
 
 		uniforms: {
 		uniforms: {
+
 			tColors: {
 			tColors: {
 				type: "t",
 				type: "t",
 				value: 0,
 				value: 0,
 				texture: null
 				texture: null
 			},
 			},
+
 			tGodRays: {
 			tGodRays: {
 				type: "t",
 				type: "t",
 				value: 1,
 				value: 1,
 				texture: null
 				texture: null
 			},
 			},
+
 			fGodRayIntensity: {
 			fGodRayIntensity: {
 				type: "f",
 				type: "f",
 				value: 0.69
 				value: 0.69
 			},
 			},
+
 			vSunPositionScreenSpace: {
 			vSunPositionScreenSpace: {
 				type: "v2",
 				type: "v2",
 				value: new THREE.Vector2( 0.5, 0.5 )
 				value: new THREE.Vector2( 0.5, 0.5 )
-			},
+			}
+
 		},
 		},
 
 
 		vertexShader: [
 		vertexShader: [
+
 			"varying vec2 vUv;",
 			"varying vec2 vUv;",
+
 			"void main() {",
 			"void main() {",
+
 				"vUv = vec2( uv.x, 1.0 - uv.y );",
 				"vUv = vec2( uv.x, 1.0 - uv.y );",
 				"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
 				"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
+
 			"}"
 			"}"
+
 			].join("\n"),
 			].join("\n"),
 
 
 		fragmentShader: [
 		fragmentShader: [
@@ -162,41 +194,63 @@ THREE.ShaderGodRays = {
 			"uniform float fGodRayIntensity;",
 			"uniform float fGodRayIntensity;",
 
 
 			"void main() {",
 			"void main() {",
+
 				// Since THREE.MeshDepthMaterial renders foreground objects white and background
 				// Since THREE.MeshDepthMaterial renders foreground objects white and background
 				// objects black, the god-rays will be white streaks. Therefore value is inverted
 				// objects black, the god-rays will be white streaks. Therefore value is inverted
 				// before being combined with tColors
 				// before being combined with tColors
-				"gl_FragColor = texture2D( tColors, vUv ) + fGodRayIntensity*vec4( 1.-texture2D( tGodRays, vUv ).r );",
-				"gl_FragColor.a = 1.;",
+
+				"gl_FragColor = texture2D( tColors, vUv ) + fGodRayIntensity * vec4( 1.0 - texture2D( tGodRays, vUv ).r );",
+				"gl_FragColor.a = 1.0;",
+
 			"}"
 			"}"
 
 
 		].join("\n")
 		].join("\n")
 
 
 	},
 	},
-	
-	
+
+
 	/**
 	/**
 	 * A dodgy sun/sky shader. Makes a bright spot at the sun location. Would be
 	 * A dodgy sun/sky shader. Makes a bright spot at the sun location. Would be
 	 * cheaper/faster/simpler to implement this as a simple sun sprite.
 	 * cheaper/faster/simpler to implement this as a simple sun sprite.
 	 */
 	 */
+
 	'godrays_fake_sun': {
 	'godrays_fake_sun': {
 
 
 		uniforms: {
 		uniforms: {
+
 			vSunPositionScreenSpace: {
 			vSunPositionScreenSpace: {
 				type: "v2",
 				type: "v2",
 				value: new THREE.Vector2( 0.5, 0.5 )
 				value: new THREE.Vector2( 0.5, 0.5 )
 			},
 			},
+
 			fAspect: {
 			fAspect: {
 				type: "f",
 				type: "f",
 				value: 1.0
 				value: 1.0
 			},
 			},
+
+			sunColor: {
+				type: "c",
+				value: new THREE.Color( 0xffee00 )
+			},
+
+			bgColor: {
+				type: "c",
+				value: new THREE.Color( 0x000000 )
+			}
+
 		},
 		},
 
 
 		vertexShader: [
 		vertexShader: [
+
 			"varying vec2 vUv;",
 			"varying vec2 vUv;",
+
 			"void main() {",
 			"void main() {",
+
 				"vUv = vec2( uv.x, 1.0 - uv.y );",
 				"vUv = vec2( uv.x, 1.0 - uv.y );",
 				"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
 				"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
+
 			"}"
 			"}"
+
 		].join("\n"),
 		].join("\n"),
 
 
 		fragmentShader: [
 		fragmentShader: [
@@ -206,13 +260,23 @@ THREE.ShaderGodRays = {
 			"uniform vec2 vSunPositionScreenSpace;",
 			"uniform vec2 vSunPositionScreenSpace;",
 			"uniform float fAspect;",
 			"uniform float fAspect;",
 
 
+			"uniform vec3 sunColor;",
+			"uniform vec3 bgColor;",
+
 			"void main() {",
 			"void main() {",
-				"vec2 diff = vUv-vSunPositionScreenSpace;",
+
+				"vec2 diff = vUv - vSunPositionScreenSpace;",
+
 				// Correct for aspect ratio
 				// Correct for aspect ratio
+
 				"diff.x *= fAspect;",
 				"diff.x *= fAspect;",
-				"float prop = clamp(length(diff)/.5,0.,1.);",
-				"prop = .35*pow( 1.0 - prop, 3. ) ;",
-				"gl_FragColor = vec4(prop,prop,0.2,1.);",
+
+				"float prop = clamp( length( diff ) / 0.5, 0.0, 1.0 );",
+				"prop = 0.35 * pow( 1.0 - prop, 3.0 );",
+
+				"gl_FragColor.xyz = mix( sunColor, bgColor, 1.0 - prop );",
+				"gl_FragColor.w = 1.0;",
+
 			"}"
 			"}"
 
 
 		].join("\n")
 		].join("\n")

+ 171 - 104
examples/webgl_postprocessing_godrays.html

@@ -32,9 +32,9 @@
 
 
 	<body>
 	<body>
 		<script src="../build/Three.js"></script>
 		<script src="../build/Three.js"></script>
+		<script src="js/ShaderGodRays.js"></script>
 
 
 		<script src="js/Detector.js"></script>
 		<script src="js/Detector.js"></script>
-		<script src="js/ShaderGodRays.js"></script>
 		<script src="js/Stats.js"></script>
 		<script src="js/Stats.js"></script>
 
 
 		<div id="info">
 		<div id="info">
@@ -47,21 +47,29 @@
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 
 
 			var container, stats;
 			var container, stats;
-			var camera, scene, renderer, parameters, material_depth;
-			
-			var tree_mesh, sphere_mesh;
+			var camera, scene, renderer, materialDepth;
+
+			var treeMesh, sphereMesh;
 
 
-			var proj = new THREE.Projector();
-			var sunPos = new THREE.Vector3( 0, 1000, -1000 );
+			var projector = new THREE.Projector();
+
+			var sunPosition = new THREE.Vector3( 0, 1000, -1000 );
+			var screenSpacePosition = new THREE.Vector3();
 
 
 			var mouseX = 0, mouseY = 0;
 			var mouseX = 0, mouseY = 0;
 
 
 			var windowHalfX = window.innerWidth / 2;
 			var windowHalfX = window.innerWidth / 2;
 			var windowHalfY = window.innerHeight / 2;
 			var windowHalfY = window.innerHeight / 2;
 
 
-			var height = window.innerHeight-100;
+			var margin = 100;
+			var height = window.innerHeight - 2 * margin;
+
+			var postprocessing = { enabled : true };
+
+			var orbitRadius = 200;
 
 
-			var postprocessing = { enabled  : true };
+			var bgColor = 0x000511;
+			var sunColor = 0xffee00;
 
 
 			init();
 			init();
 			animate();
 			animate();
@@ -71,164 +79,194 @@
 				container = document.createElement( 'div' );
 				container = document.createElement( 'div' );
 				document.body.appendChild( container );
 				document.body.appendChild( container );
 
 
+				//
+
 				scene = new THREE.Scene();
 				scene = new THREE.Scene();
 
 
 				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / height, 1, 3000 );
 				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / height, 1, 3000 );
 				camera.position.z = 200;
 				camera.position.z = 200;
 				scene.add( camera );
 				scene.add( camera );
 
 
-				renderer = new THREE.WebGLRenderer( { antialias: false } );
-				renderer.setSize( window.innerWidth, height );
-				container.appendChild( renderer.domElement );
-
-				renderer.sortObjects = false;
+				//
 
 
 				// todo - try with fog
 				// todo - try with fog
 				//scene.fog = new THREE.Fog( 0xffaa55, 1000, FAR );
 				//scene.fog = new THREE.Fog( 0xffaa55, 1000, FAR );
 				//THREE.ColorUtils.adjustHSV( scene.fog.color, 0.02, -0.15, -0.65 );
 				//THREE.ColorUtils.adjustHSV( scene.fog.color, 0.02, -0.15, -0.65 );
 
 
-				material_depth = new THREE.MeshDepthMaterial();
+				materialDepth = new THREE.MeshDepthMaterial();
+
+				var materialScene = new THREE.MeshBasicMaterial( { color: 0x000000, shading: THREE.FlatShading } );
+
+				// tree
 
 
-				parameters = { color: 0x000000, shading: THREE.FlatShading };
-				var zmat = new THREE.MeshBasicMaterial( parameters );
+				var loader = new THREE.JSONLoader();
 
 
-				// tree mesh	
-				var jsonLoader = new THREE.JSONLoader();
-				jsonLoader.load( "obj/tree/tree.js", function( geometry ) {
+				loader.load( "obj/tree/tree.js", function( geometry ) {
 
 
-					var m = new THREE.Mesh( geometry, zmat );
-					m.position.set( 0, -150, -150 );
+					treeMesh = new THREE.Mesh( geometry, materialScene );
+					treeMesh.position.set( 0, -150, -150 );
 
 
 					var sc = 400;
 					var sc = 400;
-					m.scale.set( sc, sc, sc );
-					m.matrixAutoUpdate = false;
-					m.updateMatrix();
-					scene.add( m );
-					tree_mesh = m;
+					treeMesh.scale.set( sc, sc, sc );
+
+					treeMesh.matrixAutoUpdate = false;
+					treeMesh.updateMatrix();
+
+					scene.add( treeMesh );
 
 
 				} );
 				} );
 
 
+				// sphere
+
 				var geo = new THREE.SphereGeometry( 1, 20, 10 );
 				var geo = new THREE.SphereGeometry( 1, 20, 10 );
-				mesh = new THREE.Mesh( geo, zmat );
+				sphereMesh = new THREE.Mesh( geo, materialScene );
 
 
 				var sc = 20;
 				var sc = 20;
-				mesh.scale.set( sc, sc, sc );
+				sphereMesh.scale.set( sc, sc, sc );
 
 
-				mesh.matrixAutoUpdate = false;
-				mesh.updateMatrix();
+				scene.add( sphereMesh );
 
 
-				scene.add( mesh );
-				sphere_mesh = mesh;
-				
-				scene.matrixAutoUpdate = false;
+				//
 
 
-				initPostprocessing();
+				renderer = new THREE.WebGLRenderer( { antialias: false } );
+				renderer.setSize( window.innerWidth, height );
+				container.appendChild( renderer.domElement );
+
+				renderer.sortObjects = false;
 
 
 				renderer.autoClear = false;
 				renderer.autoClear = false;
-				renderer.setClearColorHex( 0x000033, 1);
+				renderer.setClearColorHex( bgColor, 1 );
 
 
 				renderer.domElement.style.position = 'absolute';
 				renderer.domElement.style.position = 'absolute';
-				renderer.domElement.style.top = "50px";
+				renderer.domElement.style.top = margin + "px";
 				renderer.domElement.style.left = "0px";
 				renderer.domElement.style.left = "0px";
 
 
+				//
+
 				stats = new Stats();
 				stats = new Stats();
 				stats.domElement.style.position = 'absolute';
 				stats.domElement.style.position = 'absolute';
 				stats.domElement.style.top = '0px';
 				stats.domElement.style.top = '0px';
 				container.appendChild( stats.domElement );
 				container.appendChild( stats.domElement );
 
 
+				stats.domElement.children[ 0 ].children[ 0 ].style.color = "#888";
+				stats.domElement.children[ 0 ].style.background = "transparent";
+				stats.domElement.children[ 0 ].children[ 1 ].style.display = "none";
+
+				//
+
 				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
 				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
 				document.addEventListener( 'touchstart', onDocumentTouchStart, false );
 				document.addEventListener( 'touchstart', onDocumentTouchStart, false );
 				document.addEventListener( 'touchmove', onDocumentTouchMove, false );
 				document.addEventListener( 'touchmove', onDocumentTouchMove, false );
 
 
+				//
+
+				initPostprocessing();
+
 			}
 			}
 
 
+			//
+
 			function onDocumentMouseMove( event ) {
 			function onDocumentMouseMove( event ) {
 
 
 				mouseX = event.clientX - windowHalfX;
 				mouseX = event.clientX - windowHalfX;
 				mouseY = event.clientY - windowHalfY;
 				mouseY = event.clientY - windowHalfY;
+
 			}
 			}
 
 
 			function onDocumentTouchStart( event ) {
 			function onDocumentTouchStart( event ) {
 
 
-				if ( event.touches.length == 1 ) {
+				if ( event.touches.length === 1 ) {
 
 
 					event.preventDefault();
 					event.preventDefault();
 
 
 					mouseX = event.touches[ 0 ].pageX - windowHalfX;
 					mouseX = event.touches[ 0 ].pageX - windowHalfX;
 					mouseY = event.touches[ 0 ].pageY - windowHalfY;
 					mouseY = event.touches[ 0 ].pageY - windowHalfY;
+
 				}
 				}
+
 			}
 			}
 
 
 			function onDocumentTouchMove( event ) {
 			function onDocumentTouchMove( event ) {
 
 
-				if ( event.touches.length == 1 ) {
+				if ( event.touches.length === 1 ) {
 
 
 					event.preventDefault();
 					event.preventDefault();
 
 
 					mouseX = event.touches[ 0 ].pageX - windowHalfX;
 					mouseX = event.touches[ 0 ].pageX - windowHalfX;
 					mouseY = event.touches[ 0 ].pageY - windowHalfY;
 					mouseY = event.touches[ 0 ].pageY - windowHalfY;
+
 				}
 				}
+
 			}
 			}
 
 
+			//
+
 			function initPostprocessing() {
 			function initPostprocessing() {
 
 
 				postprocessing.scene = new THREE.Scene();
 				postprocessing.scene = new THREE.Scene();
 
 
-				postprocessing.camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2,  window.innerHeight / 2, window.innerHeight / - 2, -10000, 10000 );
+				postprocessing.camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2,  height / 2, height / - 2, -10000, 10000 );
 				postprocessing.camera.position.z = 100;
 				postprocessing.camera.position.z = 100;
 
 
 				postprocessing.scene.add( postprocessing.camera );
 				postprocessing.scene.add( postprocessing.camera );
 
 
 				var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat };
 				var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat };
 				postprocessing.rtTextureColors = new THREE.WebGLRenderTarget( window.innerWidth, height, pars );
 				postprocessing.rtTextureColors = new THREE.WebGLRenderTarget( window.innerWidth, height, pars );
-				
+
 				// Switching the depth formats to luminance from rgb doesn't seem to work. I didn't
 				// Switching the depth formats to luminance from rgb doesn't seem to work. I didn't
 				// investigate further for now.
 				// investigate further for now.
 				// pars.format = THREE.LuminanceFormat;
 				// pars.format = THREE.LuminanceFormat;
-				
+
 				// I would have this quarter size and use it as one of the ping-pong render
 				// I would have this quarter size and use it as one of the ping-pong render
 				// targets but the aliasing causes some temporal flickering
 				// targets but the aliasing causes some temporal flickering
+
 				postprocessing.rtTextureDepth = new THREE.WebGLRenderTarget( window.innerWidth, height, pars );
 				postprocessing.rtTextureDepth = new THREE.WebGLRenderTarget( window.innerWidth, height, pars );
-				
-				// Aggressive downsize god-ray ping-pong render targets to minimize cost 
+
+				// Aggressive downsize god-ray ping-pong render targets to minimize cost
+
 				var w = window.innerWidth / 4.0;
 				var w = window.innerWidth / 4.0;
 				var h = height / 4.0;
 				var h = height / 4.0;
 				postprocessing.rtTextureGodRays1 = new THREE.WebGLRenderTarget( w, h, pars );
 				postprocessing.rtTextureGodRays1 = new THREE.WebGLRenderTarget( w, h, pars );
 				postprocessing.rtTextureGodRays2 = new THREE.WebGLRenderTarget( w, h, pars );
 				postprocessing.rtTextureGodRays2 = new THREE.WebGLRenderTarget( w, h, pars );
-				
+
 				// god-ray shaders
 				// god-ray shaders
 
 
-				var godray_gen_shader = THREE.ShaderGodRays[ "godrays_generate" ];
-				postprocessing.godray_gen_uniforms = THREE.UniformsUtils.clone( godray_gen_shader.uniforms );
+				var godraysGenShader = THREE.ShaderGodRays[ "godrays_generate" ];
+				postprocessing.godrayGenUniforms = THREE.UniformsUtils.clone( godraysGenShader.uniforms );
 				postprocessing.materialGodraysGenerate = new THREE.ShaderMaterial( {
 				postprocessing.materialGodraysGenerate = new THREE.ShaderMaterial( {
 
 
-					uniforms: postprocessing.godray_gen_uniforms,
-					vertexShader: godray_gen_shader.vertexShader,
-					fragmentShader: godray_gen_shader.fragmentShader
+					uniforms: postprocessing.godrayGenUniforms,
+					vertexShader: godraysGenShader.vertexShader,
+					fragmentShader: godraysGenShader.fragmentShader
 
 
 				} );
 				} );
 
 
-				var godrays_combine_shader = THREE.ShaderGodRays[ "godrays_combine" ];
-				postprocessing.godray_combine_uniforms = THREE.UniformsUtils.clone( godrays_combine_shader.uniforms );
+				var godraysCombineShader = THREE.ShaderGodRays[ "godrays_combine" ];
+				postprocessing.godrayCombineUniforms = THREE.UniformsUtils.clone( godraysCombineShader.uniforms );
 				postprocessing.materialGodraysCombine = new THREE.ShaderMaterial( {
 				postprocessing.materialGodraysCombine = new THREE.ShaderMaterial( {
 
 
-					uniforms: postprocessing.godray_combine_uniforms,
-					vertexShader: godrays_combine_shader.vertexShader,
-					fragmentShader: godrays_combine_shader.fragmentShader
+					uniforms: postprocessing.godrayCombineUniforms,
+					vertexShader: godraysCombineShader.vertexShader,
+					fragmentShader: godraysCombineShader.fragmentShader
 
 
 				} );
 				} );
 
 
-				var godrays_fake_sun_shader = THREE.ShaderGodRays[ "godrays_fake_sun" ];
-				postprocessing.godrays_fake_sun_uniforms = THREE.UniformsUtils.clone( godrays_fake_sun_shader.uniforms );
+				var godraysFakeSunShader = THREE.ShaderGodRays[ "godrays_fake_sun" ];
+				postprocessing.godraysFakeSunUniforms = THREE.UniformsUtils.clone( godraysFakeSunShader.uniforms );
 				postprocessing.materialGodraysFakeSun = new THREE.ShaderMaterial( {
 				postprocessing.materialGodraysFakeSun = new THREE.ShaderMaterial( {
 
 
-					uniforms: postprocessing.godrays_fake_sun_uniforms,
-					vertexShader: godrays_fake_sun_shader.vertexShader,
-					fragmentShader: godrays_fake_sun_shader.fragmentShader
+					uniforms: postprocessing.godraysFakeSunUniforms,
+					vertexShader: godraysFakeSunShader.vertexShader,
+					fragmentShader: godraysFakeSunShader.fragmentShader
 
 
 				} );
 				} );
-				
-				postprocessing.quad = new THREE.Mesh( new THREE.PlaneGeometry( window.innerWidth, window.innerHeight ), postprocessing.materialGodraysGenerate );
+
+				postprocessing.godraysFakeSunUniforms.bgColor.value.setHex( bgColor );
+				postprocessing.godraysFakeSunUniforms.sunColor.value.setHex( sunColor );
+
+				postprocessing.godrayCombineUniforms.fGodRayIntensity.value = 0.75;
+
+				postprocessing.quad = new THREE.Mesh( new THREE.PlaneGeometry( window.innerWidth, height ), postprocessing.materialGodraysGenerate );
 				postprocessing.quad.position.z = -9900;
 				postprocessing.quad.position.z = -9900;
 				postprocessing.quad.rotation.x = Math.PI / 2;
 				postprocessing.quad.rotation.x = Math.PI / 2;
 				postprocessing.scene.add( postprocessing.quad );
 				postprocessing.scene.add( postprocessing.quad );
@@ -238,7 +276,7 @@
 			function animate() {
 			function animate() {
 
 
 				requestAnimationFrame( animate, renderer.domElement );
 				requestAnimationFrame( animate, renderer.domElement );
-				
+
 				render();
 				render();
 				stats.update();
 				stats.update();
 
 
@@ -246,66 +284,81 @@
 
 
 			function render() {
 			function render() {
 
 
-				if ( sphere_mesh ) {
+				var time = Date.now() / 4000;
 
 
-					var radius = 100;
-					sphere_mesh.position.x = 200*Math.cos(Date.now()/4000);
-					sphere_mesh.position.z = 200*Math.sin(Date.now()/4000)-100;
-					sphere_mesh.updateMatrix();
+				sphereMesh.position.x = orbitRadius * Math.cos( time );
+				sphereMesh.position.z = orbitRadius * Math.sin( time ) - 100;
 
 
-				}
 
 
 				camera.position.x += ( mouseX - camera.position.x ) * 0.036;
 				camera.position.x += ( mouseX - camera.position.x ) * 0.036;
-				camera.position.y += ( - (mouseY) - camera.position.y ) * 0.036;
+				camera.position.y += ( - ( mouseY ) - camera.position.y ) * 0.036;
 
 
 				camera.lookAt( scene.position );
 				camera.lookAt( scene.position );
-				
+
 				if ( postprocessing.enabled ) {
 				if ( postprocessing.enabled ) {
 
 
 					// Find the screenspace position of the sun
 					// Find the screenspace position of the sun
-					var sspos = new THREE.Vector3( sunPos.x, sunPos.y, sunPos.z);
-					proj.projectVector(sspos,camera);
-					sspos.x = (sspos.x+1)/2;
-					sspos.y = (sspos.y+1)/2;
+
+					screenSpacePosition.copy( sunPosition );
+					projector.projectVector( screenSpacePosition, camera );
+
+					screenSpacePosition.x = ( screenSpacePosition.x + 1 ) / 2;
+					screenSpacePosition.y = ( screenSpacePosition.y + 1 ) / 2;
 
 
 					// Give it to the god-ray and sun shaders
 					// Give it to the god-ray and sun shaders
-					postprocessing.godray_gen_uniforms[ "vSunPositionScreenSpace" ].value = new THREE.Vector2(sspos.x,sspos.y);
-					postprocessing.godrays_fake_sun_uniforms[ "vSunPositionScreenSpace" ].value = new THREE.Vector2(sspos.x,sspos.y);
-					
+
+					postprocessing.godrayGenUniforms[ "vSunPositionScreenSpace" ].value.x = screenSpacePosition.x;
+					postprocessing.godrayGenUniforms[ "vSunPositionScreenSpace" ].value.y = screenSpacePosition.y;
+
+					postprocessing.godraysFakeSunUniforms[ "vSunPositionScreenSpace" ].value.x = screenSpacePosition.x;
+					postprocessing.godraysFakeSunUniforms[ "vSunPositionScreenSpace" ].value.y = screenSpacePosition.y;
+
 					// -- Draw sky and sun --
 					// -- Draw sky and sun --
-					
+
 					// Clear colors and depths, will clear to sky color
 					// Clear colors and depths, will clear to sky color
-					renderer.clearTarget(postprocessing.rtTextureColors,true,true,false);
-					
+
+					renderer.clearTarget( postprocessing.rtTextureColors, true, true, false );
+
 					// Sun render. Runs a shader that gives a brightness based on the screen
 					// Sun render. Runs a shader that gives a brightness based on the screen
 					// space distance to the sun. Not very efficient, so i make a scissor
 					// space distance to the sun. Not very efficient, so i make a scissor
-					// rect around the suns position to avoid rendering surrounding pixels.
-					var sunsqH = 0.74 * height; // .74 depends on extent of sun from shader
-					var sunsqW = 0.74 * height; // both dep on height because sun is aspect-corrected
-					sspos.x *= window.innerWidth;
-					sspos.y *= height;
-					renderer.setScissor( sspos.x-sunsqW/2,sspos.y-sunsqH/2,sunsqW,sunsqH );
+					// rectangle around the suns position to avoid rendering surrounding pixels.
+
+					var sunsqH = 0.74 * height; // 0.74 depends on extent of sun from shader
+					var sunsqW = 0.74 * height; // both depend on height because sun is aspect-corrected
+
+					screenSpacePosition.x *= window.innerWidth;
+					screenSpacePosition.y *= height;
+
+					renderer.setScissor( screenSpacePosition.x - sunsqW / 2, screenSpacePosition.y - sunsqH / 2, sunsqW, sunsqH );
 					renderer.enableScissorTest( true );
 					renderer.enableScissorTest( true );
-					postprocessing.godrays_fake_sun_uniforms[ "fAspect" ].value = window.innerWidth / height;
+
+					postprocessing.godraysFakeSunUniforms[ "fAspect" ].value = window.innerWidth / height;
+
 					postprocessing.scene.overrideMaterial = postprocessing.materialGodraysFakeSun;
 					postprocessing.scene.overrideMaterial = postprocessing.materialGodraysFakeSun;
 					renderer.render( postprocessing.scene, postprocessing.camera, postprocessing.rtTextureColors );
 					renderer.render( postprocessing.scene, postprocessing.camera, postprocessing.rtTextureColors );
+
 					renderer.enableScissorTest( false );
 					renderer.enableScissorTest( false );
-					
+
 					// -- Draw scene objects --
 					// -- Draw scene objects --
-					
+
 					// Colors
 					// Colors
+
 					scene.overrideMaterial = null;
 					scene.overrideMaterial = null;
 					renderer.render( scene, camera, postprocessing.rtTextureColors );
 					renderer.render( scene, camera, postprocessing.rtTextureColors );
-					
+
 					// Depth
 					// Depth
-					scene.overrideMaterial = material_depth;
+
+					scene.overrideMaterial = materialDepth;
 					renderer.render( scene, camera, postprocessing.rtTextureDepth, true );
 					renderer.render( scene, camera, postprocessing.rtTextureDepth, true );
 
 
 					// -- Render god-rays --
 					// -- Render god-rays --
 
 
 					// Maximum length of god-rays (in texture space [0,1]X[0,1])
 					// Maximum length of god-rays (in texture space [0,1]X[0,1])
+
 					var filterLen = 1.0;
 					var filterLen = 1.0;
+
 					// Samples taken by filter
 					// Samples taken by filter
+
 					var TAPS_PER_PASS = 6.0;
 					var TAPS_PER_PASS = 6.0;
 
 
 					// Pass order could equivalently be 3,2,1 (instead of 1,2,3), which
 					// Pass order could equivalently be 3,2,1 (instead of 1,2,3), which
@@ -314,31 +367,44 @@
 					// appear as a glimmer along the length of the beams
 					// appear as a glimmer along the length of the beams
 
 
 					// pass 1 - render into first ping-pong target
 					// pass 1 - render into first ping-pong target
+
 					var pass = 1.0;
 					var pass = 1.0;
-					var stepLen = filterLen*Math.pow(TAPS_PER_PASS, -pass);
-					postprocessing.godray_gen_uniforms[ "fStepSize" ].value = stepLen;
-					postprocessing.godray_gen_uniforms[ "tInput" ].texture = postprocessing.rtTextureDepth;
+					var stepLen = filterLen * Math.pow( TAPS_PER_PASS, -pass );
+
+					postprocessing.godrayGenUniforms[ "fStepSize" ].value = stepLen;
+					postprocessing.godrayGenUniforms[ "tInput" ].texture = postprocessing.rtTextureDepth;
+
 					postprocessing.scene.overrideMaterial = postprocessing.materialGodraysGenerate;
 					postprocessing.scene.overrideMaterial = postprocessing.materialGodraysGenerate;
+
 					renderer.render( postprocessing.scene, postprocessing.camera, postprocessing.rtTextureGodRays2 );
 					renderer.render( postprocessing.scene, postprocessing.camera, postprocessing.rtTextureGodRays2 );
 
 
 					// pass 2 - render into second ping-pong target
 					// pass 2 - render into second ping-pong target
+
 					pass = 2.0;
 					pass = 2.0;
-					stepLen = filterLen*Math.pow(TAPS_PER_PASS, -pass);
-					postprocessing.godray_gen_uniforms[ "fStepSize" ].value = stepLen;
-					postprocessing.godray_gen_uniforms[ "tInput" ].texture = postprocessing.rtTextureGodRays2;
-					renderer.render( postprocessing.scene, postprocessing.camera , postprocessing.rtTextureGodRays1  );
+					stepLen = filterLen * Math.pow( TAPS_PER_PASS, -pass );
+
+					postprocessing.godrayGenUniforms[ "fStepSize" ].value = stepLen;
+					postprocessing.godrayGenUniforms[ "tInput" ].texture = postprocessing.rtTextureGodRays2;
+
+					renderer.render( postprocessing.scene, postprocessing.camera, postprocessing.rtTextureGodRays1  );
 
 
 					// pass 3 - 1st RT
 					// pass 3 - 1st RT
+
 					pass = 3.0;
 					pass = 3.0;
-					stepLen = filterLen*Math.pow(TAPS_PER_PASS, -pass);
-					postprocessing.godray_gen_uniforms[ "fStepSize" ].value = stepLen;
-					postprocessing.godray_gen_uniforms[ "tInput" ].texture = postprocessing.rtTextureGodRays1;
+					stepLen = filterLen * Math.pow( TAPS_PER_PASS, -pass );
+
+					postprocessing.godrayGenUniforms[ "fStepSize" ].value = stepLen;
+					postprocessing.godrayGenUniforms[ "tInput" ].texture = postprocessing.rtTextureGodRays1;
+
 					renderer.render( postprocessing.scene, postprocessing.camera , postprocessing.rtTextureGodRays2  );
 					renderer.render( postprocessing.scene, postprocessing.camera , postprocessing.rtTextureGodRays2  );
 
 
 					// final pass - composite god-rays onto colors
 					// final pass - composite god-rays onto colors
-					postprocessing.godray_combine_uniforms["tColors"].texture = postprocessing.rtTextureColors;
-					postprocessing.godray_combine_uniforms["tGodRays"].texture = postprocessing.rtTextureGodRays2;
+
+					postprocessing.godrayCombineUniforms["tColors"].texture = postprocessing.rtTextureColors;
+					postprocessing.godrayCombineUniforms["tGodRays"].texture = postprocessing.rtTextureGodRays2;
+
 					postprocessing.scene.overrideMaterial = postprocessing.materialGodraysCombine;
 					postprocessing.scene.overrideMaterial = postprocessing.materialGodraysCombine;
+
 					renderer.render( postprocessing.scene, postprocessing.camera );
 					renderer.render( postprocessing.scene, postprocessing.camera );
 					postprocessing.scene.overrideMaterial = null;
 					postprocessing.scene.overrideMaterial = null;
 
 
@@ -350,6 +416,7 @@
 				}
 				}
 
 
 			}
 			}
+
 		</script>
 		</script>
 	</body>
 	</body>
 </html>
 </html>