Michael Herzog 1 месяц назад
Родитель
Сommit
b48227fffd

+ 0 - 1
examples/jsm/Addons.js

@@ -223,7 +223,6 @@ export * from './shaders/FilmShader.js';
 export * from './shaders/FocusShader.js';
 export * from './shaders/FreiChenShader.js';
 export * from './shaders/GammaCorrectionShader.js';
-export * from './shaders/GodRaysShader.js';
 export * from './shaders/GTAOShader.js';
 export * from './shaders/HalftoneShader.js';
 export * from './shaders/HorizontalBlurShader.js';

+ 0 - 333
examples/jsm/shaders/GodRaysShader.js

@@ -1,333 +0,0 @@
-import {
-	Color,
-	Vector3
-} from 'three';
-
-/**
- * @module GodRaysShader
- * @three_import import * as GodRaysShader from 'three/addons/shaders/GodRaysShader.js';
- */
-
-/**
- * God-rays (crepuscular rays)
- *
- * 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
- * source. The blur repeatedly applies a blur filter of increasing support but constant
- * sample count to produce a blur filter with large support.
- *
- * My implementation performs 3 passes, similar to the implementation from Sousa. I found
- * just 6 samples per pass produced acceptable results. The blur is applied three times,
- * with decreasing filter support. The result is equivalent to a single pass with
- * 6*6*6 = 216 samples.
- *
- * References:
- * - [Sousa2008, Crysis Next Gen Effects, GDC2008](http://www.crytek.com/sites/default/files/GDC08_SousaT_CrysisEffects.ppt).
- *
- * @constant
- * @type {ShaderMaterial~Shader}
- */
-const GodRaysDepthMaskShader = {
-
-	name: 'GodRaysDepthMaskShader',
-
-	uniforms: {
-
-		tInput: {
-			value: null
-		}
-
-	},
-
-	vertexShader: /* glsl */`
-
-		varying vec2 vUv;
-
-		void main() {
-
-		 vUv = uv;
-		 gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
-
-	 }`,
-
-	fragmentShader: /* glsl */`
-
-		varying vec2 vUv;
-
-		uniform sampler2D tInput;
-
-		void main() {
-
-			gl_FragColor = vec4( 1.0 ) - texture2D( tInput, vUv );
-
-		}`
-
-};
-
-
-/**
- * The god-ray generation shader.
- *
- * First pass:
- *
- * The depth map is blurred along radial lines towards the "sun". The
- * output is written to a temporary render target (I used a 1/4 sized
- * target).
- *
- * Pass two & three:
- *
- * The results of the previous pass are re-blurred, each time with a
- * decreased distance between samples.
- *
- * @constant
- * @type {ShaderMaterial~Shader}
- */
-const GodRaysGenerateShader = {
-
-	name: 'GodRaysGenerateShader',
-
-	uniforms: {
-
-		tInput: {
-			value: null
-		},
-		fStepSize: {
-			value: 1.0
-		},
-		vSunPositionScreenSpace: {
-			value: new Vector3()
-		}
-
-	},
-
-	vertexShader: /* glsl */`
-
-		varying vec2 vUv;
-
-		void main() {
-
-		 vUv = uv;
-		 gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
-
-	 }`,
-
-	fragmentShader: /* glsl */`
-
-		#define TAPS_PER_PASS 6.0
-
-		varying vec2 vUv;
-
-		uniform sampler2D tInput;
-
-		uniform vec3 vSunPositionScreenSpace;
-		uniform float fStepSize; // filter step size
-
-		void main() {
-
-		// delta from current pixel to "sun" position
-
-			vec2 delta = vSunPositionScreenSpace.xy - vUv;
-			float dist = length( delta );
-
-		// Step vector (uv space)
-
-			vec2 stepv = fStepSize * delta / dist;
-
-		// Number of iterations between pixel and sun
-
-			float iters = dist/fStepSize;
-
-			vec2 uv = vUv.xy;
-			float col = 0.0;
-
-		// This breaks ANGLE in Chrome 22
-		//	- see http://code.google.com/p/chromium/issues/detail?id=153105
-
-		/*
-		// Unrolling didn't do much on my hardware (ATI Mobility Radeon 3450),
-		// so i've just left the loop
-
-		"for ( float i = 0.0; i < TAPS_PER_PASS; i += 1.0 ) {",
-
-		// Accumulate samples, making sure we don't walk past the light source.
-
-		// The check for uv.y < 1 would not be necessary with "border" UV wrap
-		// mode, with a black border color. I don't think this is currently
-		// 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
-		// not specifically handled.
-
-		"	col += ( i <= iters && uv.y < 1.0 ? texture2D( tInput, uv ).r : 0.0 );",
-		"	uv += stepv;",
-
-		"}",
-		*/
-
-		// Unrolling loop manually makes it work in ANGLE
-
-			float f = min( 1.0, max( vSunPositionScreenSpace.z / 1000.0, 0.0 ) ); // used to fade out godrays
-
-			if ( 0.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;
-			uv += stepv;
-
-			if ( 1.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;
-			uv += stepv;
-
-			if ( 2.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;
-			uv += stepv;
-
-			if ( 3.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;
-			uv += stepv;
-
-			if ( 4.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;
-			uv += stepv;
-
-			if ( 5.0 <= iters && uv.y < 1.0 ) col += texture2D( tInput, uv ).r * f;
-			uv += stepv;
-
-		// Should technically be dividing by 'iters but 'TAPS_PER_PASS' smooths out
-		// objectionable artifacts, in particular near the sun position. The side
-		// effect is that the result is darker than it should be around the sun, as
-		// TAPS_PER_PASS is greater than the number of samples actually accumulated.
-		// 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.
-
-			gl_FragColor = vec4( col/TAPS_PER_PASS );
-			gl_FragColor.a = 1.0;
-
-		}`
-
-};
-
-/**
- * Additively applies god rays from texture tGodRays to a background (tColors).
- * fGodRayIntensity attenuates the god rays.
- *
- * @constant
- * @type {ShaderMaterial~Shader}
- */
-const GodRaysCombineShader = {
-
-	name: 'GodRaysCombineShader',
-
-	uniforms: {
-
-		tColors: {
-			value: null
-		},
-
-		tGodRays: {
-			value: null
-		},
-
-		fGodRayIntensity: {
-			value: 0.69
-		}
-
-	},
-
-	vertexShader: /* glsl */`
-
-		varying vec2 vUv;
-
-		void main() {
-
-			vUv = uv;
-			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
-
-		}`,
-
-	fragmentShader: /* glsl */`
-
-		varying vec2 vUv;
-
-		uniform sampler2D tColors;
-		uniform sampler2D tGodRays;
-
-		uniform float fGodRayIntensity;
-
-		void main() {
-
-		// Since THREE.MeshDepthMaterial renders foreground objects white and background
-		// objects black, the god-rays will be white streaks. Therefore value is inverted
-		// before being combined with tColors
-
-			gl_FragColor = texture2D( tColors, vUv ) + fGodRayIntensity * vec4( 1.0 - texture2D( tGodRays, vUv ).r );
-			gl_FragColor.a = 1.0;
-
-		}`
-
-};
-
-
-/**
- * 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.
- *
- * @constant
- * @type {Object}
- */
-const GodRaysFakeSunShader = {
-
-	name: 'GodRaysFakeSunShader',
-
-	uniforms: {
-
-		vSunPositionScreenSpace: {
-			value: new Vector3()
-		},
-
-		fAspect: {
-			value: 1.0
-		},
-
-		sunColor: {
-			value: new Color( 0xffee00 )
-		},
-
-		bgColor: {
-			value: new Color( 0x000000 )
-		}
-
-	},
-
-	vertexShader: /* glsl */`
-
-		varying vec2 vUv;
-
-		void main() {
-
-			vUv = uv;
-			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
-
-		}`,
-
-	fragmentShader: /* glsl */`
-
-		varying vec2 vUv;
-
-		uniform vec3 vSunPositionScreenSpace;
-		uniform float fAspect;
-
-		uniform vec3 sunColor;
-		uniform vec3 bgColor;
-
-		void main() {
-
-			vec2 diff = vUv - vSunPositionScreenSpace.xy;
-
-		// Correct for aspect ratio
-
-			diff.x *= fAspect;
-
-			float prop = clamp( length( diff ) / 0.5, 0.0, 1.0 );
-			prop = 0.35 * pow( 1.0 - prop, 3.0 );
-
-			gl_FragColor.xyz = ( vSunPositionScreenSpace.z > 0.0 ) ? mix( sunColor, bgColor, 1.0 - prop ) : bgColor;
-			gl_FragColor.w = 1.0;
-
-		}`
-
-};
-
-export { GodRaysDepthMaskShader, GodRaysGenerateShader, GodRaysCombineShader, GodRaysFakeSunShader };

