diff --git a/examples/jsm/Addons.js b/examples/jsm/Addons.js
index d901f4de1746e5..58350ce6d9bed9 100644
--- a/examples/jsm/Addons.js
+++ b/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';
diff --git a/examples/jsm/shaders/GodRaysShader.js b/examples/jsm/shaders/GodRaysShader.js
deleted file mode 100644
index 6fe9629adee004..00000000000000
--- a/examples/jsm/shaders/GodRaysShader.js
+++ /dev/null
@@ -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 };
diff --git a/examples/models/gltf/godrays_demo.glb b/examples/models/gltf/godrays_demo.glb
new file mode 100644
index 00000000000000..4e63ff9131dfdb
Binary files /dev/null and b/examples/models/gltf/godrays_demo.glb differ
diff --git a/examples/screenshots/webgl_postprocessing_godrays.jpg b/examples/screenshots/webgl_postprocessing_godrays.jpg
index 60ddccdd51a986..0a8a358541c7bd 100644
Binary files a/examples/screenshots/webgl_postprocessing_godrays.jpg and b/examples/screenshots/webgl_postprocessing_godrays.jpg differ
diff --git a/examples/tags.json b/examples/tags.json
index 16dd0c5053e6c2..edee62010f7d63 100644
--- a/examples/tags.json
+++ b/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" ],
diff --git a/examples/webgl_postprocessing_godrays.html b/examples/webgl_postprocessing_godrays.html
index 605ffab5d308dd..e6efed53c1f35d 100644
--- a/examples/webgl_postprocessing_godrays.html
+++ b/examples/webgl_postprocessing_godrays.html
@@ -9,14 +9,16 @@
@@ -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();
}