|
@@ -1,2491 +0,0 @@
|
|
|
-/**
|
|
|
- * @author alteredq / http://alteredqualia.com/
|
|
|
- * @author MPanknin / http://www.redplant.de/
|
|
|
- * @author takahiro / https://github.com/takahirox
|
|
|
- *
|
|
|
- * WebGLDeferredRenderer supports two types of Deferred Renderings.
|
|
|
- * One is Classic Deferred Rendering and the other one is
|
|
|
- * Light Pre-Pass (Deferred Lighting).
|
|
|
- * Classic Deferred Rendering is default. You can use Light Pre-Pass
|
|
|
- * by calling .enableLightPrePass( true ) method.
|
|
|
- *
|
|
|
- * Dependencies
|
|
|
- * - THREE.CopyShader
|
|
|
- * - THREE.RenderPass
|
|
|
- * - THREE.ShaderPass
|
|
|
- * - THREE.EffectComposer
|
|
|
- * - THREE.FXAAShader
|
|
|
- *
|
|
|
- * TODO
|
|
|
- * - reuse existing glsl
|
|
|
- * - shadow
|
|
|
- * - optimization
|
|
|
- * - MRT (when it's available on Three.js)
|
|
|
- * - AmbientLight
|
|
|
- * - HemisphereLight
|
|
|
- * - PointLight (distance < 0)
|
|
|
- * - morphNormals
|
|
|
- * - BumpMap
|
|
|
- * - ToneMap
|
|
|
- * - envMap
|
|
|
- * - wrapAround
|
|
|
- * - addEffect
|
|
|
- */
|
|
|
-
|
|
|
-THREE.WebGLDeferredRenderer = function ( parameters ) {
|
|
|
-
|
|
|
- parameters = parameters || {};
|
|
|
-
|
|
|
- // private properties
|
|
|
-
|
|
|
- var _this = this;
|
|
|
-
|
|
|
- var _context;
|
|
|
- var _state;
|
|
|
-
|
|
|
- var _width, _height;
|
|
|
-
|
|
|
- // for Classic Deferred Rendering
|
|
|
- var _compColor;
|
|
|
- var _passColor, _passForward, _passCopy;
|
|
|
-
|
|
|
- // for Light Pre-Pass
|
|
|
- var _compReconstruction;
|
|
|
- var _passReconstruction;
|
|
|
-
|
|
|
- // for Common
|
|
|
- var _compNormalDepth, _compLight, _compFinal;
|
|
|
- var _passNormalDepth, _passLight, _passLightFullscreen, _passFinal, _passFXAA;
|
|
|
-
|
|
|
- var _depthTexture;
|
|
|
-
|
|
|
- var _currentCamera;
|
|
|
-
|
|
|
- var _lightScene, _lightFullscreenScene;
|
|
|
-
|
|
|
- var _antialias = false;
|
|
|
- var _hasTransparentObject = false;
|
|
|
- var _lightPrePass = false;
|
|
|
- var _cacheKeepAlive = false;
|
|
|
-
|
|
|
- var _tmpMaterial = new THREE.ShaderMaterial( { visible: false } );
|
|
|
- var _tmpVector3 = new THREE.Vector3();
|
|
|
-
|
|
|
- // scene/material/light cache for deferred rendering.
|
|
|
- // save them at the creation and release
|
|
|
- // if they're unused removeThresholdCount frames
|
|
|
- // unless _cacheKeepAlive is true.
|
|
|
-
|
|
|
- // scene.uuid -> lightScene, lightFullscreenScene
|
|
|
- var _lightScenesCache = {};
|
|
|
- var _lightFullscreenScenesCache = {};
|
|
|
-
|
|
|
- // object.material.uuid -> deferredMaterial or
|
|
|
- // object.material[ n ].uuid -> deferredMaterial
|
|
|
- var _normalDepthMaterialsCache = {};
|
|
|
- var _normalDepthShininessMaterialsCache = {};
|
|
|
- var _colorMaterialsCache = {};
|
|
|
- var _reconstructionMaterialsCache = {};
|
|
|
-
|
|
|
- // originalLight.uuid -> deferredLight
|
|
|
- var _deferredLightsCache = {};
|
|
|
-
|
|
|
- // deferredLight.uuid -> deferredLightMaterial
|
|
|
- var _classicDeferredLightMaterialsCache = {};
|
|
|
- var _lightPrePassMaterialsCache = {};
|
|
|
-
|
|
|
- var _removeThresholdCount = 60;
|
|
|
-
|
|
|
- // deferredMaterials.uuid -> object.material or
|
|
|
- // deferredMaterials.uuid -> object.material[ n ]
|
|
|
- // save before render and release after render.
|
|
|
- var _originalMaterialsTable = {};
|
|
|
-
|
|
|
- // object.uuid -> originalOnBeforeRender
|
|
|
- // save before render and release after render.
|
|
|
- var _originalOnBeforeRendersTable = {};
|
|
|
-
|
|
|
- // object.material.uuid -> object.material.visible or
|
|
|
- // object.material[ i ].uuid -> object.material[ i ].visible or
|
|
|
- // save before render and release after render.
|
|
|
- var _originalVisibleTable = {};
|
|
|
-
|
|
|
- // external properties
|
|
|
-
|
|
|
- this.renderer = undefined;
|
|
|
- this.domElement = undefined;
|
|
|
-
|
|
|
- this.forwardRendering = false; // for debug
|
|
|
-
|
|
|
- // private methods
|
|
|
-
|
|
|
- function init( parameters ) {
|
|
|
-
|
|
|
- _this.renderer = parameters.renderer !== undefined ? parameters.renderer : new THREE.WebGLRenderer();
|
|
|
- _this.domElement = _this.renderer.domElement;
|
|
|
-
|
|
|
- _context = _this.renderer.getContext();
|
|
|
- _state = _this.renderer.state;
|
|
|
-
|
|
|
- _width = parameters.width !== undefined ? parameters.width : _this.renderer.getSize( new THREE.Vector2() ).width;
|
|
|
- _height = parameters.height !== undefined ? parameters.height : _this.renderer.getSize( new THREE.Vector2() ).height;
|
|
|
-
|
|
|
- var antialias = parameters.antialias !== undefined ? parameters.antialias : false;
|
|
|
-
|
|
|
- if ( parameters.cacheKeepAlive !== undefined ) _cacheKeepAlive = parameters.cacheKeepAlive;
|
|
|
-
|
|
|
- initDepthTexture();
|
|
|
-
|
|
|
- initPassNormalDepth();
|
|
|
- initPassColor();
|
|
|
- initPassLight();
|
|
|
- initPassReconstruction();
|
|
|
- initPassFinal();
|
|
|
-
|
|
|
- _this.setSize( _width, _height );
|
|
|
- _this.setAntialias( antialias );
|
|
|
- _this.enableLightPrePass( false );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function initDepthTexture() {
|
|
|
-
|
|
|
- _depthTexture = new THREE.DepthTexture(
|
|
|
- _width,
|
|
|
- _height,
|
|
|
- THREE.UnsignedInt248Type,
|
|
|
- undefined,
|
|
|
- undefined,
|
|
|
- undefined,
|
|
|
- undefined,
|
|
|
- undefined,
|
|
|
- undefined,
|
|
|
- THREE.DepthStencilFormat
|
|
|
- );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function initPassNormalDepth() {
|
|
|
-
|
|
|
- _passNormalDepth = new THREE.RenderPass();
|
|
|
- _passNormalDepth.clear = true;
|
|
|
-
|
|
|
- var rt = new THREE.WebGLRenderTarget( _width, _height, {
|
|
|
- minFilter: THREE.NearestFilter,
|
|
|
- magFilter: THREE.NearestFilter,
|
|
|
- format: THREE.RGBAFormat,
|
|
|
- type: THREE.FloatType,
|
|
|
- stencilBuffer: true,
|
|
|
- depthTexture: _depthTexture
|
|
|
- } );
|
|
|
-
|
|
|
- rt.texture.generateMipamps = false;
|
|
|
-
|
|
|
- _compNormalDepth = new THREE.EffectComposer( _this.renderer, rt );
|
|
|
- _compNormalDepth.renderToScreen = false;
|
|
|
- _compNormalDepth.addPass( _passNormalDepth );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function initPassColor() {
|
|
|
-
|
|
|
- _passColor = new THREE.RenderPass();
|
|
|
- _passColor.clear = true;
|
|
|
-
|
|
|
- var rt = new THREE.WebGLRenderTarget( _width, _height, {
|
|
|
- minFilter: THREE.NearestFilter,
|
|
|
- magFilter: THREE.NearestFilter,
|
|
|
- format: THREE.RGBAFormat,
|
|
|
- type: THREE.FloatType,
|
|
|
- depthTexture: _depthTexture
|
|
|
- } );
|
|
|
-
|
|
|
- rt.texture.generateMipamps = false;
|
|
|
-
|
|
|
- _compColor = new THREE.EffectComposer( _this.renderer, rt );
|
|
|
- _compColor.renderToScreen = false;
|
|
|
- _compColor.addPass( _passColor );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function initPassLight() {
|
|
|
-
|
|
|
- _passLightFullscreen = new THREE.RenderPass();
|
|
|
- _passLightFullscreen.clear = true;
|
|
|
- _passLightFullscreen.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
|
|
|
-
|
|
|
- _passLight = new THREE.RenderPass();
|
|
|
- _passLight.clear = false;
|
|
|
-
|
|
|
- var rt = new THREE.WebGLRenderTarget( _width, _height, {
|
|
|
- minFilter: THREE.NearestFilter,
|
|
|
- magFilter: THREE.NearestFilter,
|
|
|
- format: THREE.RGBAFormat,
|
|
|
- type: THREE.FloatType,
|
|
|
- depthTexture: _depthTexture
|
|
|
- } );
|
|
|
-
|
|
|
- rt.texture.generateMipamps = false;
|
|
|
-
|
|
|
- _compLight = new THREE.EffectComposer( _this.renderer, rt );
|
|
|
- _compLight.renderToScreen = false;
|
|
|
- _compLight.addPass( _passLightFullscreen );
|
|
|
- _compLight.addPass( _passLight );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function initPassReconstruction() {
|
|
|
-
|
|
|
- _passReconstruction = new THREE.RenderPass();
|
|
|
- _passReconstruction.clear = true;
|
|
|
-
|
|
|
- var rt = new THREE.WebGLRenderTarget( _width, _height, {
|
|
|
- minFilter: THREE.NearestFilter,
|
|
|
- magFilter: THREE.NearestFilter,
|
|
|
- format: THREE.RGBAFormat,
|
|
|
- type: THREE.FloatType,
|
|
|
- depthTexture: _depthTexture
|
|
|
- } );
|
|
|
-
|
|
|
- rt.texture.generateMipamps = false;
|
|
|
-
|
|
|
- _compReconstruction = new THREE.EffectComposer( _this.renderer, rt );
|
|
|
- _compReconstruction.renderToScreen = false;
|
|
|
- _compReconstruction.addPass( _passReconstruction );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function initPassFinal() {
|
|
|
-
|
|
|
- _passFinal = new THREE.ShaderPass( THREE.ShaderDeferred[ 'final' ] );
|
|
|
- _passFinal.clear = true;
|
|
|
- _passFinal.uniforms.samplerResult.value = _compLight.renderTarget2.texture;
|
|
|
- _passFinal.material.blending = THREE.NoBlending;
|
|
|
- _passFinal.material.depthWrite = false;
|
|
|
- _passFinal.material.depthTest = false;
|
|
|
-
|
|
|
- _passForward = new THREE.RenderPass();
|
|
|
- _passForward.clear = false;
|
|
|
-
|
|
|
- _passCopy = new THREE.ShaderPass( THREE.CopyShader );
|
|
|
-
|
|
|
- _passFXAA = new THREE.ShaderPass( THREE.FXAAShader );
|
|
|
-
|
|
|
- var rt = new THREE.WebGLRenderTarget( _width, _height, {
|
|
|
- minFilter: THREE.NearestFilter,
|
|
|
- magFilter: THREE.LinearFilter,
|
|
|
- format: THREE.RGBFormat,
|
|
|
- type: THREE.UnsignedByteType,
|
|
|
- depthTexture: _depthTexture
|
|
|
- } );
|
|
|
-
|
|
|
- rt.texture.generateMipamps = false;
|
|
|
-
|
|
|
- _compFinal = new THREE.EffectComposer( _this.renderer, rt );
|
|
|
- _compFinal.addPass( _passFinal );
|
|
|
- _compFinal.addPass( _passForward );
|
|
|
- _compFinal.addPass( _passCopy );
|
|
|
- _compFinal.addPass( _passFXAA );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function initLightScene( scene ) {
|
|
|
-
|
|
|
- var lightSceneData = _lightScenesCache[ scene.uuid ];
|
|
|
- var lightFullscreenSceneData = _lightFullscreenScenesCache[ scene.uuid ];
|
|
|
-
|
|
|
- if ( lightSceneData === undefined ) {
|
|
|
-
|
|
|
- var s = new THREE.Scene();
|
|
|
- s.userData.lights = {};
|
|
|
-
|
|
|
- lightSceneData = createCacheData();
|
|
|
- lightSceneData.scene = s;
|
|
|
-
|
|
|
- _lightScenesCache[ scene.uuid ] = lightSceneData;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( lightFullscreenSceneData === undefined ) {
|
|
|
-
|
|
|
- var s = new THREE.Scene();
|
|
|
- s.userData.lights = {};
|
|
|
-
|
|
|
- var emissiveLight = createDeferredEmissiveLight();
|
|
|
-
|
|
|
- s.userData.emissiveLight = emissiveLight;
|
|
|
- s.add( emissiveLight );
|
|
|
-
|
|
|
- lightFullscreenSceneData = createCacheData();
|
|
|
- lightFullscreenSceneData.scene = s;
|
|
|
-
|
|
|
- _lightFullscreenScenesCache[ scene.uuid ] = lightFullscreenSceneData;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- lightSceneData.used = true;
|
|
|
- lightFullscreenSceneData.used = true;
|
|
|
-
|
|
|
- var lightScene = lightSceneData.scene;
|
|
|
- var lightFullscreenScene = lightFullscreenSceneData.scene;
|
|
|
-
|
|
|
- // emissiveLight is only for Classic Deferred Rendering
|
|
|
- lightFullscreenScene.userData.emissiveLight.visible = ! _lightPrePass;
|
|
|
-
|
|
|
- _lightScene = lightScene;
|
|
|
- _lightFullscreenScene = lightFullscreenScene;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function getMaterialFromCacheOrCreate( originalMaterial, cache, createFunc, updateFunc ) {
|
|
|
-
|
|
|
- var data = cache[ originalMaterial.uuid ];
|
|
|
-
|
|
|
- if ( data === undefined ) {
|
|
|
-
|
|
|
- data = createCacheData();
|
|
|
- data.material = createFunc( originalMaterial );
|
|
|
- cache[ originalMaterial.uuid ] = data;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- data.used = true;
|
|
|
-
|
|
|
- updateFunc( data.material, originalMaterial );
|
|
|
-
|
|
|
- _originalMaterialsTable[ data.material.uuid ] = originalMaterial;
|
|
|
-
|
|
|
- return data.material;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function overrideMaterialAndOnBeforeRender( object, getMaterialFunc, onBeforeRender ) {
|
|
|
-
|
|
|
- if ( object.material === undefined ) return;
|
|
|
-
|
|
|
- if ( Array.isArray( object.material ) ) {
|
|
|
-
|
|
|
- for ( var i = 0, il = object.material.length; i < il; i ++ ) {
|
|
|
-
|
|
|
- object.material[ i ] = getMaterialFunc( object.material[ i ] );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- object.material = getMaterialFunc( object.material );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- object.onBeforeRender = onBeforeRender;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function restoreOriginalMaterial( object ) {
|
|
|
-
|
|
|
- if ( object.material === undefined ) return;
|
|
|
-
|
|
|
- if ( Array.isArray( object.material ) ) {
|
|
|
-
|
|
|
- for ( var i = 0, il = object.material.length; i < il; i ++ ) {
|
|
|
-
|
|
|
- object.material[ i ] = _originalMaterialsTable[ object.material[ i ].uuid ];
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- object.material = _originalMaterialsTable[ object.material.uuid ];
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function setMaterialNormalDepth( object ) {
|
|
|
-
|
|
|
- overrideMaterialAndOnBeforeRender( object, getNormalDepthMaterial, updateDeferredNormalDepthUniforms );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function getNormalDepthMaterial( originalMaterial ) {
|
|
|
-
|
|
|
- return getMaterialFromCacheOrCreate(
|
|
|
- originalMaterial,
|
|
|
- ( _lightPrePass ) ? _normalDepthShininessMaterialsCache : _normalDepthMaterialsCache,
|
|
|
- createDeferredNormalDepthMaterial,
|
|
|
- updateDeferredNormalDepthMaterial
|
|
|
- );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function createDeferredNormalDepthMaterial() {
|
|
|
-
|
|
|
- var shader = ( _lightPrePass ) ? THREE.ShaderDeferred[ 'normalDepthShininess' ] : THREE.ShaderDeferred[ 'normalDepth' ];
|
|
|
-
|
|
|
- return new THREE.ShaderMaterial( {
|
|
|
- uniforms: Object.assign( {}, shader.uniforms ),
|
|
|
- fragmentShader: shader.fragmentShader,
|
|
|
- vertexShader: shader.vertexShader,
|
|
|
- blending: THREE.NoBlending
|
|
|
- } );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function updateDeferredNormalDepthMaterial( material, originalMaterial ) {
|
|
|
-
|
|
|
- if ( originalMaterial.skinning !== undefined ) material.skinning = originalMaterial.skinning;
|
|
|
- if ( originalMaterial.morphTargets !== undefined ) material.morphTargets = originalMaterial.morphTargets;
|
|
|
-
|
|
|
- if ( originalMaterial.visible === true ) {
|
|
|
-
|
|
|
- material.visible = ! originalMaterial.transparent;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- material.visible = false;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function updateDeferredNormalDepthUniforms( renderer, scene, camera, geometry, material ) {
|
|
|
-
|
|
|
- if ( ! _lightPrePass ) return;
|
|
|
-
|
|
|
- var originalMaterial = _originalMaterialsTable[ material.uuid ];
|
|
|
-
|
|
|
- if ( originalMaterial === undefined || originalMaterial.shininess === undefined ) return;
|
|
|
-
|
|
|
- material.uniforms.shininess.value = originalMaterial.shininess;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function setMaterialColor( object ) {
|
|
|
-
|
|
|
- overrideMaterialAndOnBeforeRender( object, getColorMaterial, updateDeferredColorUniforms );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function getColorMaterial( originalMaterial ) {
|
|
|
-
|
|
|
- return getMaterialFromCacheOrCreate(
|
|
|
- originalMaterial,
|
|
|
- _colorMaterialsCache,
|
|
|
- createDeferredColorMaterial,
|
|
|
- updateDeferredColorMaterial
|
|
|
- );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function createDeferredColorMaterial( originalMaterial ) {
|
|
|
-
|
|
|
- var shader = THREE.ShaderDeferred[ 'color' ];
|
|
|
-
|
|
|
- var material = new THREE.ShaderMaterial( {
|
|
|
- uniforms: Object.assign( {}, shader.uniforms ),
|
|
|
- fragmentShader: shader.fragmentShader,
|
|
|
- vertexShader: shader.vertexShader,
|
|
|
- blending: THREE.NoBlending
|
|
|
- } );
|
|
|
-
|
|
|
- if ( originalMaterial.map !== undefined ) material.map = originalMaterial.map;
|
|
|
-
|
|
|
- return material;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function updateDeferredColorMaterial( material, originalMaterial ) {
|
|
|
-
|
|
|
- if ( originalMaterial.map !== undefined ) material.map = originalMaterial.map;
|
|
|
- if ( originalMaterial.skinning !== undefined ) material.skinning = originalMaterial.skinning;
|
|
|
- if ( originalMaterial.morphTargets !== undefined ) material.morphTargets = originalMaterial.morphTargets;
|
|
|
-
|
|
|
- if ( originalMaterial.visible === true ) {
|
|
|
-
|
|
|
- material.visible = ! originalMaterial.transparent;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- material.visible = false;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function updateDeferredColorUniforms( renderer, scene, camera, geometry, material ) {
|
|
|
-
|
|
|
- var originalMaterial = _originalMaterialsTable[ material.uuid ];
|
|
|
- var uniforms = material.uniforms;
|
|
|
-
|
|
|
- var diffuse, emissive;
|
|
|
-
|
|
|
- if ( originalMaterial.isMeshBasicMaterial === true ) {
|
|
|
-
|
|
|
- emissive = originalMaterial.color;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- diffuse = originalMaterial.color;
|
|
|
- emissive = originalMaterial.emissive;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var specular = originalMaterial.specular;
|
|
|
- var shininess = originalMaterial.shininess;
|
|
|
- var map = originalMaterial.map;
|
|
|
-
|
|
|
- if ( diffuse !== undefined ) uniforms.diffuse.value.copy( diffuse );
|
|
|
- if ( emissive !== undefined ) uniforms.emissive.value.copy( emissive );
|
|
|
- if ( specular !== undefined ) uniforms.specular.value.copy( specular );
|
|
|
- if ( shininess !== undefined && uniforms.shininess !== undefined ) uniforms.shininess.value = shininess;
|
|
|
- if ( map !== undefined ) uniforms.map.value = map;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function setMaterialReconstruction( object ) {
|
|
|
-
|
|
|
- overrideMaterialAndOnBeforeRender( object, getReconstructionMaterial, updateDeferredReconstructionUniforms );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function getReconstructionMaterial( originalMaterial ) {
|
|
|
-
|
|
|
- if ( originalMaterial.transparent === true ) {
|
|
|
-
|
|
|
- _originalMaterialsTable[ originalMaterial.uuid ] = originalMaterial;
|
|
|
- return originalMaterial;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- return getMaterialFromCacheOrCreate(
|
|
|
- originalMaterial,
|
|
|
- _reconstructionMaterialsCache,
|
|
|
- createDeferredReconstructionMaterial,
|
|
|
- updateDeferredReconstructionMaterial
|
|
|
- );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function createDeferredReconstructionMaterial( originalMaterial ) {
|
|
|
-
|
|
|
- var shader = THREE.ShaderDeferred[ 'reconstruction' ];
|
|
|
-
|
|
|
- var material = new THREE.ShaderMaterial( {
|
|
|
- uniforms: Object.assign( {}, shader.uniforms ),
|
|
|
- fragmentShader: shader.fragmentShader,
|
|
|
- vertexShader: shader.vertexShader,
|
|
|
- blending: THREE.NoBlending
|
|
|
- } );
|
|
|
-
|
|
|
- if ( originalMaterial.map !== undefined ) material.map = originalMaterial.map;
|
|
|
-
|
|
|
- return material;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function updateDeferredReconstructionMaterial( material, originalMaterial ) {
|
|
|
-
|
|
|
- updateDeferredColorMaterial( material, originalMaterial );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function updateDeferredReconstructionUniforms( renderer, scene, camera, geometry, material, group ) {
|
|
|
-
|
|
|
- if ( material.transparent === true ) {
|
|
|
-
|
|
|
- // 'this' is object here because this method is set as object.onBefore()
|
|
|
- var onBeforeRender = _originalOnBeforeRendersTable[ this.uuid ];
|
|
|
-
|
|
|
- if ( onBeforeRender ) {
|
|
|
-
|
|
|
- onBeforeRender.call( this, renderer, scene, camera, geometry, material, group );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- return;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- updateDeferredColorUniforms( renderer, scene, camera, geometry, material );
|
|
|
-
|
|
|
- material.uniforms.samplerLight.value = _compLight.renderTarget2.texture;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function setVisibleForForwardRendering( object ) {
|
|
|
-
|
|
|
- if ( object.material === undefined ) return;
|
|
|
-
|
|
|
- if ( Array.isArray( object.material ) ) {
|
|
|
-
|
|
|
- for ( var i = 0, il = object.material.length; i < il; i ++ ) {
|
|
|
-
|
|
|
- if ( _originalVisibleTable[ object.material[ i ].uuid ] === undefined ) {
|
|
|
-
|
|
|
- _originalVisibleTable[ object.material[ i ].uuid ] = object.material[ i ].visible;
|
|
|
- object.material[ i ].visible = object.material[ i ].transparent && object.material[ i ].visible;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- if ( _originalVisibleTable[ object.material.uuid ] === undefined ) {
|
|
|
-
|
|
|
- _originalVisibleTable[ object.material.uuid ] = object.material.visible;
|
|
|
- object.material.visible = object.material.transparent && object.material.visible;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function restoreVisible( object ) {
|
|
|
-
|
|
|
- if ( object.material === undefined ) return;
|
|
|
-
|
|
|
- if ( Array.isArray( object.material ) ) {
|
|
|
-
|
|
|
- for ( var i = 0, il = object.material.length; i < il; i ++ ) {
|
|
|
-
|
|
|
- object.material[ i ].visible = _originalVisibleTable[ object.material[ i ].uuid ];
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- object.material.visible = _originalVisibleTable[ object.material.uuid ];
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function createDeferredEmissiveLight() {
|
|
|
-
|
|
|
- var shader = THREE.ShaderDeferred[ 'emissiveLight' ];
|
|
|
-
|
|
|
- var material = new THREE.ShaderMaterial( {
|
|
|
- uniforms: Object.assign( {}, shader.uniforms ),
|
|
|
- vertexShader: shader.vertexShader,
|
|
|
- fragmentShader: shader.fragmentShader,
|
|
|
- blending: THREE.NoBlending,
|
|
|
- depthWrite: false
|
|
|
- } );
|
|
|
-
|
|
|
- var geometry = new THREE.PlaneBufferGeometry( 2, 2 );
|
|
|
- var mesh = new THREE.Mesh( geometry, material );
|
|
|
-
|
|
|
- mesh.onBeforeRender = function ( renderer, scene, camera, geometry, material ) {
|
|
|
-
|
|
|
- material.uniforms.samplerColor.value = _compColor.renderTarget2.texture;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- return mesh;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function createDeferredLight( originalLight ) {
|
|
|
-
|
|
|
- if ( originalLight.isPointLight ) {
|
|
|
-
|
|
|
- return createDeferredPointLight( originalLight );
|
|
|
-
|
|
|
- } else if ( originalLight.isSpotLight ) {
|
|
|
-
|
|
|
- return createDeferredSpotLight( originalLight );
|
|
|
-
|
|
|
- } else if ( originalLight.isDirectionalLight ) {
|
|
|
-
|
|
|
- return createDeferredDirectionalLight( originalLight );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- return null;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function createDeferredLightMaterial( originalLight ) {
|
|
|
-
|
|
|
- if ( originalLight.isPointLight ) {
|
|
|
-
|
|
|
- return createDeferredPointLightMaterial();
|
|
|
-
|
|
|
- } else if ( originalLight.isSpotLight ) {
|
|
|
-
|
|
|
- return createDeferredSpotLightMaterial();
|
|
|
-
|
|
|
- } else if ( originalLight.isDirectionalLight ) {
|
|
|
-
|
|
|
- return createDeferredDirectionalLightMaterial();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- return null;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function getDeferredLightMaterial( light ) {
|
|
|
-
|
|
|
- var cache = ( _lightPrePass ) ? _lightPrePassMaterialsCache : _classicDeferredLightMaterialsCache;
|
|
|
-
|
|
|
- var data = cache[ light.uuid ];
|
|
|
-
|
|
|
- if ( data === undefined ) {
|
|
|
-
|
|
|
- data = createCacheData();
|
|
|
- data.material = createDeferredLightMaterial( light.userData.originalLight );
|
|
|
- cache[ light.uuid ] = data;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- data.used = true;
|
|
|
-
|
|
|
- return data.material;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function updateDeferredLight( light ) {
|
|
|
-
|
|
|
- var originalLight = light.userData.originalLight;
|
|
|
-
|
|
|
- if ( originalLight.isPointLight ) {
|
|
|
-
|
|
|
- updateDeferredPointLight( light );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function createDeferredLightMesh( light, geometry ) {
|
|
|
-
|
|
|
- var mesh = new THREE.Mesh( geometry, _tmpMaterial );
|
|
|
-
|
|
|
- mesh.userData.originalLight = light;
|
|
|
-
|
|
|
- return mesh;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function createDeferredLightShaderMaterial( shader ) {
|
|
|
-
|
|
|
- var material = new THREE.ShaderMaterial( {
|
|
|
- uniforms: Object.assign( {}, shader.uniforms ),
|
|
|
- vertexShader: shader.vertexShader,
|
|
|
- fragmentShader: shader.fragmentShader,
|
|
|
- transparent: true,
|
|
|
- blending: THREE.AdditiveBlending,
|
|
|
- depthWrite: false
|
|
|
- } );
|
|
|
-
|
|
|
- if ( _lightPrePass ) material.premultipliedAlpha = true;
|
|
|
-
|
|
|
- return material;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function updateDeferredLightCommonUniforms( uniforms ) {
|
|
|
-
|
|
|
- if ( _lightPrePass ) {
|
|
|
-
|
|
|
- uniforms.samplerNormalDepthShininess.value = _compNormalDepth.renderTarget2.texture;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- uniforms.samplerNormalDepth.value = _compNormalDepth.renderTarget2.texture;
|
|
|
- uniforms.samplerColor.value = _compColor.renderTarget2.texture;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function createDeferredPointLight( light ) {
|
|
|
-
|
|
|
- var mesh = createDeferredLightMesh( light, new THREE.SphereBufferGeometry( 1, 16, 8 ) );
|
|
|
- mesh.onBeforeRender = updateDeferredPointLightUniforms;
|
|
|
- return mesh;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * optimization:
|
|
|
- * Renders PointLight only back face with stencil test.
|
|
|
- */
|
|
|
- function createDeferredPointLightMaterial() {
|
|
|
-
|
|
|
- var shader = ( _lightPrePass ) ? THREE.ShaderDeferred[ 'pointLightPre' ] : THREE.ShaderDeferred[ 'pointLight' ];
|
|
|
-
|
|
|
- var material = createDeferredLightShaderMaterial( shader );
|
|
|
-
|
|
|
- material.side = THREE.BackSide;
|
|
|
- material.depthFunc = THREE.GreaterEqualDepth;
|
|
|
-
|
|
|
- return material;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function updateDeferredPointLight( light ) {
|
|
|
-
|
|
|
- var originalLight = light.userData.originalLight;
|
|
|
- var distance = originalLight.distance;
|
|
|
-
|
|
|
- if ( distance > 0 ) {
|
|
|
-
|
|
|
- light.scale.set( 1, 1, 1 ).multiplyScalar( distance );
|
|
|
- light.position.setFromMatrixPosition( originalLight.matrixWorld );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function updateDeferredPointLightUniforms( renderer, scene, camera, geometry, material ) {
|
|
|
-
|
|
|
- var light = this;
|
|
|
-
|
|
|
- var originalLight = light.userData.originalLight;
|
|
|
- var distance = originalLight.distance;
|
|
|
- var uniforms = material.uniforms;
|
|
|
-
|
|
|
- uniforms.lightColor.value.copy( originalLight.color );
|
|
|
-
|
|
|
- if ( distance > 0 ) {
|
|
|
-
|
|
|
- uniforms.lightRadius.value = distance;
|
|
|
- uniforms.lightIntensity.value = originalLight.intensity;
|
|
|
- uniforms.lightPositionVS.value.setFromMatrixPosition( originalLight.matrixWorld ).applyMatrix4( _currentCamera.matrixWorldInverse );
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- uniforms.lightRadius.value = Infinity;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- updateDeferredLightCommonUniforms( uniforms );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function createDeferredSpotLight( light ) {
|
|
|
-
|
|
|
- var mesh = createDeferredLightMesh( light, new THREE.PlaneBufferGeometry( 2, 2 ) );
|
|
|
- mesh.onBeforeRender = updateDeferredSpotLightUniforms;
|
|
|
- return mesh;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function createDeferredSpotLightMaterial() {
|
|
|
-
|
|
|
- var shader = ( _lightPrePass ) ? THREE.ShaderDeferred[ 'spotLightPre' ] : THREE.ShaderDeferred[ 'spotLight' ];
|
|
|
-
|
|
|
- var material = createDeferredLightShaderMaterial( shader );
|
|
|
-
|
|
|
- material.depthTest = false;
|
|
|
-
|
|
|
- return material;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function updateDeferredSpotLightUniforms() {
|
|
|
-
|
|
|
- var light = this;
|
|
|
-
|
|
|
- var originalLight = light.userData.originalLight;
|
|
|
- var uniforms = light.material.uniforms;
|
|
|
-
|
|
|
- uniforms.lightAngle.value = originalLight.angle;
|
|
|
- uniforms.lightColor.value.copy( originalLight.color );
|
|
|
- uniforms.lightIntensity.value = originalLight.intensity;
|
|
|
- uniforms.lightPositionVS.value.setFromMatrixPosition( originalLight.matrixWorld ).applyMatrix4( _currentCamera.matrixWorldInverse );
|
|
|
-
|
|
|
- var vec = uniforms.lightDirectionVS.value;
|
|
|
- var vec2 = _tmpVector3;
|
|
|
-
|
|
|
- vec.setFromMatrixPosition( originalLight.matrixWorld );
|
|
|
- vec2.setFromMatrixPosition( originalLight.target.matrixWorld );
|
|
|
- vec.sub( vec2 ).normalize().transformDirection( _currentCamera.matrixWorldInverse );
|
|
|
-
|
|
|
- updateDeferredLightCommonUniforms( uniforms );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function createDeferredDirectionalLight( light ) {
|
|
|
-
|
|
|
- var mesh = createDeferredLightMesh( light, new THREE.PlaneBufferGeometry( 2, 2 ) );
|
|
|
- mesh.onBeforeRender = updateDeferredDirectionalLightUniforms;
|
|
|
- return mesh;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function createDeferredDirectionalLightMaterial() {
|
|
|
-
|
|
|
- var shader = ( _lightPrePass ) ? THREE.ShaderDeferred[ 'directionalLightPre' ] : THREE.ShaderDeferred[ 'directionalLight' ];
|
|
|
-
|
|
|
- var material = createDeferredLightShaderMaterial( shader );
|
|
|
-
|
|
|
- material.depthTest = false;
|
|
|
-
|
|
|
- return material;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function updateDeferredDirectionalLightUniforms() {
|
|
|
-
|
|
|
- var light = this;
|
|
|
-
|
|
|
- var originalLight = light.userData.originalLight;
|
|
|
- var uniforms = light.material.uniforms;
|
|
|
-
|
|
|
- uniforms.lightColor.value.copy( originalLight.color );
|
|
|
- uniforms.lightIntensity.value = originalLight.intensity;
|
|
|
-
|
|
|
- var vec = uniforms.lightDirectionVS.value;
|
|
|
- var vec2 = _tmpVector3;
|
|
|
-
|
|
|
- vec.setFromMatrixPosition( originalLight.matrixWorld );
|
|
|
- vec2.setFromMatrixPosition( originalLight.target.matrixWorld );
|
|
|
- vec.sub( vec2 ).normalize().transformDirection( _currentCamera.matrixWorldInverse );
|
|
|
-
|
|
|
- updateDeferredLightCommonUniforms( uniforms );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function saveOriginalOnBeforeRenderAndCheckTransparency( object ) {
|
|
|
-
|
|
|
- if ( object.material === undefined ) return;
|
|
|
-
|
|
|
- _originalOnBeforeRendersTable[ object.uuid ] = object.onBeforeRender;
|
|
|
-
|
|
|
- // _hasTransparentObject is used only for Classic Deferred Rendering
|
|
|
- if ( _hasTransparentObject || _lightPrePass ) return;
|
|
|
-
|
|
|
- if ( ! object.visible ) return;
|
|
|
-
|
|
|
- if ( Array.isArray( object.material ) ) {
|
|
|
-
|
|
|
- for ( var i = 0, il = object.material.length; i < il; i ++ ) {
|
|
|
-
|
|
|
- if ( object.material[ i ].visible === true && object.material[ i ].transparent === true ) {
|
|
|
-
|
|
|
- _hasTransparentObject = true;
|
|
|
- break;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- if ( object.material.visible === true && object.material.transparent === true ) _hasTransparentObject = true;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function restoreOriginalOnBeforeRender( object ) {
|
|
|
-
|
|
|
- if ( object.material === undefined ) return;
|
|
|
-
|
|
|
- object.onBeforeRender = _originalOnBeforeRendersTable[ object.uuid ];
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function addDeferredLightsToLightScene( object ) {
|
|
|
-
|
|
|
- if ( object.isLight !== true ) return;
|
|
|
-
|
|
|
- var data = _deferredLightsCache[ object.uuid ];
|
|
|
-
|
|
|
- if ( data === undefined ) {
|
|
|
-
|
|
|
- data = createCacheData();
|
|
|
- data.light = createDeferredLight( object );
|
|
|
- _deferredLightsCache[ object.uuid ] = data;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- data.used = true;
|
|
|
-
|
|
|
- var light = data.light;
|
|
|
-
|
|
|
- if ( light === null ) return;
|
|
|
-
|
|
|
- var scene = ( object.isPointLight === true ) ? _lightScene : _lightFullscreenScene;
|
|
|
-
|
|
|
- var lights = scene.userData.lights;
|
|
|
-
|
|
|
- if ( lights[ light.uuid ] === undefined ) {
|
|
|
-
|
|
|
- scene.add( light );
|
|
|
-
|
|
|
- lights[ light.uuid ] = {
|
|
|
- light: light,
|
|
|
- found: true
|
|
|
- };
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- lights[ light.uuid ].found = true;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function updateDeferredLightsInLightScene( scene ) {
|
|
|
-
|
|
|
- var lights = scene.userData.lights;
|
|
|
- var keys = Object.keys( lights );
|
|
|
-
|
|
|
- for ( var i = 0, il = keys.length; i < il; i ++ ) {
|
|
|
-
|
|
|
- var key = keys[ i ];
|
|
|
-
|
|
|
- if ( lights[ key ].found === false ) {
|
|
|
-
|
|
|
- scene.remove( lights[ key ].light );
|
|
|
- delete lights[ key ];
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- var light = lights[ key ].light;
|
|
|
- light.material = getDeferredLightMaterial( light );
|
|
|
-
|
|
|
- updateDeferredLight( light );
|
|
|
- lights[ key ].found = false;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function updateDeferredCommonUniforms( camera ) {
|
|
|
-
|
|
|
- var uniforms = THREE.ShaderDeferredCommon[ 'commonUniforms' ];
|
|
|
-
|
|
|
- uniforms.viewWidth.value = _width;
|
|
|
- uniforms.viewHeight.value = _height;
|
|
|
-
|
|
|
- uniforms.matProjInverse.value.getInverse( camera.projectionMatrix );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function enableFinalPasses() {
|
|
|
-
|
|
|
- if ( _lightPrePass ) {
|
|
|
-
|
|
|
- _passForward.enabled = false;
|
|
|
- _passCopy.enabled = false;
|
|
|
-
|
|
|
- if ( _antialias ) {
|
|
|
-
|
|
|
- _passFXAA.enabled = true;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- _passFXAA.enabled = false;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- if ( _hasTransparentObject ) {
|
|
|
-
|
|
|
- if ( _antialias ) {
|
|
|
-
|
|
|
- _passForward.enabled = true;
|
|
|
- _passCopy.enabled = false;
|
|
|
- _passFXAA.enabled = true;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- _passForward.enabled = true;
|
|
|
- _passCopy.enabled = true;
|
|
|
- _passFXAA.enabled = false;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- if ( _antialias ) {
|
|
|
-
|
|
|
- _passForward.enabled = false;
|
|
|
- _passCopy.enabled = false;
|
|
|
- _passFXAA.enabled = true;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- _passForward.enabled = false;
|
|
|
- _passCopy.enabled = false;
|
|
|
- _passFXAA.enabled = false;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function createCacheData() {
|
|
|
-
|
|
|
- return {
|
|
|
- used: true,
|
|
|
- keepAlive: _cacheKeepAlive,
|
|
|
- count: 0
|
|
|
- };
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function cleanupCache( cache ) {
|
|
|
-
|
|
|
- var keys = Object.keys( cache );
|
|
|
-
|
|
|
- for ( var i = 0, il = keys.length; i < il; i ++ ) {
|
|
|
-
|
|
|
- var key = keys[ i ];
|
|
|
-
|
|
|
- if ( cache[ key ].used === false ) {
|
|
|
-
|
|
|
- cache[ key ].count ++;
|
|
|
-
|
|
|
- if ( cache[ key ].keepAlive === false && cache[ key ].count > _removeThresholdCount ) {
|
|
|
-
|
|
|
- delete cache[ key ];
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- cache[ key ].used = false;
|
|
|
- cache[ key ].count = 0;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function cleanupTable( table ) {
|
|
|
-
|
|
|
- var keys = Object.keys( table );
|
|
|
-
|
|
|
- for ( var i = 0, il = keys.length; i < il; i ++ ) {
|
|
|
-
|
|
|
- var key = keys[ i ];
|
|
|
-
|
|
|
- table[ key ] = undefined;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function cleanupCaches() {
|
|
|
-
|
|
|
- cleanupCache( _lightScenesCache );
|
|
|
- cleanupCache( _lightFullscreenScenesCache );
|
|
|
- cleanupCache( _normalDepthMaterialsCache );
|
|
|
- cleanupCache( _normalDepthShininessMaterialsCache );
|
|
|
- cleanupCache( _colorMaterialsCache );
|
|
|
- cleanupCache( _reconstructionMaterialsCache );
|
|
|
- cleanupCache( _classicDeferredLightMaterialsCache );
|
|
|
- cleanupCache( _lightPrePassMaterialsCache );
|
|
|
- cleanupCache( _deferredLightsCache );
|
|
|
-
|
|
|
- cleanupTable( _originalMaterialsTable );
|
|
|
- cleanupTable( _originalOnBeforeRendersTable );
|
|
|
- cleanupTable( _originalVisibleTable );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * Classic Deferred Rendering
|
|
|
- *
|
|
|
- * 1) g-buffer normal + depth pass
|
|
|
- *
|
|
|
- * RGB: normal
|
|
|
- * A: depth
|
|
|
- *
|
|
|
- *
|
|
|
- * Light Pre-Pass Rendering
|
|
|
- *
|
|
|
- * 1') g-buffer normal + depth pass + shininess
|
|
|
- *
|
|
|
- * RG: normal
|
|
|
- * B: shininess
|
|
|
- * A: depth
|
|
|
- */
|
|
|
-
|
|
|
- function renderNormalDepth( scene, camera ) {
|
|
|
-
|
|
|
- scene.traverse( setMaterialNormalDepth );
|
|
|
-
|
|
|
- _passNormalDepth.scene = scene;
|
|
|
- _passNormalDepth.camera = camera;
|
|
|
-
|
|
|
- _this.renderer.autoClearDepth = true;
|
|
|
- _this.renderer.autoClearStencil = true;
|
|
|
-
|
|
|
- _state.buffers.stencil.setTest( true );
|
|
|
- _state.buffers.stencil.setFunc( _context.ALWAYS, 1, 0xffffffff );
|
|
|
- _state.buffers.stencil.setOp( _context.REPLACE, _context.REPLACE, _context.REPLACE );
|
|
|
-
|
|
|
- _compNormalDepth.render();
|
|
|
-
|
|
|
- scene.traverse( restoreOriginalMaterial );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * Classic Deferred Rendering
|
|
|
- *
|
|
|
- * 2) g-buffer color pass
|
|
|
- *
|
|
|
- * R: diffuse
|
|
|
- * G: emissive
|
|
|
- * B: specular
|
|
|
- * A: shininess
|
|
|
- */
|
|
|
-
|
|
|
- function renderColor( scene, camera ) {
|
|
|
-
|
|
|
- scene.traverse( setMaterialColor );
|
|
|
-
|
|
|
- _passColor.scene = scene;
|
|
|
- _passColor.camera = camera;
|
|
|
-
|
|
|
- _this.renderer.autoClearDepth = false;
|
|
|
- _this.renderer.autoClearStencil = false;
|
|
|
-
|
|
|
- _state.buffers.stencil.setFunc( _context.EQUAL, 1, 0xffffffff );
|
|
|
- _state.buffers.stencil.setOp( _context.KEEP, _context.KEEP, _context.KEEP );
|
|
|
-
|
|
|
- _compColor.render();
|
|
|
-
|
|
|
- scene.traverse( restoreOriginalMaterial );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * Classic Deferred Rendering
|
|
|
- *
|
|
|
- * 3) light pass
|
|
|
- */
|
|
|
-
|
|
|
- function renderLight( scene, camera ) {
|
|
|
-
|
|
|
- scene.traverse( addDeferredLightsToLightScene );
|
|
|
-
|
|
|
- updateDeferredLightsInLightScene( _lightScene );
|
|
|
- updateDeferredLightsInLightScene( _lightFullscreenScene );
|
|
|
-
|
|
|
- _passLight.scene = _lightScene;
|
|
|
- _passLight.camera = camera;
|
|
|
-
|
|
|
- _passLightFullscreen.scene = _lightFullscreenScene;
|
|
|
-
|
|
|
- _this.renderer.autoClearDepth = false;
|
|
|
- _this.renderer.autoClearStencil = false;
|
|
|
-
|
|
|
- _compLight.render();
|
|
|
-
|
|
|
- _state.buffers.stencil.setTest( false );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * Light Pre-Pass Rendering
|
|
|
- *
|
|
|
- * 2') Light pre pass
|
|
|
- */
|
|
|
-
|
|
|
- function renderLightPre( scene, camera ) {
|
|
|
-
|
|
|
- scene.traverse( addDeferredLightsToLightScene );
|
|
|
-
|
|
|
- updateDeferredLightsInLightScene( _lightScene );
|
|
|
- updateDeferredLightsInLightScene( _lightFullscreenScene );
|
|
|
-
|
|
|
- _passLight.scene = _lightScene;
|
|
|
- _passLight.camera = camera;
|
|
|
-
|
|
|
- _passLightFullscreen.scene = _lightFullscreenScene;
|
|
|
-
|
|
|
- _this.renderer.autoClearDepth = false;
|
|
|
- _this.renderer.autoClearStencil = false;
|
|
|
-
|
|
|
- _state.buffers.stencil.setFunc( _context.EQUAL, 1, 0xffffffff );
|
|
|
- _state.buffers.stencil.setOp( _context.KEEP, _context.KEEP, _context.KEEP );
|
|
|
-
|
|
|
- _compLight.render();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * Light Pre-Pass Rendering
|
|
|
- *
|
|
|
- * 3') Reconstruction pass
|
|
|
- *
|
|
|
- * Transprency handling:
|
|
|
- * Here renders transparent objects with normal forward rendering.
|
|
|
- */
|
|
|
-
|
|
|
- function renderReconstruction( scene, camera ) {
|
|
|
-
|
|
|
- scene.traverse( setMaterialReconstruction );
|
|
|
-
|
|
|
- _passReconstruction.scene = scene;
|
|
|
- _passReconstruction.camera = camera;
|
|
|
-
|
|
|
- _this.renderer.autoClearDepth = false;
|
|
|
- _this.renderer.autoClearStencil = false;
|
|
|
-
|
|
|
- _compReconstruction.render();
|
|
|
-
|
|
|
- _state.buffers.stencil.setTest( false );
|
|
|
-
|
|
|
- scene.traverse( restoreOriginalMaterial );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * Classic Deferred Rendering
|
|
|
- *
|
|
|
- * 4) Final pass
|
|
|
- *
|
|
|
- * transparency handling:
|
|
|
- * If there's any transparent objects, here renders them on the deferred rendering result
|
|
|
- * with normal forward rendering. This may be the easist way but heavy.
|
|
|
- * We should consider any better ways someday.
|
|
|
- *
|
|
|
- *
|
|
|
- * Light Pre-Pass Rendering
|
|
|
- *
|
|
|
- * 4') Final pass
|
|
|
- *
|
|
|
- *
|
|
|
- * Common
|
|
|
- *
|
|
|
- * antialias handling:
|
|
|
- * Here uses postprocessing FXAA for antialias.
|
|
|
- *
|
|
|
- */
|
|
|
-
|
|
|
- function renderFinal( scene, camera ) {
|
|
|
-
|
|
|
- if ( ! _lightPrePass && _hasTransparentObject ) {
|
|
|
-
|
|
|
- scene.traverse( setVisibleForForwardRendering );
|
|
|
- scene.traverse( restoreOriginalOnBeforeRender );
|
|
|
-
|
|
|
- _passForward.scene = scene;
|
|
|
- _passForward.camera = camera;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- enableFinalPasses();
|
|
|
-
|
|
|
- _this.renderer.autoClearDepth = false;
|
|
|
- _this.renderer.autoClearStencil = false;
|
|
|
-
|
|
|
- _compFinal.render();
|
|
|
-
|
|
|
- if ( ! _lightPrePass && _hasTransparentObject ) {
|
|
|
-
|
|
|
- scene.traverse( restoreVisible );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // external APIs
|
|
|
-
|
|
|
- this.setSize = function ( width, height ) {
|
|
|
-
|
|
|
- _width = width;
|
|
|
- _height = height;
|
|
|
-
|
|
|
- this.renderer.setSize( _width, _height );
|
|
|
-
|
|
|
- _compNormalDepth.setSize( _width, _height );
|
|
|
- _compColor.setSize( _width, _height );
|
|
|
- _compLight.setSize( _width, _height );
|
|
|
- _compReconstruction.setSize( _width, _height );
|
|
|
- _compFinal.setSize( _width, _height );
|
|
|
-
|
|
|
- _depthTexture.image.width = _width;
|
|
|
- _depthTexture.image.height = _height;
|
|
|
- _depthTexture.needsUpdate = true;
|
|
|
-
|
|
|
- _passFXAA.uniforms.resolution.value.set( 1 / _width, 1 / _height );
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.setAntialias = function ( enabled ) {
|
|
|
-
|
|
|
- _antialias = enabled;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.enableLightPrePass = function ( enabled ) {
|
|
|
-
|
|
|
- _lightPrePass = enabled;
|
|
|
-
|
|
|
- _passFinal.uniforms.samplerResult.value = ( _lightPrePass ) ? _compReconstruction.renderTarget2.texture : _compLight.renderTarget2.texture;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- this.render = function ( scene, camera ) {
|
|
|
-
|
|
|
- // for debug to compare with normal forward rendering
|
|
|
-
|
|
|
- if ( this.forwardRendering ) {
|
|
|
-
|
|
|
- this.renderer.render( scene, camera );
|
|
|
- return;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var currentSceneAutoUpdate = scene.autoUpdate;
|
|
|
- var currentAutoClearColor = this.renderer.autoClearColor;
|
|
|
- var currentAutoClearDepth = this.renderer.autoClearDepth;
|
|
|
- var currentAutoClearStencil = this.renderer.autoClearStencil;
|
|
|
-
|
|
|
- _currentCamera = camera;
|
|
|
-
|
|
|
- initLightScene( scene );
|
|
|
-
|
|
|
- scene.autoUpdate = false;
|
|
|
- scene.updateMatrixWorld();
|
|
|
-
|
|
|
- _hasTransparentObject = false;
|
|
|
-
|
|
|
- scene.traverse( saveOriginalOnBeforeRenderAndCheckTransparency );
|
|
|
-
|
|
|
- updateDeferredCommonUniforms( camera );
|
|
|
-
|
|
|
- renderNormalDepth( scene, camera );
|
|
|
-
|
|
|
- if ( _lightPrePass ) {
|
|
|
-
|
|
|
- renderLightPre( scene, camera );
|
|
|
- renderReconstruction( scene, camera );
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- renderColor( scene, camera );
|
|
|
- renderLight( scene, camera );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- renderFinal( scene, camera );
|
|
|
-
|
|
|
- scene.traverse( restoreOriginalOnBeforeRender );
|
|
|
-
|
|
|
- cleanupCaches();
|
|
|
-
|
|
|
- scene.autoUpdate = currentSceneAutoUpdate;
|
|
|
- this.renderer.autoClearColor = currentAutoClearColor;
|
|
|
- this.renderer.autoClearDepth = currentAutoClearDepth;
|
|
|
- this.renderer.autoClearStencil = currentAutoClearStencil;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
- // initialize
|
|
|
-
|
|
|
- init( parameters );
|
|
|
-
|
|
|
-};
|
|
|
-
|
|
|
-THREE.DeferredShaderChunk = {
|
|
|
-
|
|
|
- packVector3: [
|
|
|
-
|
|
|
- "float vec3_to_float( vec3 data ) {",
|
|
|
-
|
|
|
- " const float unit = 255.0/256.0;",
|
|
|
- " highp float compressed = fract( data.x * unit ) + floor( data.y * unit * 255.0 ) + floor( data.z * unit * 255.0 ) * 255.0;",
|
|
|
- " return compressed;",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( "\n" ),
|
|
|
-
|
|
|
- unpackFloat: [
|
|
|
-
|
|
|
- "vec3 float_to_vec3( float data ) {",
|
|
|
-
|
|
|
- " const float unit = 255.0;",
|
|
|
- " vec3 uncompressed;",
|
|
|
- " uncompressed.x = fract( data );",
|
|
|
- " float zInt = floor( data / unit );",
|
|
|
- " uncompressed.z = fract( zInt / unit );",
|
|
|
- " uncompressed.y = fract( floor( data - ( zInt * unit ) ) / unit );",
|
|
|
- " return uncompressed;",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( "\n" ),
|
|
|
-
|
|
|
- // Refer to http://aras-p.info/texts/CompactNormalStorage.html
|
|
|
- packNormal: [
|
|
|
-
|
|
|
- "vec2 normal_to_vec2( vec3 normal ) {",
|
|
|
-
|
|
|
- " return normal.xy / sqrt( normal.z * 8.0 + 8.0 ) + 0.5;",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( "\n" ),
|
|
|
-
|
|
|
- unpackVector2: [
|
|
|
-
|
|
|
- "vec3 vec2_to_normal( vec2 data ) {",
|
|
|
-
|
|
|
- " vec2 fenc = data * 4.0 - 2.0;",
|
|
|
- " float f = dot( fenc, fenc );",
|
|
|
- " float g = sqrt( 1.0 - f / 4.0 );",
|
|
|
- " vec3 normal;",
|
|
|
- " normal.xy = fenc * g;",
|
|
|
- " normal.z = 1.0 - f / 2.0;",
|
|
|
- " return normal;",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( "\n" ),
|
|
|
-
|
|
|
- computeTextureCoord: [
|
|
|
-
|
|
|
- "vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );"
|
|
|
-
|
|
|
- ].join( "\n" ),
|
|
|
-
|
|
|
- packNormalDepth: [
|
|
|
-
|
|
|
- "vec4 packedNormalDepth;",
|
|
|
- "packedNormalDepth.xyz = normal * 0.5 + 0.5;",
|
|
|
- "packedNormalDepth.w = position.z / position.w;"
|
|
|
-
|
|
|
- ].join( "\n" ),
|
|
|
-
|
|
|
- unpackNormalDepth: [
|
|
|
-
|
|
|
- "vec4 normalDepthMap = texture2D( samplerNormalDepth, texCoord );",
|
|
|
- "float depth = normalDepthMap.w;",
|
|
|
-
|
|
|
- "if ( depth == 0.0 ) discard;",
|
|
|
-
|
|
|
- "vec3 normal = normalDepthMap.xyz * 2.0 - 1.0;"
|
|
|
-
|
|
|
- ].join( "\n" ),
|
|
|
-
|
|
|
- packNormalDepthShininess: [
|
|
|
-
|
|
|
- "vec4 packedNormalDepthShininess;",
|
|
|
- "packedNormalDepthShininess.xy = normal_to_vec2( normal );",
|
|
|
- "packedNormalDepthShininess.z = shininess;",
|
|
|
- "packedNormalDepthShininess.w = position.z / position.w;"
|
|
|
-
|
|
|
- ].join( "\n" ),
|
|
|
-
|
|
|
- unpackNormalDepthShininess: [
|
|
|
-
|
|
|
- "vec4 normalDepthMap = texture2D( samplerNormalDepthShininess, texCoord );",
|
|
|
- "float depth = normalDepthMap.w;",
|
|
|
-
|
|
|
- "if ( depth == 0.0 ) discard;",
|
|
|
-
|
|
|
- "vec3 normal = vec2_to_normal( normalDepthMap.xy );",
|
|
|
- "float shininess = normalDepthMap.z;"
|
|
|
-
|
|
|
- ].join( "\n" ),
|
|
|
-
|
|
|
- packColor: [
|
|
|
-
|
|
|
- "vec4 packedColor;",
|
|
|
- "packedColor.x = vec3_to_float( diffuseColor.rgb );",
|
|
|
- "packedColor.y = vec3_to_float( emissiveColor );",
|
|
|
- "packedColor.z = vec3_to_float( specularColor );",
|
|
|
- "packedColor.w = shininess;"
|
|
|
-
|
|
|
- ].join( "\n" ),
|
|
|
-
|
|
|
- unpackColor: [
|
|
|
-
|
|
|
- "vec4 colorMap = texture2D( samplerColor, texCoord );",
|
|
|
- "vec3 diffuseColor = float_to_vec3( colorMap.x );",
|
|
|
- "vec3 emissiveColor = float_to_vec3( colorMap.y );",
|
|
|
- "vec3 specularColor = float_to_vec3( colorMap.z );",
|
|
|
- "float shininess = colorMap.w;"
|
|
|
-
|
|
|
- ].join( "\n" ),
|
|
|
-
|
|
|
- packLight: [
|
|
|
-
|
|
|
- "vec4 packedLight;",
|
|
|
- "packedLight.xyz = lightIntensity * lightColor * max( dot( lightVector, normal ), 0.0 ) * attenuation;",
|
|
|
- "packedLight.w = lightIntensity * specular * max( dot( lightVector, normal ), 0.0 ) * attenuation;"
|
|
|
-
|
|
|
- ].join( "\n" ),
|
|
|
-
|
|
|
- computeVertexPositionVS: [
|
|
|
-
|
|
|
- "vec2 xy = texCoord * 2.0 - 1.0;",
|
|
|
- "vec4 vertexPositionProjected = vec4( xy, depth, 1.0 );",
|
|
|
- "vec4 vertexPositionVS = matProjInverse * vertexPositionProjected;",
|
|
|
- "vertexPositionVS.xyz /= vertexPositionVS.w;",
|
|
|
- "vertexPositionVS.w = 1.0;"
|
|
|
-
|
|
|
- ].join( "\n" ),
|
|
|
-
|
|
|
- // TODO: calculate schlick
|
|
|
- computeSpecular: [
|
|
|
-
|
|
|
- "vec3 halfVector = normalize( lightVector - normalize( vertexPositionVS.xyz ) );",
|
|
|
- "float dotNormalHalf = max( dot( normal, halfVector ), 0.0 );",
|
|
|
- "float specular = 0.31830988618 * ( shininess * 0.5 + 1.0 ) * pow( dotNormalHalf, shininess );"
|
|
|
-
|
|
|
- ].join( "\n" ),
|
|
|
-
|
|
|
- combine: [
|
|
|
-
|
|
|
- "gl_FragColor = vec4( lightIntensity * lightColor * max( dot( lightVector, normal ), 0.0 ) * ( diffuseColor + specular * specularColor ) * attenuation, 1.0 );"
|
|
|
-
|
|
|
- ].join( "\n" )
|
|
|
-
|
|
|
-};
|
|
|
-
|
|
|
-THREE.ShaderDeferredCommon = {
|
|
|
-
|
|
|
- commonUniforms: {
|
|
|
-
|
|
|
- matProjInverse: new THREE.Uniform( new THREE.Matrix4() ),
|
|
|
-
|
|
|
- viewWidth: new THREE.Uniform( 800 ),
|
|
|
- viewHeight: new THREE.Uniform( 600 )
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-};
|
|
|
-
|
|
|
-THREE.ShaderDeferred = {
|
|
|
-
|
|
|
- normalDepth: {
|
|
|
-
|
|
|
- uniforms: {},
|
|
|
-
|
|
|
- vertexShader: [
|
|
|
-
|
|
|
- "varying vec3 vNormal;",
|
|
|
- "varying vec4 vPosition;",
|
|
|
-
|
|
|
- "#include <morphtarget_pars_vertex>",
|
|
|
- "#include <skinning_pars_vertex>",
|
|
|
-
|
|
|
- "void main() {",
|
|
|
-
|
|
|
- "#include <begin_vertex>",
|
|
|
- "#include <beginnormal_vertex>",
|
|
|
- "#include <skinbase_vertex>",
|
|
|
- "#include <skinnormal_vertex>",
|
|
|
- "#include <defaultnormal_vertex>",
|
|
|
- "#include <morphtarget_vertex>",
|
|
|
- "#include <skinning_vertex>",
|
|
|
- "#include <project_vertex>",
|
|
|
-
|
|
|
- " vNormal = normalize( transformedNormal );",
|
|
|
- " vPosition = gl_Position;",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( "\n" ),
|
|
|
-
|
|
|
- fragmentShader: [
|
|
|
-
|
|
|
- "varying vec3 vNormal;",
|
|
|
- "varying vec4 vPosition;",
|
|
|
-
|
|
|
- "void main() {",
|
|
|
-
|
|
|
- " vec3 normal = vNormal;",
|
|
|
- " vec4 position = vPosition;",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "packNormalDepth" ],
|
|
|
-
|
|
|
- " gl_FragColor = packedNormalDepth;",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( "\n" )
|
|
|
-
|
|
|
- },
|
|
|
-
|
|
|
- color: {
|
|
|
-
|
|
|
- uniforms: {
|
|
|
-
|
|
|
- map: new THREE.Uniform( null ),
|
|
|
- offsetRepeat: new THREE.Uniform( new THREE.Vector4( 0, 0, 1, 1 ) ),
|
|
|
-
|
|
|
- diffuse: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
|
|
|
- emissive: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
|
|
|
- specular: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
|
|
|
- shininess: new THREE.Uniform( 30.0 )
|
|
|
-
|
|
|
- },
|
|
|
-
|
|
|
- vertexShader: [
|
|
|
-
|
|
|
- "#include <uv_pars_vertex>",
|
|
|
- "#include <morphtarget_pars_vertex>",
|
|
|
- "#include <skinning_pars_vertex>",
|
|
|
-
|
|
|
- "void main() {",
|
|
|
-
|
|
|
- "#include <uv_vertex>",
|
|
|
- "#include <begin_vertex>",
|
|
|
- "#include <beginnormal_vertex>",
|
|
|
- "#include <skinbase_vertex>",
|
|
|
- "#include <skinnormal_vertex>",
|
|
|
- "#include <defaultnormal_vertex>",
|
|
|
- "#include <morphtarget_vertex>",
|
|
|
- "#include <skinning_vertex>",
|
|
|
- "#include <project_vertex>",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( "\n" ),
|
|
|
-
|
|
|
- fragmentShader: [
|
|
|
-
|
|
|
- "uniform vec3 diffuse;",
|
|
|
- "uniform vec3 emissive;",
|
|
|
- "uniform vec3 specular;",
|
|
|
- "uniform float shininess;",
|
|
|
-
|
|
|
- "#include <uv_pars_fragment>",
|
|
|
- "#include <map_pars_fragment>",
|
|
|
- THREE.DeferredShaderChunk[ "packVector3" ],
|
|
|
-
|
|
|
- "void main() {",
|
|
|
-
|
|
|
- " vec4 diffuseColor = vec4( diffuse, 1.0 );",
|
|
|
- " vec3 emissiveColor = emissive;",
|
|
|
- " vec3 specularColor = specular;",
|
|
|
-
|
|
|
- "#include <map_fragment>",
|
|
|
- THREE.DeferredShaderChunk[ "packColor" ],
|
|
|
-
|
|
|
- " gl_FragColor = packedColor;",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( "\n" )
|
|
|
-
|
|
|
- },
|
|
|
-
|
|
|
- emissiveLight: {
|
|
|
-
|
|
|
- uniforms: Object.assign(
|
|
|
-
|
|
|
- {
|
|
|
-
|
|
|
- samplerColor: new THREE.Uniform( null )
|
|
|
-
|
|
|
- },
|
|
|
-
|
|
|
- THREE.ShaderDeferredCommon[ 'commonUniforms' ]
|
|
|
-
|
|
|
- ),
|
|
|
-
|
|
|
- vertexShader: [
|
|
|
-
|
|
|
- "void main() { ",
|
|
|
-
|
|
|
- " gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( '\n' ),
|
|
|
-
|
|
|
- fragmentShader: [
|
|
|
-
|
|
|
- "uniform sampler2D samplerColor;",
|
|
|
-
|
|
|
- "uniform float viewHeight;",
|
|
|
- "uniform float viewWidth;",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "unpackFloat" ],
|
|
|
-
|
|
|
- "void main() {",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "computeTextureCoord" ],
|
|
|
- THREE.DeferredShaderChunk[ "unpackColor" ],
|
|
|
-
|
|
|
- " gl_FragColor = vec4( emissiveColor, 1.0 );",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( '\n' )
|
|
|
-
|
|
|
- },
|
|
|
-
|
|
|
- pointLight: {
|
|
|
-
|
|
|
- uniforms: Object.assign(
|
|
|
-
|
|
|
- {
|
|
|
-
|
|
|
- samplerNormalDepth: new THREE.Uniform( null ),
|
|
|
- samplerColor: new THREE.Uniform( null ),
|
|
|
-
|
|
|
- lightColor: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
|
|
|
- lightPositionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ),
|
|
|
- lightIntensity: new THREE.Uniform( 1.0 ),
|
|
|
- lightRadius: new THREE.Uniform( 1.0 )
|
|
|
-
|
|
|
- },
|
|
|
-
|
|
|
- THREE.ShaderDeferredCommon[ 'commonUniforms' ]
|
|
|
-
|
|
|
- ),
|
|
|
-
|
|
|
- vertexShader: [
|
|
|
-
|
|
|
- "void main() {",
|
|
|
-
|
|
|
- " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( "\n" ),
|
|
|
-
|
|
|
- fragmentShader: [
|
|
|
-
|
|
|
- "uniform sampler2D samplerNormalDepth;",
|
|
|
- "uniform sampler2D samplerColor;",
|
|
|
-
|
|
|
- "uniform float viewHeight;",
|
|
|
- "uniform float viewWidth;",
|
|
|
-
|
|
|
- "uniform vec3 lightColor;",
|
|
|
- "uniform vec3 lightPositionVS;",
|
|
|
- "uniform float lightIntensity;",
|
|
|
- "uniform float lightRadius;",
|
|
|
-
|
|
|
- "uniform mat4 matProjInverse;",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "unpackFloat" ],
|
|
|
-
|
|
|
- "void main() {",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "computeTextureCoord" ],
|
|
|
- THREE.DeferredShaderChunk[ "unpackNormalDepth" ],
|
|
|
- THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
|
|
|
-
|
|
|
- " vec3 lightVector = lightPositionVS - vertexPositionVS.xyz;",
|
|
|
- " float distance = length( lightVector );",
|
|
|
-
|
|
|
- " if ( distance > lightRadius ) discard;",
|
|
|
-
|
|
|
- " lightVector = normalize( lightVector );",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "unpackColor" ],
|
|
|
- THREE.DeferredShaderChunk[ "computeSpecular" ],
|
|
|
-
|
|
|
- " //float cutoff = 0.3;",
|
|
|
- " //float denom = distance / lightRadius + 1.0;",
|
|
|
- " //float attenuation = 1.0 / ( denom * denom );",
|
|
|
- " //attenuation = ( attenuation - cutoff ) / ( 1.0 - cutoff );",
|
|
|
- " //attenuation = max( attenuation, 0.0 );",
|
|
|
- " //attenuation *= attenuation;",
|
|
|
-
|
|
|
- " //diffuseColor *= saturate( -distance / lightRadius + 1.0 );",
|
|
|
- " //float attenuation = 1.0;",
|
|
|
-
|
|
|
- " float attenuation = saturate( -distance / lightRadius + 1.0 );",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "combine" ],
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( "\n" )
|
|
|
-
|
|
|
- },
|
|
|
-
|
|
|
- spotLight: {
|
|
|
-
|
|
|
- uniforms: Object.assign(
|
|
|
-
|
|
|
- {
|
|
|
-
|
|
|
- samplerNormalDepth: new THREE.Uniform( null ),
|
|
|
- samplerColor: new THREE.Uniform( null ),
|
|
|
-
|
|
|
- lightColor: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
|
|
|
- lightDirectionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ),
|
|
|
- lightPositionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ),
|
|
|
- lightAngle: new THREE.Uniform( 1.0 ),
|
|
|
- lightIntensity: new THREE.Uniform( 1.0 )
|
|
|
-
|
|
|
- },
|
|
|
-
|
|
|
- THREE.ShaderDeferredCommon[ 'commonUniforms' ]
|
|
|
-
|
|
|
- ),
|
|
|
-
|
|
|
- vertexShader: [
|
|
|
-
|
|
|
- "void main() { ",
|
|
|
-
|
|
|
- " gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( "\n" ),
|
|
|
-
|
|
|
- fragmentShader: [
|
|
|
-
|
|
|
- "uniform sampler2D samplerNormalDepth;",
|
|
|
- "uniform sampler2D samplerColor;",
|
|
|
-
|
|
|
- "uniform float viewHeight;",
|
|
|
- "uniform float viewWidth;",
|
|
|
-
|
|
|
- "uniform vec3 lightColor;",
|
|
|
- "uniform vec3 lightPositionVS;",
|
|
|
- "uniform vec3 lightDirectionVS;",
|
|
|
- "uniform float lightAngle;",
|
|
|
- "uniform float lightIntensity;",
|
|
|
-
|
|
|
- "uniform mat4 matProjInverse;",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "unpackFloat" ],
|
|
|
-
|
|
|
- "void main() {",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "computeTextureCoord" ],
|
|
|
- THREE.DeferredShaderChunk[ "unpackNormalDepth" ],
|
|
|
- THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
|
|
|
- THREE.DeferredShaderChunk[ "unpackColor" ],
|
|
|
-
|
|
|
- " vec3 lightVector = normalize( lightPositionVS.xyz - vertexPositionVS.xyz );",
|
|
|
-
|
|
|
- " float rho = dot( lightDirectionVS, lightVector );",
|
|
|
- " float rhoMax = cos( lightAngle );",
|
|
|
-
|
|
|
- " if ( rho <= rhoMax ) discard;",
|
|
|
-
|
|
|
- " float theta = rhoMax + 0.0001;",
|
|
|
- " float phi = rhoMax + 0.05;",
|
|
|
- " float falloff = 4.0;",
|
|
|
-
|
|
|
- " float spot = 0.0;",
|
|
|
-
|
|
|
- " if ( rho >= phi ) {",
|
|
|
-
|
|
|
- " spot = 1.0;",
|
|
|
-
|
|
|
- " } else if ( rho <= theta ) {",
|
|
|
-
|
|
|
- " spot = 0.0;",
|
|
|
-
|
|
|
- " } else { ",
|
|
|
-
|
|
|
- " spot = pow( ( rho - theta ) / ( phi - theta ), falloff );",
|
|
|
-
|
|
|
- " }",
|
|
|
-
|
|
|
- " diffuseColor *= spot;",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "computeSpecular" ],
|
|
|
-
|
|
|
- " const float attenuation = 1.0;",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "combine" ],
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( "\n" )
|
|
|
-
|
|
|
- },
|
|
|
-
|
|
|
- directionalLight: {
|
|
|
-
|
|
|
- uniforms: Object.assign(
|
|
|
-
|
|
|
- {
|
|
|
-
|
|
|
- samplerNormalDepth: new THREE.Uniform( null ),
|
|
|
- samplerColor: new THREE.Uniform( null ),
|
|
|
-
|
|
|
- lightColor: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
|
|
|
- lightDirectionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ),
|
|
|
- lightIntensity: new THREE.Uniform( 1.0 )
|
|
|
- },
|
|
|
-
|
|
|
- THREE.ShaderDeferredCommon[ 'commonUniforms' ]
|
|
|
-
|
|
|
- ),
|
|
|
-
|
|
|
- vertexShader: [
|
|
|
-
|
|
|
- "void main() { ",
|
|
|
-
|
|
|
- " gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( '\n' ),
|
|
|
-
|
|
|
- fragmentShader: [
|
|
|
-
|
|
|
- "uniform sampler2D samplerNormalDepth;",
|
|
|
- "uniform sampler2D samplerColor;",
|
|
|
-
|
|
|
- "uniform float viewHeight;",
|
|
|
- "uniform float viewWidth;",
|
|
|
-
|
|
|
- "uniform vec3 lightColor;",
|
|
|
- "uniform vec3 lightDirectionVS;",
|
|
|
- "uniform float lightIntensity;",
|
|
|
-
|
|
|
- "uniform mat4 matProjInverse;",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "unpackFloat" ],
|
|
|
-
|
|
|
- "void main() {",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "computeTextureCoord" ],
|
|
|
- THREE.DeferredShaderChunk[ "unpackNormalDepth" ],
|
|
|
- THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
|
|
|
- THREE.DeferredShaderChunk[ "unpackColor" ],
|
|
|
-
|
|
|
- " vec3 lightVector = normalize( lightDirectionVS );",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "computeSpecular" ],
|
|
|
-
|
|
|
- " const float attenuation = 1.0;",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "combine" ],
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( '\n' )
|
|
|
-
|
|
|
- },
|
|
|
-
|
|
|
- normalDepthShininess: {
|
|
|
-
|
|
|
- uniforms: {
|
|
|
-
|
|
|
- shininess: new THREE.Uniform( 30.0 )
|
|
|
-
|
|
|
- },
|
|
|
-
|
|
|
- vertexShader: [
|
|
|
-
|
|
|
- "varying vec3 vNormal;",
|
|
|
- "varying vec4 vPosition;",
|
|
|
-
|
|
|
- "#include <morphtarget_pars_vertex>",
|
|
|
- "#include <skinning_pars_vertex>",
|
|
|
-
|
|
|
- "void main() {",
|
|
|
-
|
|
|
- "#include <begin_vertex>",
|
|
|
- "#include <beginnormal_vertex>",
|
|
|
- "#include <skinbase_vertex>",
|
|
|
- "#include <skinnormal_vertex>",
|
|
|
- "#include <defaultnormal_vertex>",
|
|
|
- "#include <morphtarget_vertex>",
|
|
|
- "#include <skinning_vertex>",
|
|
|
- "#include <project_vertex>",
|
|
|
-
|
|
|
- " vNormal = normalize( transformedNormal );",
|
|
|
- " vPosition = gl_Position;",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( "\n" ),
|
|
|
-
|
|
|
- fragmentShader: [
|
|
|
-
|
|
|
- "varying vec3 vNormal;",
|
|
|
- "varying vec4 vPosition;",
|
|
|
-
|
|
|
- "uniform float shininess;",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "packNormal" ],
|
|
|
-
|
|
|
- "void main() {",
|
|
|
-
|
|
|
- " vec3 normal = vNormal;",
|
|
|
- " vec4 position = vPosition;",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "packNormalDepthShininess" ],
|
|
|
-
|
|
|
- " gl_FragColor = packedNormalDepthShininess;",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( "\n" )
|
|
|
-
|
|
|
- },
|
|
|
-
|
|
|
- pointLightPre: {
|
|
|
-
|
|
|
- uniforms: Object.assign(
|
|
|
-
|
|
|
- {
|
|
|
-
|
|
|
- samplerNormalDepthShininess: new THREE.Uniform( null ),
|
|
|
-
|
|
|
- lightColor: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
|
|
|
- lightPositionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ),
|
|
|
- lightIntensity: new THREE.Uniform( 1.0 ),
|
|
|
- lightRadius: new THREE.Uniform( 1.0 )
|
|
|
- },
|
|
|
-
|
|
|
- THREE.ShaderDeferredCommon[ 'commonUniforms' ]
|
|
|
-
|
|
|
- ),
|
|
|
-
|
|
|
-
|
|
|
- vertexShader: [
|
|
|
-
|
|
|
- "void main() {",
|
|
|
-
|
|
|
- " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( "\n" ),
|
|
|
-
|
|
|
- fragmentShader: [
|
|
|
-
|
|
|
- "uniform sampler2D samplerNormalDepthShininess;",
|
|
|
-
|
|
|
- "uniform float viewHeight;",
|
|
|
- "uniform float viewWidth;",
|
|
|
-
|
|
|
- "uniform vec3 lightColor;",
|
|
|
- "uniform vec3 lightPositionVS;",
|
|
|
- "uniform float lightIntensity;",
|
|
|
- "uniform float lightRadius;",
|
|
|
-
|
|
|
- "uniform mat4 matProjInverse;",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "unpackFloat" ],
|
|
|
- THREE.DeferredShaderChunk[ "unpackVector2" ],
|
|
|
-
|
|
|
- "void main() {",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "computeTextureCoord" ],
|
|
|
- THREE.DeferredShaderChunk[ "unpackNormalDepthShininess" ],
|
|
|
- THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
|
|
|
-
|
|
|
- " vec3 lightVector = lightPositionVS - vertexPositionVS.xyz;",
|
|
|
- " float distance = length( lightVector );",
|
|
|
-
|
|
|
- " if ( distance > lightRadius ) discard;",
|
|
|
-
|
|
|
- " lightVector = normalize( lightVector );",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "computeSpecular" ],
|
|
|
-
|
|
|
- " float attenuation = saturate( -distance / lightRadius + 1.0 );",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "packLight" ],
|
|
|
-
|
|
|
- " gl_FragColor = packedLight;",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( "\n" )
|
|
|
-
|
|
|
- },
|
|
|
-
|
|
|
- spotLightPre: {
|
|
|
-
|
|
|
- uniforms: Object.assign(
|
|
|
-
|
|
|
- {
|
|
|
-
|
|
|
- samplerNormalDepthShininess: new THREE.Uniform( null ),
|
|
|
-
|
|
|
- lightColor: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
|
|
|
- lightDirectionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ),
|
|
|
- lightPositionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ),
|
|
|
- lightAngle: new THREE.Uniform( 1.0 ),
|
|
|
- lightIntensity: new THREE.Uniform( 1.0 )
|
|
|
-
|
|
|
- },
|
|
|
-
|
|
|
- THREE.ShaderDeferredCommon[ 'commonUniforms' ]
|
|
|
-
|
|
|
- ),
|
|
|
-
|
|
|
- vertexShader: [
|
|
|
-
|
|
|
- "void main() { ",
|
|
|
-
|
|
|
- " gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( "\n" ),
|
|
|
-
|
|
|
- fragmentShader: [
|
|
|
-
|
|
|
- "uniform sampler2D samplerNormalDepthShininess;",
|
|
|
-
|
|
|
- "uniform float viewHeight;",
|
|
|
- "uniform float viewWidth;",
|
|
|
-
|
|
|
- "uniform vec3 lightColor;",
|
|
|
- "uniform vec3 lightPositionVS;",
|
|
|
- "uniform vec3 lightDirectionVS;",
|
|
|
- "uniform float lightAngle;",
|
|
|
- "uniform float lightIntensity;",
|
|
|
-
|
|
|
- "uniform mat4 matProjInverse;",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "unpackFloat" ],
|
|
|
- THREE.DeferredShaderChunk[ "unpackVector2" ],
|
|
|
-
|
|
|
- "void main() {",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "computeTextureCoord" ],
|
|
|
- THREE.DeferredShaderChunk[ "unpackNormalDepthShininess" ],
|
|
|
- THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
|
|
|
-
|
|
|
- " vec3 lightVector = normalize( lightPositionVS.xyz - vertexPositionVS.xyz );",
|
|
|
-
|
|
|
- " float rho = dot( lightDirectionVS, lightVector );",
|
|
|
- " float rhoMax = cos( lightAngle );",
|
|
|
-
|
|
|
- " if ( rho <= rhoMax ) discard;",
|
|
|
-
|
|
|
- " float theta = rhoMax + 0.0001;",
|
|
|
- " float phi = rhoMax + 0.05;",
|
|
|
- " float falloff = 4.0;",
|
|
|
-
|
|
|
- " float spot = 0.0;",
|
|
|
-
|
|
|
- " if ( rho >= phi ) {",
|
|
|
-
|
|
|
- " spot = 1.0;",
|
|
|
-
|
|
|
- " } else if ( rho <= theta ) {",
|
|
|
-
|
|
|
- " spot = 0.0;",
|
|
|
-
|
|
|
- " } else { ",
|
|
|
-
|
|
|
- " spot = pow( ( rho - theta ) / ( phi - theta ), falloff );",
|
|
|
-
|
|
|
- " }",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "computeSpecular" ],
|
|
|
-
|
|
|
- " const float attenuation = 1.0;",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "packLight" ],
|
|
|
-
|
|
|
- " gl_FragColor = spot * packedLight;",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( "\n" )
|
|
|
-
|
|
|
- },
|
|
|
-
|
|
|
- directionalLightPre: {
|
|
|
-
|
|
|
- uniforms: Object.assign(
|
|
|
-
|
|
|
- {
|
|
|
-
|
|
|
- samplerNormalDepthShininess: new THREE.Uniform( null ),
|
|
|
-
|
|
|
- lightColor: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
|
|
|
- lightDirectionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ),
|
|
|
- lightIntensity: new THREE.Uniform( 1.0 )
|
|
|
-
|
|
|
- },
|
|
|
-
|
|
|
- THREE.ShaderDeferredCommon[ 'commonUniforms' ]
|
|
|
-
|
|
|
- ),
|
|
|
-
|
|
|
- vertexShader: [
|
|
|
-
|
|
|
- "void main() { ",
|
|
|
-
|
|
|
- " gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( '\n' ),
|
|
|
-
|
|
|
- fragmentShader: [
|
|
|
-
|
|
|
- "uniform sampler2D samplerNormalDepthShininess;",
|
|
|
-
|
|
|
- "uniform float viewHeight;",
|
|
|
- "uniform float viewWidth;",
|
|
|
-
|
|
|
- "uniform vec3 lightColor;",
|
|
|
- "uniform vec3 lightDirectionVS;",
|
|
|
- "uniform float lightIntensity;",
|
|
|
-
|
|
|
- "uniform mat4 matProjInverse;",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "unpackFloat" ],
|
|
|
- THREE.DeferredShaderChunk[ "unpackVector2" ],
|
|
|
-
|
|
|
- "void main() {",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "computeTextureCoord" ],
|
|
|
- THREE.DeferredShaderChunk[ "unpackNormalDepthShininess" ],
|
|
|
- THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
|
|
|
-
|
|
|
- " vec3 lightVector = normalize( lightDirectionVS );",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "computeSpecular" ],
|
|
|
-
|
|
|
- " const float attenuation = 1.0;",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "packLight" ],
|
|
|
-
|
|
|
- " gl_FragColor = packedLight;",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( '\n' )
|
|
|
-
|
|
|
- },
|
|
|
-
|
|
|
- reconstruction: {
|
|
|
-
|
|
|
- uniforms: Object.assign(
|
|
|
-
|
|
|
- {
|
|
|
-
|
|
|
- samplerLight: new THREE.Uniform( null ),
|
|
|
-
|
|
|
- map: new THREE.Uniform( null ),
|
|
|
- offsetRepeat: new THREE.Uniform( new THREE.Vector4( 0, 0, 1, 1 ) ),
|
|
|
-
|
|
|
- diffuse: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
|
|
|
- emissive: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
|
|
|
- specular: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
|
|
|
- shininess: new THREE.Uniform( 30.0 )
|
|
|
-
|
|
|
- },
|
|
|
-
|
|
|
- THREE.ShaderDeferredCommon[ 'commonUniforms' ]
|
|
|
-
|
|
|
- ),
|
|
|
-
|
|
|
- vertexShader: [
|
|
|
-
|
|
|
- "#include <uv_pars_vertex>",
|
|
|
- "#include <morphtarget_pars_vertex>",
|
|
|
- "#include <skinning_pars_vertex>",
|
|
|
-
|
|
|
- "void main() {",
|
|
|
-
|
|
|
- "#include <uv_vertex>",
|
|
|
- "#include <begin_vertex>",
|
|
|
- "#include <beginnormal_vertex>",
|
|
|
- "#include <skinbase_vertex>",
|
|
|
- "#include <skinnormal_vertex>",
|
|
|
- "#include <defaultnormal_vertex>",
|
|
|
- "#include <morphtarget_vertex>",
|
|
|
- "#include <skinning_vertex>",
|
|
|
- "#include <project_vertex>",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( "\n" ),
|
|
|
-
|
|
|
- fragmentShader: [
|
|
|
-
|
|
|
- "uniform sampler2D samplerLight;",
|
|
|
-
|
|
|
- "uniform vec3 diffuse;",
|
|
|
- "uniform vec3 emissive;",
|
|
|
- "uniform vec3 specular;",
|
|
|
- "uniform float shininess;",
|
|
|
-
|
|
|
- "uniform float viewHeight;",
|
|
|
- "uniform float viewWidth;",
|
|
|
-
|
|
|
- "#include <uv_pars_fragment>",
|
|
|
- "#include <map_pars_fragment>",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "unpackFloat" ],
|
|
|
-
|
|
|
- "void main() {",
|
|
|
-
|
|
|
- " vec4 diffuseColor = vec4( diffuse, 1.0 );",
|
|
|
- " vec3 emissiveColor = emissive;",
|
|
|
- " vec3 specularColor = specular;",
|
|
|
-
|
|
|
- THREE.DeferredShaderChunk[ "computeTextureCoord" ],
|
|
|
-
|
|
|
- " vec4 light = texture2D( samplerLight, texCoord );",
|
|
|
-
|
|
|
- "#include <map_fragment>",
|
|
|
-
|
|
|
- " vec3 diffuseFinal = diffuseColor.rgb * light.rgb;",
|
|
|
- " vec3 emissiveFinal = emissiveColor;",
|
|
|
- " vec3 specularFinal = specularColor * light.rgb * light.a;",
|
|
|
-
|
|
|
- " gl_FragColor = vec4( diffuseFinal + emissiveFinal + specularFinal, 1.0 );",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( "\n" )
|
|
|
-
|
|
|
- },
|
|
|
-
|
|
|
- // TODO: implement tone mapping
|
|
|
- final: {
|
|
|
-
|
|
|
- uniforms: {
|
|
|
-
|
|
|
- samplerResult: new THREE.Uniform( null )
|
|
|
-
|
|
|
- },
|
|
|
-
|
|
|
- vertexShader: [
|
|
|
-
|
|
|
- "varying vec2 texCoord;",
|
|
|
-
|
|
|
- "void main() {",
|
|
|
-
|
|
|
- " vec4 pos = vec4( sign( position.xy ), 0.0, 1.0 );",
|
|
|
- " texCoord = pos.xy * vec2( 0.5 ) + 0.5;",
|
|
|
- " gl_Position = pos;",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( "\n" ),
|
|
|
-
|
|
|
- fragmentShader: [
|
|
|
-
|
|
|
- "varying vec2 texCoord;",
|
|
|
- "uniform sampler2D samplerResult;",
|
|
|
-
|
|
|
- "void main() {",
|
|
|
-
|
|
|
- " gl_FragColor = texture2D( samplerResult, texCoord );",
|
|
|
-
|
|
|
- "}"
|
|
|
-
|
|
|
- ].join( "\n" )
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-};
|