BIN
examples/models/gltf/godrays_demo.glb


BIN
examples/screenshots/webgl_postprocessing_godrays.jpg


+ 1 - 1
examples/tags.json

@@ -102,7 +102,7 @@
 	"webgl_postprocessing_dof": [ "bokeh" ],
 	"webgl_postprocessing_dof2": [ "bokeh" ],
 	"webgl_postprocessing_fxaa": [ "msaa", "multisampled" ],
-	"webgl_postprocessing_godrays": [ "light scattering" ],
+	"webgl_postprocessing_godrays": [ "community" ],
 	"webgl_postprocessing_gtao": [ "ambient occlusion" ],
 	"webgl_shadowmap_progressive": [ "shadow", "soft", "lightmap", "onBeforeCompile" ],
 	"webgl_postprocessing_ssaa": [ "msaa", "multisampled" ],

+ 126 - 281
examples/webgl_postprocessing_godrays.html

@@ -9,14 +9,16 @@
 
 	<body>
 		<div id="info">
-			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - webgl god-rays example - tree by <a href="http://www.turbosquid.com/3d-models/free-tree-3d-model/592617" target="_blank" rel="noopener">stanloshka</a>
+			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - webgl god-rays example - <a href="https://github.com/Ameobea/three-good-godrays" target="_blank" rel="noopener">three-good-godrays extension</a>
 		</div>
 
 		<script type="importmap">
 			{
 				"imports": {
 					"three": "../build/three.module.js",
-					"three/addons/": "./jsm/"
+					"three/addons/": "./jsm/",
+					"postprocessing": "https://unpkg.com/postprocessing@6.38.2/build/index.js",
+					"goodrays": "https://unpkg.com/three-good-godrays@0.8.1/build/three-good-godrays.esm.js"
 				}
 			}
 		</script>
