1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377 |
- /**
- * @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
- * - shared material
- * - 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 _gl;
- 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 _lightScene, _lightFullscreenScene;
- var _antialias = false, _hasTransparentObject = false, _lightPrePass = false;
- var _invisibleMaterial = new THREE.ShaderMaterial( { visible: false } );
- var _tmpVector3 = new THREE.Vector3();
- // 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( { antialias: false } );
- _this.domElement = _this.renderer.domElement;
- _gl = _this.renderer.context;
- _width = parameters.width !== undefined ? parameters.width : _this.renderer.getSize().width;
- _height = parameters.height !== undefined ? parameters.height : _this.renderer.getSize().height;
- var antialias = parameters.antialias !== undefined ? parameters.antialias : false;
- 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.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.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.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.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 ) {
- if ( scene.userData.lightScene === undefined ) {
- var lightScene = new THREE.Scene();
- lightScene.userData.lights = {};
- scene.userData.lightScene = lightScene;
- }
- if ( scene.userData.lightFullscreenScene === undefined ) {
- var lightScene = new THREE.Scene();
- lightScene.userData.lights = {};
- lightScene.userData.emissiveLight = createDeferredEmissiveLight();
- lightScene.add( lightScene.userData.emissiveLight );
- scene.userData.lightFullscreenScene = lightScene;
- }
- _lightScene = scene.userData.lightScene;
- _lightFullscreenScene = scene.userData.lightFullscreenScene;
- // emissiveLight is only for Classic Deferred Rendering
- _lightFullscreenScene.userData.emissiveLight.visible = ! _lightPrePass;
- }
- function setMaterialNormalDepth( object ) {
- if ( object.material === undefined ) return;
- object.material = getNormalDepthMaterial( object );
- if ( object.userData.originalMaterial.isMultiMaterial === true ) {
- for ( var i = 0, il = object.userData.originalMaterial.materials.length; i < il; i ++ ) {
- updateDeferredNormalDepthMaterial( object.material.materials[ i ], object.userData.originalMaterial.materials[ i ], _lightPrePass );
- }
- } else {
- updateDeferredNormalDepthMaterial( object.material, object.userData.originalMaterial, _lightPrePass );
- }
- }
- function getNormalDepthMaterial( object ) {
- if ( ( _lightPrePass && object.userData.normalDepthShininessMaterial === undefined ) ||
- ( ! _lightPrePass && object.userData.normalDepthMaterial === undefined ) ) {
- initDeferredNormalDepthMaterial( object, _lightPrePass );
- }
- return ( _lightPrePass ) ? object.userData.normalDepthShininessMaterial : object.userData.normalDepthMaterial;
- }
- function initDeferredNormalDepthMaterial( object, isLightPrePass ) {
- var originalMaterial = object.userData.originalMaterial;
- var material;
- if ( originalMaterial.isMultiMaterial === true ) {
- var materials = [];
- for ( var i = 0, il = originalMaterial.materials.length; i < il; i ++ ) {
- materials.push( createDeferredNormalDepthMaterial( originalMaterial.materials[ i ], isLightPrePass ) );
- }
- material = new THREE.MultiMaterial( materials );
- } else {
- material = createDeferredNormalDepthMaterial( originalMaterial, isLightPrePass );
- }
- if ( isLightPrePass ) {
- object.userData.normalDepthShininessMaterial = material;
- } else {
- object.userData.normalDepthMaterial = material;
- }
- }
- function createDeferredNormalDepthMaterial( originalMaterial, isLightPrePass ) {
- var shader = ( isLightPrePass ) ? THREE.ShaderDeferred[ 'normalDepthShininess' ] : THREE.ShaderDeferred[ 'normalDepth' ];
- var material = new THREE.ShaderMaterial( {
- uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
- fragmentShader: shader.fragmentShader,
- vertexShader: shader.vertexShader,
- blending: THREE.NoBlending
- } );
- return material;
- }
- function updateDeferredNormalDepthMaterial( material, originalMaterial, isLightPrePass ) {
- if ( originalMaterial.skinning !== undefined ) material.skinning = originalMaterial.skinning;
- if ( originalMaterial.morphTargets !== undefined ) material.morphTargets = originalMaterial.morphTargets;
- if ( isLightPrePass ) {
- var shininess = originalMaterial.shininess;
- if ( ( originalMaterial.isShaderMaterial === true ) && originalMaterial.uniforms !== undefined ) {
- if ( shininess === undefined && originalMaterial.uniforms.shininess !== undefined ) shininess = originalMaterial.uniforms.shininess.value;
- }
- if ( shininess !== undefined ) material.uniforms.shininess.value = shininess;
- }
- if ( originalMaterial.visible === true ) {
- material.visible = ! originalMaterial.transparent;
- } else {
- material.visible = false;
- }
- }
- function setMaterialColor( object ) {
- if ( object.material === undefined ) return;
- object.material = getColorMaterial( object );
- if ( object.userData.originalMaterial.isMultiMaterial === true ) {
- for ( var i = 0, il = object.userData.originalMaterial.materials.length; i < il; i ++ ) {
- updateDeferredColorMaterial( object.material.materials[ i ], object.userData.originalMaterial.materials[ i ] );
- }
- } else {
- updateDeferredColorMaterial( object.material, object.userData.originalMaterial );
- }
- }
- function getColorMaterial( object ) {
- if ( object.userData.colorMaterial === undefined ) {
- initDeferredColorMaterial( object );
- }
- return object.userData.colorMaterial;
- }
- function initDeferredColorMaterial( object ) {
- var originalMaterial = object.userData.originalMaterial;
- if ( originalMaterial.isMultiMaterial === true ) {
- var materials = [];
- for ( var i = 0, il = originalMaterial.materials.length; i < il; i ++ ) {
- materials.push( createDeferredColorMaterial( originalMaterial.materials[ i ] ) );
- }
- object.userData.colorMaterial = new THREE.MultiMaterial( materials );
- } else {
- object.userData.colorMaterial = createDeferredColorMaterial( originalMaterial );
- }
- }
- function createDeferredColorMaterial( originalMaterial ) {
- var shader = THREE.ShaderDeferred[ 'color' ];
- var material = new THREE.ShaderMaterial( {
- uniforms: THREE.UniformsUtils.clone( 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 ) {
- 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 ( originalMaterial.isShaderMaterial === true && originalMaterial.uniforms !== undefined ) {
- if ( diffuse === undefined && originalMaterial.uniforms.diffuse !== undefined ) diffuse = originalMaterial.uniforms.diffuse.value;
- if ( emissive === undefined && originalMaterial.uniforms.emissive !== undefined ) emissive = originalMaterial.uniforms.emissive.value;
- if ( specular === undefined && originalMaterial.uniforms.specular !== undefined ) specular = originalMaterial.uniforms.specular.value;
- if ( shininess === undefined && originalMaterial.uniforms.shininess !== undefined ) shininess = originalMaterial.uniforms.shininess.value;
- }
- if ( diffuse !== undefined ) material.uniforms.diffuse.value.copy( diffuse );
- if ( emissive !== undefined ) material.uniforms.emissive.value.copy( emissive );
- if ( specular !== undefined ) material.uniforms.specular.value.copy( specular );
- if ( shininess !== undefined && material.uniforms.shininess !== undefined ) material.uniforms.shininess.value = shininess;
- if ( map !== undefined ) {
- material.map = map;
- material.uniforms.map.value = 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 setMaterialReconstruction( object ) {
- if ( object.material === undefined ) return;
- if ( object.userData.originalMaterial.transparent === true ) {
- object.material = object.userData.originalMaterial;
- return;
- }
- object.material = getReconstructionMaterial( object );
- if ( object.userData.originalMaterial.isMultiMaterial === true ) {
- for ( var i = 0, il = object.userData.originalMaterial.materials.length; i < il; i ++ ) {
- updateDeferredReconstructionMaterial( object.material.materials[ i ], object.userData.originalMaterial.materials[ i ] );
- }
- } else {
- updateDeferredReconstructionMaterial( object.material, object.userData.originalMaterial );
- }
- }
- function getReconstructionMaterial( object ) {
- if ( object.userData.reconstructionMaterial === undefined ) {
- initDeferredReconstructionMaterial( object );
- }
- return object.userData.reconstructionMaterial;
- }
- function initDeferredReconstructionMaterial( object ) {
- var originalMaterial = object.userData.originalMaterial;
- if ( originalMaterial.isMultiMaterial === true ) {
- var materials = [];
- for ( var i = 0, il = originalMaterial.materials.length; i < il; i ++ ) {
- materials.push( createDeferredReconstructionMaterial( originalMaterial.materials[ i ] ) );
- }
- object.userData.reconstructionMaterial = new THREE.MultiMaterial( materials );
- } else {
- object.userData.reconstructionMaterial = createDeferredReconstructionMaterial( originalMaterial );
- }
- }
- function createDeferredReconstructionMaterial( originalMaterial ) {
- var shader = THREE.ShaderDeferred[ 'reconstruction' ];
- var material = new THREE.ShaderMaterial( {
- uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
- fragmentShader: shader.fragmentShader,
- vertexShader: shader.vertexShader,
- blending: THREE.NoBlending
- } );
- if ( originalMaterial.map !== undefined ) material.map = originalMaterial.map;
- material.uniforms.samplerLight.value = _compLight.renderTarget2.texture;
- return material;
- }
- function updateDeferredReconstructionMaterial( material, originalMaterial ) {
- updateDeferredColorMaterial( material, originalMaterial );
- material.uniforms.viewWidth.value = _width;
- material.uniforms.viewHeight.value = _height;
- }
- function setMaterialForwardRendering( object ) {
- if ( object.material === undefined ) return;
- if ( object.userData.originalMaterial.isMultiMaterial === true ) {
- if ( object.userData.forwardMaterial === undefined ) {
- initInvisibleMaterial( object );
- }
- object.material = object.userData.forwardMaterial;
- for ( var i = 0, il = object.userData.originalMaterial.materials.length; i < il; i ++ ) {
- object.material.materials[ i ] = getForwardRenderingMaterial( object.userData.originalMaterial.materials[ i ] );
- }
- } else {
- object.material = getForwardRenderingMaterial( object.userData.originalMaterial );
- }
- }
- function initInvisibleMaterial( object ) {
- if ( object.userData.originalMaterial.isMultiMaterial === true ) {
- var materials = [];
- for ( var i = 0, il = object.userData.originalMaterial.materials.length; i < il; i ++ ) {
- materials.push( _invisibleMaterial );
- }
- object.userData.forwardMaterial = new THREE.MultiMaterial( materials );
- }
- }
- function getForwardRenderingMaterial( originalMaterial ) {
- if ( originalMaterial.transparent === true && originalMaterial.visible === true ) {
- return originalMaterial
- } else {
- return _invisibleMaterial;
- }
- }
- function createDeferredEmissiveLight() {
- var shader = THREE.ShaderDeferred[ 'emissiveLight' ];
- var material = new THREE.ShaderMaterial( {
- uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
- vertexShader: shader.vertexShader,
- fragmentShader: shader.fragmentShader,
- blending: THREE.NoBlending,
- depthWrite: false
- } );
- material.uniforms.samplerColor.value = _compColor.renderTarget2.texture;
- var geometry = new THREE.PlaneBufferGeometry( 2, 2 );
- var mesh = new THREE.Mesh( geometry, material );
- return mesh;
- }
- function updateDeferredEmissiveLight( light, camera ) {
- var uniforms = light.material.uniforms;
- uniforms.viewWidth.value = _width;
- uniforms.viewHeight.value = _height;
- }
- function initDeferredLight( light ) {
- var deferredLight;
- if ( light.isPointLight ) {
- deferredLight = createDeferredPointLight( light );
- } else if ( light.isSpotLight ) {
- deferredLight = createDeferredSpotLight( light );
- } else if ( light.isDirectionalLight ) {
- deferredLight = createDeferredDirectionalLight( light );
- } else {
- deferredLight = null;
- }
- light.userData.deferredLight = deferredLight;
- }
- function initDeferredLightMaterial( light, isLightPrePass ) {
- var originalLight = light.userData.originalLight;
- var material;
- if ( originalLight.isPointLight ) {
- material = createDeferredPointLightMaterial( isLightPrePass );
- } else if ( originalLight.isSpotLight ) {
- material = createDeferredSpotLightMaterial( isLightPrePass );
- } else if ( originalLight.isDirectionalLight ) {
- material = createDeferredDirectionalLightMaterial( isLightPrePass );
- } else {
- material = null;
- }
- if ( isLightPrePass ) {
- light.userData.materialLightPrePass = material;
- } else {
- light.userData.materialClassic = material;
- }
- }
- function getDeferredLightMaterial( light ) {
- if ( ( _lightPrePass && light.userData.materialLightPrePass === undefined ) ||
- ( ! _lightPrePass && light.userData.materialClassic === undefined ) ) {
- initDeferredLightMaterial( light, _lightPrePass );
- }
- return ( _lightPrePass ) ? light.userData.materialLightPrePass : light.userData.materialClassic;
- }
- function updateDeferredLight( light, camera ) {
- var originalLight = light.userData.originalLight;
- if ( originalLight.isPointLight ) {
- updateDeferredPointLight( light, camera );
- } else if ( originalLight.isSpotLight ) {
- updateDeferredSpotLight( light, camera );
- } else if ( originalLight.isDirectionalLight ) {
- updateDeferredDirectionalLight( light, camera );
- }
- }
- function createDeferredLightMesh( light, geometry ) {
- var mesh = new THREE.Mesh( geometry, _invisibleMaterial );
- mesh.userData.originalLight = light;
- return mesh;
- }
- function createDeferredLightMaterial( shader, isLightPrePass ) {
- var material = new THREE.ShaderMaterial( {
- uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
- vertexShader: shader.vertexShader,
- fragmentShader: shader.fragmentShader,
- transparent: true,
- blending: THREE.AdditiveBlending,
- depthWrite: false
- } );
- if ( isLightPrePass ) {
- material.premultipliedAlpha = true;
- material.uniforms.samplerNormalDepthShininess.value = _compNormalDepth.renderTarget2.texture;
- } else {
- material.uniforms.samplerNormalDepth.value = _compNormalDepth.renderTarget2.texture;
- material.uniforms.samplerColor.value = _compColor.renderTarget2.texture;
- }
- return material;
- }
- function createDeferredPointLight( light ) {
- return createDeferredLightMesh( light, new THREE.SphereGeometry( 1, 16, 8 ) );
- }
- /*
- * optimization:
- * Renders PointLight only back face with stencil test.
- */
- function createDeferredPointLightMaterial( isLightPrePass ) {
- var shader = ( isLightPrePass ) ? THREE.ShaderDeferred[ 'pointLightPre' ] : THREE.ShaderDeferred[ 'pointLight' ];
- var material = createDeferredLightMaterial( shader, isLightPrePass );
- material.side = THREE.BackSide;
- material.depthFunc = THREE.GreaterEqualDepth;
- return material;
- }
- function updateDeferredPointLight( light, camera ) {
- var originalLight = light.userData.originalLight;
- var distance = originalLight.distance;
- var uniforms = light.material.uniforms;
- uniforms.matProjInverse.value.getInverse( camera.projectionMatrix );
- uniforms.viewWidth.value = _width;
- uniforms.viewHeight.value = _height;
- uniforms.lightColor.value.copy( originalLight.color );
- if ( distance > 0 ) {
- light.scale.set( 1, 1, 1 ).multiplyScalar( distance );
- uniforms.lightRadius.value = distance;
- uniforms.lightIntensity.value = originalLight.intensity;
- uniforms.lightPositionVS.value.setFromMatrixPosition( originalLight.matrixWorld ).applyMatrix4( camera.matrixWorldInverse );
- light.position.setFromMatrixPosition( originalLight.matrixWorld );
- } else {
- uniforms.lightRadius.value = Infinity;
- }
- }
- function createDeferredSpotLight( light ) {
- return createDeferredLightMesh( light, new THREE.PlaneBufferGeometry( 2, 2 ) );
- }
- function createDeferredSpotLightMaterial( isLightPrePass ) {
- var shader = ( isLightPrePass ) ? THREE.ShaderDeferred[ 'spotLightPre' ] : THREE.ShaderDeferred[ 'spotLight' ];
- var material = createDeferredLightMaterial( shader, isLightPrePass );
- material.depthTest = false;
- return material;
- }
- function updateDeferredSpotLight( light, camera ) {
- var originalLight = light.userData.originalLight;
- var uniforms = light.material.uniforms;
- uniforms.matProjInverse.value.getInverse( camera.projectionMatrix );
- uniforms.viewWidth.value = _width;
- uniforms.viewHeight.value = _height;
- uniforms.lightAngle.value = originalLight.angle;
- uniforms.lightColor.value.copy( originalLight.color );
- uniforms.lightIntensity.value = originalLight.intensity;
- uniforms.lightPositionVS.value.setFromMatrixPosition( originalLight.matrixWorld ).applyMatrix4( camera.matrixWorldInverse );
- var vec = uniforms.lightDirectionVS.value;
- var vec2 = _tmpVector3;
- vec.setFromMatrixPosition( originalLight.matrixWorld );
- vec2.setFromMatrixPosition( originalLight.target.matrixWorld );
- vec.sub( vec2 ).normalize().transformDirection( camera.matrixWorldInverse );
- }
- function createDeferredDirectionalLight( light ) {
- return createDeferredLightMesh( light, new THREE.PlaneBufferGeometry( 2, 2 ) );
- }
- function createDeferredDirectionalLightMaterial( isLightPrePass ) {
- var shader = ( isLightPrePass ) ? THREE.ShaderDeferred[ 'directionalLightPre' ] : THREE.ShaderDeferred[ 'directionalLight' ];
- var material = createDeferredLightMaterial( shader, isLightPrePass );
- material.depthTest = false;
- return material;
- }
- function updateDeferredDirectionalLight( light, camera ) {
- var originalLight = light.userData.originalLight;
- var uniforms = light.material.uniforms;
- uniforms.matProjInverse.value.getInverse( camera.projectionMatrix );
- uniforms.viewWidth.value = _width;
- uniforms.viewHeight.value = _height;
- 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( camera.matrixWorldInverse );
- }
- function saveOriginalMaterialAndCheckTransparency( object ) {
- if ( object.material !== undefined ) {
- object.userData.originalMaterial = object.material;
- if ( _hasTransparentObject ) return;
- if ( object.material.isMultiMaterial === true ) {
- for ( var i = 0, il = object.material.materials.length; i < il; i ++ ) {
- if ( object.material.materials[ i ].transparent === true ) {
- _hasTransparentObject = true;
- break;
- }
- }
- } else {
- if ( object.material.transparent === true ) _hasTransparentObject = true;
- }
- }
- }
- function restoreOriginalMaterial( object ) {
- if ( object.userData.originalMaterial !== undefined ) object.material = object.userData.originalMaterial;
- }
- function addDeferredLightsToLightScene( object ) {
- if ( object.isLight !== true ) return;
- if ( object.userData.deferredLight === undefined ) {
- initDeferredLight( object );
- }
- var light = object.userData.deferredLight;
- 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, camera ) {
- 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;
- var material = getDeferredLightMaterial( light );
- light.material = material;
- updateDeferredLight( light, camera );
- lights[ key ].found = false;
- }
- }
- }
- function enableFinalPasses() {
- if ( _lightPrePass ) {
- _passForward.renderToScreen = false;
- _passForward.enabled = false;
- _passCopy.renderToScreen = false;
- _passCopy.enabled = false;
- if ( _antialias ) {
- _passFinal.renderToScreen = false;
- _passFXAA.renderToScreen = true;
- _passFXAA.enabled = true;
- } else {
- _passFinal.renderToScreen = true;
- _passFXAA.renderToScreen = false;
- _passFXAA.enabled = false;
- }
- } else {
- if ( _hasTransparentObject ) {
- if ( _antialias ) {
- _passFinal.renderToScreen = false;
- _passForward.renderToScreen = false;
- _passForward.enabled = true;
- _passCopy.renderToScreen = false;
- _passCopy.enabled = false;
- _passFXAA.renderToScreen = true;
- _passFXAA.enabled = true;
- } else {
- _passFinal.renderToScreen = false;
- _passForward.renderToScreen = false;
- _passForward.enabled = true;
- _passCopy.renderToScreen = true;
- _passCopy.enabled = true;
- _passFXAA.renderToScreen = false;
- _passFXAA.enabled = false;
- }
- } else {
- if ( _antialias ) {
- _passFinal.renderToScreen = false;
- _passForward.renderToScreen = false;
- _passForward.enabled = false;
- _passCopy.renderToScreen = false;
- _passCopy.enabled = false;
- _passFXAA.renderToScreen = true;
- _passFXAA.enabled = true;
- } else {
- _passFinal.renderToScreen = true;
- _passForward.renderToScreen = false;
- _passForward.enabled = false;
- _passCopy.renderToScreen = false;
- _passCopy.enabled = false;
- _passFXAA.renderToScreen = false;
- _passFXAA.enabled = false;
- }
- }
- }
- }
- /*
- * Classic Deferred Rendering
- *
- * 1) g-buffer normal + depth pass
- *
- * RGB: normal
- * A: depth
- *
- *
- * Light Pre-Pass Rendering
- *
- * 1') g-buffer normal + depth pass + shininess
- *
- * R: 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;
- _gl.enable( _gl.STENCIL_TEST );
- _gl.stencilFunc( _gl.ALWAYS, 1, 0xffffffff );
- _gl.stencilOp( _gl.REPLACE, _gl.REPLACE, _gl.REPLACE );
- _compNormalDepth.render();
- }
- /*
- * 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;
- _gl.stencilFunc( _gl.EQUAL, 1, 0xffffffff );
- _gl.stencilOp( _gl.KEEP, _gl.KEEP, _gl.KEEP );
- _compColor.render();
- }
- /*
- * Classic Deferred Rendering
- *
- * 3) light pass
- */
- function renderLight( scene, camera ) {
- updateDeferredEmissiveLight( _lightFullscreenScene.userData.emissiveLight, camera );
- scene.traverse( addDeferredLightsToLightScene );
- updateDeferredLightsInLightScene( _lightScene, camera );
- updateDeferredLightsInLightScene( _lightFullscreenScene, camera );
- _passLight.scene = _lightScene;
- _passLight.camera = camera;
- _passLightFullscreen.scene = _lightFullscreenScene;
- _this.renderer.autoClearDepth = false;
- _this.renderer.autoClearStencil = false;
- _compLight.render();
- _gl.disable( _gl.STENCIL_TEST );
- }
- /*
- * Light Pre-Pass Rendering
- *
- * 2') Light pre pass
- */
- function renderLightPre( scene, camera ) {
- scene.traverse( addDeferredLightsToLightScene );
- updateDeferredLightsInLightScene( _lightScene, camera );
- updateDeferredLightsInLightScene( _lightFullscreenScene, camera );
- _passLight.scene = _lightScene;
- _passLight.camera = camera;
- _passLightFullscreen.scene = _lightFullscreenScene;
- _this.renderer.autoClearDepth = false;
- _this.renderer.autoClearStencil = false;
- _gl.stencilFunc( _gl.EQUAL, 1, 0xffffffff );
- _gl.stencilOp( _gl.KEEP, _gl.KEEP, _gl.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();
- _gl.disable( _gl.STENCIL_TEST );
- }
- /*
- * 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( setMaterialForwardRendering );
- _passForward.scene = scene;
- _passForward.camera = camera;
- }
- enableFinalPasses();
- _this.renderer.autoClearDepth = false;
- _this.renderer.autoClearStencil = false;
- _compFinal.render();
- }
- // 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 tmpSceneAutoUpdate = scene.autoUpdate;
- var tmpAutoClearColor = this.renderer.autoClearColor;
- var tmpAutoClearDepth = this.renderer.autoClearDepth;
- var tmpAutoClearStencil = this.renderer.autoClearStencil;
- initLightScene( scene );
- scene.autoUpdate = false;
- scene.updateMatrixWorld();
- _hasTransparentObject = false;
- scene.traverse( saveOriginalMaterialAndCheckTransparency );
- renderNormalDepth( scene, camera );
- if ( _lightPrePass ) {
- renderLightPre( scene, camera );
- renderReconstruction( scene, camera );
- } else {
- renderColor( scene, camera );
- renderLight( scene, camera );
- }
- renderFinal( scene, camera );
- scene.traverse( restoreOriginalMaterial );
- scene.autoUpdate = tmpSceneAutoUpdate;
- this.renderer.autoClearColor = tmpAutoClearColor;
- this.renderer.autoClearDepth = tmpAutoClearDepth;
- this.renderer.autoClearStencil = tmpAutoClearStencil;
- };
- // 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" ),
- 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" ),
- // TODO: optimize normal packing. reference http://aras-p.info/texts/CompactNormalStorage.html
- packNormalDepthShininess: [
- "vec4 packedNormalDepthShininess;",
- "packedNormalDepthShininess.x = vec3_to_float( normal * 0.5 + 0.5 );",
- "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 = float_to_vec3( normalDepthMap.x ) * 2.0 - 1.0;",
- "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.ShaderDeferred = {
- normalDepth: {
- uniforms: {},
- vertexShader: [
- "varying vec3 vNormal;",
- "varying vec4 vPosition;",
- THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
- THREE.ShaderChunk[ "skinning_pars_vertex" ],
- "void main() {",
- THREE.ShaderChunk[ "begin_vertex" ],
- THREE.ShaderChunk[ "beginnormal_vertex" ],
- THREE.ShaderChunk[ "skinbase_vertex" ],
- THREE.ShaderChunk[ "skinnormal_vertex" ],
- THREE.ShaderChunk[ "defaultnormal_vertex" ],
- THREE.ShaderChunk[ "morphtarget_vertex" ],
- THREE.ShaderChunk[ "skinning_vertex" ],
- THREE.ShaderChunk[ "project_vertex" ],
- "vNormal = normalize( normalMatrix * objectNormal );",
- "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: { value: null },
- offsetRepeat: { value: new THREE.Vector4( 0, 0, 1, 1 ) },
- diffuse: { value: new THREE.Color( 0x000000 ) },
- emissive: { value: new THREE.Color( 0x000000 ) },
- specular: { value: new THREE.Color( 0x000000 ) },
- shininess: { value: 30.0 }
- },
- vertexShader: [
- THREE.ShaderChunk[ "uv_pars_vertex" ],
- THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
- THREE.ShaderChunk[ "skinning_pars_vertex" ],
- "void main() {",
- THREE.ShaderChunk[ "uv_vertex" ],
- THREE.ShaderChunk[ "begin_vertex" ],
- THREE.ShaderChunk[ "beginnormal_vertex" ],
- THREE.ShaderChunk[ "skinbase_vertex" ],
- THREE.ShaderChunk[ "skinnormal_vertex" ],
- THREE.ShaderChunk[ "defaultnormal_vertex" ],
- THREE.ShaderChunk[ "morphtarget_vertex" ],
- THREE.ShaderChunk[ "skinning_vertex" ],
- THREE.ShaderChunk[ "project_vertex" ],
- "}"
- ].join( "\n" ),
- fragmentShader: [
- "uniform vec3 diffuse;",
- "uniform vec3 emissive;",
- "uniform vec3 specular;",
- "uniform float shininess;",
- THREE.ShaderChunk[ "uv_pars_fragment" ],
- THREE.ShaderChunk[ "map_pars_fragment" ],
- THREE.DeferredShaderChunk[ "packVector3" ],
- "void main() {",
- "vec4 diffuseColor = vec4( diffuse, 1.0 );",
- "vec3 emissiveColor = emissive;",
- "vec3 specularColor = specular;",
- THREE.ShaderChunk[ "map_fragment" ],
- THREE.DeferredShaderChunk[ "packColor" ],
- "gl_FragColor = packedColor;",
- "}"
- ].join( "\n" )
- },
- emissiveLight: {
- uniforms: {
- samplerColor: { value: null },
- viewWidth: { value: 800 },
- viewHeight: { value: 600 }
- },
- 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: {
- samplerNormalDepth: { value: null },
- samplerColor: { value: null },
- matProjInverse: { value: new THREE.Matrix4() },
- viewWidth: { value: 800 },
- viewHeight: { value: 600 },
- lightColor: { value: new THREE.Color( 0x000000 ) },
- lightPositionVS: { value: new THREE.Vector3( 0, 1, 0 ) },
- lightIntensity: { value: 1.0 },
- lightRadius: { value: 1.0 }
- },
- 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: {
- samplerNormalDepth: { value: null },
- samplerColor: { value: null },
- matProjInverse: { value: new THREE.Matrix4() },
- viewWidth: { value: 800 },
- viewHeight: { value: 600 },
- lightColor: { value: new THREE.Color( 0x000000 ) },
- lightDirectionVS: { value: new THREE.Vector3( 0, 1, 0 ) },
- lightPositionVS: { value: new THREE.Vector3( 0, 1, 0 ) },
- lightAngle: { value: 1.0 },
- lightIntensity: { value: 1.0 }
- },
- 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 * 0.5 );",
- "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: {
- samplerNormalDepth: { value: null },
- samplerColor: { value: null },
- matProjInverse: { value: new THREE.Matrix4() },
- viewWidth: { value: 800 },
- viewHeight: { value: 600 },
- lightColor: { value: new THREE.Color( 0x000000 ) },
- lightDirectionVS : { value: new THREE.Vector3( 0, 1, 0 ) },
- lightIntensity: { value: 1.0 }
- },
- 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: { value: 30.0 }
- },
- vertexShader: [
- "varying vec3 vNormal;",
- "varying vec4 vPosition;",
- THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
- THREE.ShaderChunk[ "skinning_pars_vertex" ],
- "void main() {",
- THREE.ShaderChunk[ "begin_vertex" ],
- THREE.ShaderChunk[ "beginnormal_vertex" ],
- THREE.ShaderChunk[ "skinbase_vertex" ],
- THREE.ShaderChunk[ "skinnormal_vertex" ],
- THREE.ShaderChunk[ "defaultnormal_vertex" ],
- THREE.ShaderChunk[ "morphtarget_vertex" ],
- THREE.ShaderChunk[ "skinning_vertex" ],
- THREE.ShaderChunk[ "project_vertex" ],
- "vNormal = normalize( normalMatrix * objectNormal );",
- "vPosition = gl_Position;",
- "}"
- ].join( "\n" ),
- fragmentShader: [
- "varying vec3 vNormal;",
- "varying vec4 vPosition;",
- "uniform float shininess;",
- THREE.DeferredShaderChunk[ "packVector3" ],
- "void main() {",
- "vec3 normal = vNormal;",
- "vec4 position = vPosition;",
- THREE.DeferredShaderChunk[ "packNormalDepthShininess" ],
- "gl_FragColor = packedNormalDepthShininess;",
- "}"
- ].join( "\n" )
- },
- pointLightPre: {
- uniforms: {
- samplerNormalDepthShininess: { value: null },
- matProjInverse: { value: new THREE.Matrix4() },
- viewWidth: { value: 800 },
- viewHeight: { value: 600 },
- lightColor: { value: new THREE.Color( 0x000000 ) },
- lightPositionVS: { value: new THREE.Vector3( 0, 1, 0 ) },
- lightIntensity: { value: 1.0 },
- lightRadius: { value: 1.0 }
- },
- 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" ],
- "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: {
- samplerNormalDepthShininess: { value: null },
- matProjInverse: { value: new THREE.Matrix4() },
- viewWidth: { value: 800 },
- viewHeight: { value: 600 },
- lightColor: { value: new THREE.Color( 0x000000 ) },
- lightDirectionVS: { value: new THREE.Vector3( 0, 1, 0 ) },
- lightPositionVS: { value: new THREE.Vector3( 0, 1, 0 ) },
- lightAngle: { value: 1.0 },
- lightIntensity: { value: 1.0 }
- },
- 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" ],
- "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 * 0.5 );",
- "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: {
- samplerNormalDepthShininess: { value: null },
- matProjInverse: { value: new THREE.Matrix4() },
- viewWidth: { value: 800 },
- viewHeight: { value: 600 },
- lightColor: { value: new THREE.Color( 0x000000 ) },
- lightDirectionVS : { value: new THREE.Vector3( 0, 1, 0 ) },
- lightIntensity: { value: 1.0 }
- },
- 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" ],
- "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: {
- samplerLight: { value: null },
- map: { value: null },
- offsetRepeat: { value: new THREE.Vector4( 0, 0, 1, 1 ) },
- viewWidth: { value: 800 },
- viewHeight: { value: 600 },
- diffuse: { value: new THREE.Color( 0x000000 ) },
- emissive: { value: new THREE.Color( 0x000000 ) },
- specular: { value: new THREE.Color( 0x000000 ) },
- shininess: { value: 30.0 }
- },
- vertexShader: [
- THREE.ShaderChunk[ "uv_pars_vertex" ],
- THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
- THREE.ShaderChunk[ "skinning_pars_vertex" ],
- "void main() {",
- THREE.ShaderChunk[ "uv_vertex" ],
- THREE.ShaderChunk[ "begin_vertex" ],
- THREE.ShaderChunk[ "beginnormal_vertex" ],
- THREE.ShaderChunk[ "skinbase_vertex" ],
- THREE.ShaderChunk[ "skinnormal_vertex" ],
- THREE.ShaderChunk[ "defaultnormal_vertex" ],
- THREE.ShaderChunk[ "morphtarget_vertex" ],
- THREE.ShaderChunk[ "skinning_vertex" ],
- THREE.ShaderChunk[ "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;",
- THREE.ShaderChunk[ "uv_pars_fragment" ],
- THREE.ShaderChunk[ "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 );",
- THREE.ShaderChunk[ "map_fragment" ],
- "vec3 diffuseFinal = diffuseColor.rgb * light.rgb;",
- "vec3 emissiveFinal = emissiveColor;",
- "vec3 specularFinal = specularColor * light.rgb * ( light.a / ( 0.2126 * light.r + 0.7152 * light.g + 0.0722 * light.b + 0.00001 ) );",
- "gl_FragColor = vec4( diffuseFinal + emissiveFinal + specularFinal, 1.0 );",
- "}"
- ].join( "\n" )
- },
- // TODO: implement tone mapping
- final: {
- uniforms: {
- samplerResult: { value: 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" )
- }
- };
|