@@ -27,92 +29,130 @@
 
 			import Stats from 'three/addons/libs/stats.module.js';
 
-			import { OBJLoader } from 'three/addons/loaders/OBJLoader.js';
+			import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
 			import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
-			import { GodRaysFakeSunShader, GodRaysDepthMaskShader, GodRaysCombineShader, GodRaysGenerateShader } from 'three/addons/shaders/GodRaysShader.js';
 
-			let container, stats;
-			let camera, scene, renderer, materialDepth;
+			import { EffectComposer, RenderPass } from 'postprocessing';
+			import { GodraysPass } from 'goodrays';
 
-			let sphereMesh;
+			let camera, scene, renderer, composer;
+			let controls, stats;
 
-			const sunPosition = new THREE.Vector3( 0, 1000, - 1000 );
-			const clipPosition = new THREE.Vector4();
-			const screenSpacePosition = new THREE.Vector3();
+			init();
 
-			const postprocessing = { enabled: true };
+			async function init() {
 
-			const orbitRadius = 200;
+				camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1, 1000 );
+				camera.position.set( - 175, 50, 0 );
 
-			const bgColor = 0x000511;
-			const sunColor = 0xffee00;
+				scene = new THREE.Scene();
+				scene.background = new THREE.Color( 0x000000 );
 
-			// Use a smaller size for some of the god-ray render targets for better performance.
-			const godrayRenderTargetResolutionMultiplier = 1.0 / 4.0;
+				// asset
 
-			init();
+				const loader = new GLTFLoader();
+				const gltf = await loader.loadAsync( 'models/gltf/godrays_demo.glb' );
+				scene.add( gltf.scene );
 
-			function init() {
+				const pillars = gltf.scene.getObjectByName( 'concrete' );
+				pillars.material = new THREE.MeshStandardMaterial( {
+					color: 0x333333,
+				} );
 
-				container = document.createElement( 'div' );
-				document.body.appendChild( container );
+				const base = gltf.scene.getObjectByName( 'base' );
+				base.material = new THREE.MeshStandardMaterial( {
+					color: 0x333333,
+					side: THREE.DoubleSide,
+				} );
 
-				//
+				setupBackdrop();
 
-				camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 3000 );
-				camera.position.z = 200;
+				// lights
 
-				scene = new THREE.Scene();
+				const lightPos = new THREE.Vector3( 0, 50, 0 );
+				const lightSphereMaterial = new THREE.MeshBasicMaterial( {
+					color: 0xffffff,
+				} );
+				const lightSphere = new THREE.Mesh( new THREE.SphereGeometry( 0.5, 16, 16 ), lightSphereMaterial );
+				lightSphere.position.copy( lightPos );
+				scene.add( lightSphere );
 
-				//
+				scene.add( new THREE.AmbientLight( 0xcccccc, 0.4 ) );
 
-				materialDepth = new THREE.MeshDepthMaterial();
+				const pointLight = new THREE.PointLight( 0xf6287d, 10000 );
+				pointLight.castShadow = true;
+				pointLight.shadow.bias = - 0.001;
+				pointLight.shadow.mapSize.width = 1024;
+				pointLight.shadow.mapSize.height = 1024;
+				pointLight.position.copy( lightPos );
+				scene.add( pointLight );
 
-				// tree
+				// shadow setup
 
-				const loader = new OBJLoader();
-				loader.load( 'models/obj/tree.obj', function ( object ) {
+				scene.traverse( obj => {
 
-					object.position.set( 0, - 150, - 150 );
-					object.scale.multiplyScalar( 400 );
-					scene.add( object );
+					if ( obj.isMesh === true ) {
 
-				} );
+						obj.castShadow = true;
+						obj.receiveShadow = true;
 
-				// sphere
+					}
 
-				const geo = new THREE.SphereGeometry( 1, 20, 10 );
-				sphereMesh = new THREE.Mesh( geo, new THREE.MeshBasicMaterial( { color: 0x000000 } ) );
-				sphereMesh.scale.multiplyScalar( 20 );
-				scene.add( sphereMesh );
+				} );
+
+				lightSphere.castShadow = false;
+				lightSphere.receiveShadow = false;
 
 				//
 
 				renderer = new THREE.WebGLRenderer();
-				renderer.setClearColor( 0xffffff );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.setAnimationLoop( animate );
-				container.appendChild( renderer.domElement );
+				renderer.shadowMap.enabled = true;
+				document.body.appendChild( renderer.domElement );
+
+				//
 
-				renderer.autoClear = false;
+				composer = new EffectComposer( renderer, { frameBufferType: THREE.HalfFloatType } );
 
-				const controls = new OrbitControls( camera, renderer.domElement );
-				controls.minDistance = 50;
-				controls.maxDistance = 500;
+				const renderPass = new RenderPass( scene, camera );
+    			composer.addPass( renderPass );
+
+				const params = {
+					density: 1 / 128,
+					maxDensity: 0.5,
+					edgeStrength: 2,
+					edgeRadius: 2,
+					distanceAttenuation: 2,
+					color: new THREE.Color( 0xf6287d ),
+					raymarchSteps: 60,
+					blur: true,
+					gammaCorrection: true,
+				};
+
+
+				const godraysPass = new GodraysPass( pointLight, camera, params );
+				godraysPass.renderToScreen = true;
+				composer.addPass( godraysPass );
 
 				//
 
-				stats = new Stats();
-				container.appendChild( stats.dom );
+				controls = new OrbitControls( camera, renderer.domElement );
+				controls.target.set( 0, 0.5, 0 );
+				controls.enableDamping = true;
+				controls.maxDistance = 200;
+				controls.update();
 
 				//
 
-				window.addEventListener( 'resize', onWindowResize );
+				stats = new Stats();
+				document.body.appendChild( stats.dom );
 
 				//
 
-				initPostprocessing( window.innerWidth, window.innerHeight );
+				window.addEventListener( 'resize', onWindowResize );
+
 
 			}
 
@@ -120,254 +160,59 @@
 
 			function onWindowResize() {
 
-				const renderTargetWidth = window.innerWidth;
-				const renderTargetHeight = window.innerHeight;
-
-				camera.aspect = renderTargetWidth / renderTargetHeight;
+				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.updateProjectionMatrix();
 
-				renderer.setSize( renderTargetWidth, renderTargetHeight );
-				postprocessing.rtTextureColors.setSize( renderTargetWidth, renderTargetHeight );
-				postprocessing.rtTextureDepth.setSize( renderTargetWidth, renderTargetHeight );
-				postprocessing.rtTextureDepthMask.setSize( renderTargetWidth, renderTargetHeight );
-
-				const adjustedWidth = renderTargetWidth * godrayRenderTargetResolutionMultiplier;
-				const adjustedHeight = renderTargetHeight * godrayRenderTargetResolutionMultiplier;
-				postprocessing.rtTextureGodRays1.setSize( adjustedWidth, adjustedHeight );
-				postprocessing.rtTextureGodRays2.setSize( adjustedWidth, adjustedHeight );
+				renderer.setSize( window.innerWidth, window.innerHeight );
 
 			}
 
-			function initPostprocessing( renderTargetWidth, renderTargetHeight ) {
-
-				postprocessing.scene = new THREE.Scene();
-
-				postprocessing.camera = new THREE.OrthographicCamera( - 0.5, 0.5, 0.5, - 0.5, - 10000, 10000 );
-				postprocessing.camera.position.z = 100;
-
-				postprocessing.scene.add( postprocessing.camera );
-
-				postprocessing.rtTextureColors = new THREE.WebGLRenderTarget( renderTargetWidth, renderTargetHeight, { type: THREE.HalfFloatType } );
-
-				// I would have this quarter size and use it as one of the ping-pong render
-				// targets but the aliasing causes some temporal flickering
-
-				postprocessing.rtTextureDepth = new THREE.WebGLRenderTarget( renderTargetWidth, renderTargetHeight, { type: THREE.HalfFloatType } );
-				postprocessing.rtTextureDepthMask = new THREE.WebGLRenderTarget( renderTargetWidth, renderTargetHeight, { type: THREE.HalfFloatType } );
-
-				// The ping-pong render targets can use an adjusted resolution to minimize cost
-
-				const adjustedWidth = renderTargetWidth * godrayRenderTargetResolutionMultiplier;
-				const adjustedHeight = renderTargetHeight * godrayRenderTargetResolutionMultiplier;
-				postprocessing.rtTextureGodRays1 = new THREE.WebGLRenderTarget( adjustedWidth, adjustedHeight, { type: THREE.HalfFloatType } );
-				postprocessing.rtTextureGodRays2 = new THREE.WebGLRenderTarget( adjustedWidth, adjustedHeight, { type: THREE.HalfFloatType } );
-
-				// god-ray shaders
-
-				const godraysMaskShader = GodRaysDepthMaskShader;
-				postprocessing.godrayMaskUniforms = THREE.UniformsUtils.clone( godraysMaskShader.uniforms );
-				postprocessing.materialGodraysDepthMask = new THREE.ShaderMaterial( {
-
-					uniforms: postprocessing.godrayMaskUniforms,
-					vertexShader: godraysMaskShader.vertexShader,
-					fragmentShader: godraysMaskShader.fragmentShader
+			function setupBackdrop() {
 
+				 const backdropDistance = 200;
+				// Add backdrop walls `backdropDistance` units away from the origin
+				const backdropGeometry = new THREE.PlaneGeometry( 400, 200 );
+				const backdropMaterial = new THREE.MeshBasicMaterial( {
+					color: 0x200808,
+					side: THREE.DoubleSide,
 				} );
-
-				const godraysGenShader = GodRaysGenerateShader;
-				postprocessing.godrayGenUniforms = THREE.UniformsUtils.clone( godraysGenShader.uniforms );
-				postprocessing.materialGodraysGenerate = new THREE.ShaderMaterial( {
-
-					uniforms: postprocessing.godrayGenUniforms,
-					vertexShader: godraysGenShader.vertexShader,
-					fragmentShader: godraysGenShader.fragmentShader
-
-				} );
-
-				const godraysCombineShader = GodRaysCombineShader;
-				postprocessing.godrayCombineUniforms = THREE.UniformsUtils.clone( godraysCombineShader.uniforms );
-				postprocessing.materialGodraysCombine = new THREE.ShaderMaterial( {
-
-					uniforms: postprocessing.godrayCombineUniforms,
-					vertexShader: godraysCombineShader.vertexShader,
-					fragmentShader: godraysCombineShader.fragmentShader
-
-				} );
-
-				const godraysFakeSunShader = GodRaysFakeSunShader;
-				postprocessing.godraysFakeSunUniforms = THREE.UniformsUtils.clone( godraysFakeSunShader.uniforms );
-				postprocessing.materialGodraysFakeSun = new THREE.ShaderMaterial( {
-
-					uniforms: postprocessing.godraysFakeSunUniforms,
-					vertexShader: godraysFakeSunShader.vertexShader,
-					fragmentShader: godraysFakeSunShader.fragmentShader
-
-				} );
-
-				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( 1.0, 1.0 ),
-					postprocessing.materialGodraysGenerate
-				);
-				postprocessing.quad.position.z = - 9900;
-				postprocessing.scene.add( postprocessing.quad );
+				const backdropLeft = new THREE.Mesh( backdropGeometry, backdropMaterial );
+				backdropLeft.position.set( - backdropDistance, 100, 0 );
+				backdropLeft.rotateY( Math.PI / 2 );
+				scene.add( backdropLeft );
+			
+				const backdropRight = new THREE.Mesh( backdropGeometry, backdropMaterial );
+				backdropRight.position.set( backdropDistance, 100, 0 );
+				backdropRight.rotateY( Math.PI / 2 );
+				scene.add( backdropRight );
+			
+				const backdropFront = new THREE.Mesh( backdropGeometry, backdropMaterial );
+				backdropFront.position.set( 0, 100, - backdropDistance );
+				scene.add( backdropFront );
+			
+				const backdropBack = new THREE.Mesh( backdropGeometry, backdropMaterial );
+				backdropBack.position.set( 0, 100, backdropDistance );
+				scene.add( backdropBack );
+			
+				const backdropTop = new THREE.Mesh( backdropGeometry, backdropMaterial );
+				backdropTop.position.set( 0, 200, 0 );
+				backdropTop.rotateX( Math.PI / 2 );
+				backdropTop.scale.set( 3, 6, 1 );
+				scene.add( backdropTop );
 
 			}
 
 			function animate() {
 
-				stats.begin();
-				render();
-				stats.end();
-
-			}
-
-			function getStepSize( filterLen, tapsPerPass, pass ) {
-
-				return filterLen * Math.pow( tapsPerPass, - pass );
-
-			}
-
-			function filterGodRays( inputTex, renderTarget, stepSize ) {
-
-				postprocessing.scene.overrideMaterial = postprocessing.materialGodraysGenerate;
-
-				postprocessing.godrayGenUniforms[ 'fStepSize' ].value = stepSize;
-				postprocessing.godrayGenUniforms[ 'tInput' ].value = inputTex;
-
-				renderer.setRenderTarget( renderTarget );
-				renderer.render( postprocessing.scene, postprocessing.camera );
-				postprocessing.scene.overrideMaterial = null;
-
-			}
-
-			function render() {
-
-				const time = Date.now() / 4000;
-
-				sphereMesh.position.x = orbitRadius * Math.cos( time );
-				sphereMesh.position.z = orbitRadius * Math.sin( time ) - 100;
-
-				if ( postprocessing.enabled ) {
-
-					clipPosition.x = sunPosition.x;
-					clipPosition.y = sunPosition.y;
-					clipPosition.z = sunPosition.z;
-					clipPosition.w = 1;
-
-					clipPosition.applyMatrix4( camera.matrixWorldInverse ).applyMatrix4( camera.projectionMatrix );
-
-					// perspective divide (produce NDC space)
-
-					clipPosition.x /= clipPosition.w;
-					clipPosition.y /= clipPosition.w;
-
-					screenSpacePosition.x = ( clipPosition.x + 1 ) / 2; // transform from [-1,1] to [0,1]
-					screenSpacePosition.y = ( clipPosition.y + 1 ) / 2; // transform from [-1,1] to [0,1]
-					screenSpacePosition.z = clipPosition.z; // needs to stay in clip space for visibility checks
-
-					// Give it to the god-ray and sun shaders
-
-					postprocessing.godrayGenUniforms[ 'vSunPositionScreenSpace' ].value.copy( screenSpacePosition );
-					postprocessing.godraysFakeSunUniforms[ 'vSunPositionScreenSpace' ].value.copy( screenSpacePosition );
-
-					// -- Draw sky and sun --
-
-					// Clear colors and depths, will clear to sky color
-
-					renderer.setRenderTarget( postprocessing.rtTextureColors );
-					renderer.clear( true, true, false );
-
-					// 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
-					// rectangle around the suns position to avoid rendering surrounding pixels.
-
-					const sunsqH = 0.74 * window.innerHeight; // 0.74 depends on extent of sun from shader
-					const sunsqW = 0.74 * window.innerHeight; // both depend on height because sun is aspect-corrected
-
-					screenSpacePosition.x *= window.innerWidth;
-					screenSpacePosition.y *= window.innerHeight;
-
-					renderer.setScissor( screenSpacePosition.x - sunsqW / 2, screenSpacePosition.y - sunsqH / 2, sunsqW, sunsqH );
-					renderer.setScissorTest( true );
+				controls.update();
 
-					postprocessing.godraysFakeSunUniforms[ 'fAspect' ].value = window.innerWidth / window.innerHeight;
-
-					postprocessing.scene.overrideMaterial = postprocessing.materialGodraysFakeSun;
-					renderer.setRenderTarget( postprocessing.rtTextureColors );
-					renderer.render( postprocessing.scene, postprocessing.camera );
-
-					renderer.setScissorTest( false );
-
-					// -- Draw scene objects --
-
-					// Colors
-
-					scene.overrideMaterial = null;
-					renderer.setRenderTarget( postprocessing.rtTextureColors );
-					renderer.render( scene, camera );
-
-					// Depth
-
-					scene.overrideMaterial = materialDepth;
-					renderer.setRenderTarget( postprocessing.rtTextureDepth );
-					renderer.clear();
-					renderer.render( scene, camera );
-
-					//
-
-					postprocessing.godrayMaskUniforms[ 'tInput' ].value = postprocessing.rtTextureDepth.texture;
-
-					postprocessing.scene.overrideMaterial = postprocessing.materialGodraysDepthMask;
-					renderer.setRenderTarget( postprocessing.rtTextureDepthMask );
-					renderer.render( postprocessing.scene, postprocessing.camera );
-
-					// -- Render god-rays --
-
-					// Maximum length of god-rays (in texture space [0,1]X[0,1])
-
-					const filterLen = 1.0;
-
-					// Samples taken by filter
-
-					const TAPS_PER_PASS = 6.0;
-
-					// Pass order could equivalently be 3,2,1 (instead of 1,2,3), which
-					// would start with a small filter support and grow to large. however
-					// the large-to-small order produces less objectionable aliasing artifacts that
-					// appear as a glimmer along the length of the beams
-
-					// pass 1 - render into first ping-pong target
-					filterGodRays( postprocessing.rtTextureDepthMask.texture, postprocessing.rtTextureGodRays2, getStepSize( filterLen, TAPS_PER_PASS, 1.0 ) );
-
-					// pass 2 - render into second ping-pong target
-					filterGodRays( postprocessing.rtTextureGodRays2.texture, postprocessing.rtTextureGodRays1, getStepSize( filterLen, TAPS_PER_PASS, 2.0 ) );
-
-					// pass 3 - 1st RT
-					filterGodRays( postprocessing.rtTextureGodRays1.texture, postprocessing.rtTextureGodRays2, getStepSize( filterLen, TAPS_PER_PASS, 3.0 ) );
-
-					// final pass - composite god-rays onto colors
-
-					postprocessing.godrayCombineUniforms[ 'tColors' ].value = postprocessing.rtTextureColors.texture;
-					postprocessing.godrayCombineUniforms[ 'tGodRays' ].value = postprocessing.rtTextureGodRays2.texture;
-
-					postprocessing.scene.overrideMaterial = postprocessing.materialGodraysCombine;
-
-					renderer.setRenderTarget( null );
-					renderer.render( postprocessing.scene, postprocessing.camera );
-					postprocessing.scene.overrideMaterial = null;
-
-				} else {
+				stats.begin();
 
-					renderer.setRenderTarget( null );
-					renderer.clear();
-					renderer.render( scene, camera );
+				composer.render();
 
-				}
+				//renderer.render( scene, camera );
+			
+				stats.end();
 
 			}
 

粤ICP备19079148号