WebGLDeferredRenderer.js 55 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524
  1. /**
  2. * @author alteredq / http://alteredqualia.com/
  3. * @author MPanknin / http://www.redplant.de/
  4. * @author takahiro / https://github.com/takahirox
  5. *
  6. * WebGLDeferredRenderer supports two types of Deferred Renderings.
  7. * One is Classic Deferred Rendering and the other one is
  8. * Light Pre-Pass (Deferred Lighting).
  9. * Classic Deferred Rendering is default. You can use Light Pre-Pass
  10. * by calling .enableLightPrePass( true ) method.
  11. *
  12. * Dependencies
  13. * - THREE.CopyShader
  14. * - THREE.RenderPass
  15. * - THREE.ShaderPass
  16. * - THREE.EffectComposer
  17. * - THREE.FXAAShader
  18. *
  19. * TODO
  20. * - reuse existing glsl
  21. * - shadow
  22. * - optimization
  23. * - MRT (when it's available on Three.js)
  24. * - AmbientLight
  25. * - HemisphereLight
  26. * - PointLight (distance < 0)
  27. * - morphNormals
  28. * - BumpMap
  29. * - ToneMap
  30. * - envMap
  31. * - wrapAround
  32. * - addEffect
  33. */
  34. THREE.WebGLDeferredRenderer = function ( parameters ) {
  35. parameters = parameters || {};
  36. // private properties
  37. var _this = this;
  38. var _context;
  39. var _state;
  40. var _width, _height;
  41. // for Classic Deferred Rendering
  42. var _compColor;
  43. var _passColor, _passForward, _passCopy;
  44. // for Light Pre-Pass
  45. var _compReconstruction;
  46. var _passReconstruction;
  47. // for Common
  48. var _compNormalDepth, _compLight, _compFinal;
  49. var _passNormalDepth, _passLight, _passLightFullscreen, _passFinal, _passFXAA;
  50. var _depthTexture;
  51. var _currentCamera;
  52. var _lightScene, _lightFullscreenScene;
  53. var _antialias = false;
  54. var _hasTransparentObject = false;
  55. var _lightPrePass = false;
  56. var _cacheKeepAlive = false;
  57. var _tmpMaterial = new THREE.ShaderMaterial( { visible: false } );
  58. var _tmpVector3 = new THREE.Vector3();
  59. // scene/material/light cache for deferred rendering.
  60. // save them at the creation and release
  61. // if they're unused removeThresholdCount frames
  62. // unless _cacheKeepAlive is true.
  63. // scene.uuid -> lightScene, lightFullscreenScene
  64. var _lightScenesCache = {};
  65. var _lightFullscreenScenesCache = {};
  66. // object.material.uuid -> deferredMaterial or
  67. // object.material[ n ].uuid -> deferredMaterial
  68. var _normalDepthMaterialsCache = {};
  69. var _normalDepthShininessMaterialsCache = {};
  70. var _colorMaterialsCache = {};
  71. var _reconstructionMaterialsCache = {};
  72. // originalLight.uuid -> deferredLight
  73. var _deferredLightsCache = {};
  74. // deferredLight.uuid -> deferredLightMaterial
  75. var _classicDeferredLightMaterialsCache = {};
  76. var _lightPrePassMaterialsCache = {};
  77. var _removeThresholdCount = 60;
  78. // deferredMaterials.uuid -> object.material or
  79. // deferredMaterials.uuid -> object.material[ n ]
  80. // save before render and release after render.
  81. var _originalMaterialsTable = {};
  82. // object.uuid -> originalOnBeforeRender
  83. // save before render and release after render.
  84. var _originalOnBeforeRendersTable = {};
  85. // object.material.uuid -> object.material.visible or
  86. // object.material[ i ].uuid -> object.material[ i ].visible or
  87. // save before render and release after render.
  88. var _originalVisibleTable = {};
  89. // external properties
  90. this.renderer = undefined;
  91. this.domElement = undefined;
  92. this.forwardRendering = false; // for debug
  93. // private methods
  94. function init( parameters ) {
  95. _this.renderer = parameters.renderer !== undefined ? parameters.renderer : new THREE.WebGLRenderer();
  96. _this.domElement = _this.renderer.domElement;
  97. _context = _this.renderer.context;
  98. _state = _this.renderer.state;
  99. _width = parameters.width !== undefined ? parameters.width : _this.renderer.getSize( new THREE.Vector2() ).width;
  100. _height = parameters.height !== undefined ? parameters.height : _this.renderer.getSize( new THREE.Vector2() ).height;
  101. var antialias = parameters.antialias !== undefined ? parameters.antialias : false;
  102. if ( parameters.cacheKeepAlive !== undefined ) _cacheKeepAlive = parameters.cacheKeepAlive;
  103. initDepthTexture();
  104. initPassNormalDepth();
  105. initPassColor();
  106. initPassLight();
  107. initPassReconstruction();
  108. initPassFinal();
  109. _this.setSize( _width, _height );
  110. _this.setAntialias( antialias );
  111. _this.enableLightPrePass( false );
  112. }
  113. function initDepthTexture() {
  114. _depthTexture = new THREE.DepthTexture(
  115. _width,
  116. _height,
  117. THREE.UnsignedInt248Type,
  118. undefined,
  119. undefined,
  120. undefined,
  121. undefined,
  122. undefined,
  123. undefined,
  124. THREE.DepthStencilFormat
  125. );
  126. }
  127. function initPassNormalDepth() {
  128. _passNormalDepth = new THREE.RenderPass();
  129. _passNormalDepth.clear = true;
  130. var rt = new THREE.WebGLRenderTarget( _width, _height, {
  131. minFilter: THREE.NearestFilter,
  132. magFilter: THREE.NearestFilter,
  133. format: THREE.RGBAFormat,
  134. type: THREE.FloatType,
  135. stencilBuffer: true,
  136. depthTexture: _depthTexture
  137. } );
  138. rt.texture.generateMipamps = false;
  139. _compNormalDepth = new THREE.EffectComposer( _this.renderer, rt );
  140. _compNormalDepth.addPass( _passNormalDepth );
  141. }
  142. function initPassColor() {
  143. _passColor = new THREE.RenderPass();
  144. _passColor.clear = true;
  145. var rt = new THREE.WebGLRenderTarget( _width, _height, {
  146. minFilter: THREE.NearestFilter,
  147. magFilter: THREE.NearestFilter,
  148. format: THREE.RGBAFormat,
  149. type: THREE.FloatType,
  150. depthTexture: _depthTexture
  151. } );
  152. rt.texture.generateMipamps = false;
  153. _compColor = new THREE.EffectComposer( _this.renderer, rt );
  154. _compColor.addPass( _passColor );
  155. }
  156. function initPassLight() {
  157. _passLightFullscreen = new THREE.RenderPass();
  158. _passLightFullscreen.clear = true;
  159. _passLightFullscreen.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
  160. _passLight = new THREE.RenderPass();
  161. _passLight.clear = false;
  162. var rt = new THREE.WebGLRenderTarget( _width, _height, {
  163. minFilter: THREE.NearestFilter,
  164. magFilter: THREE.NearestFilter,
  165. format: THREE.RGBAFormat,
  166. type: THREE.FloatType,
  167. depthTexture: _depthTexture
  168. } );
  169. rt.texture.generateMipamps = false;
  170. _compLight = new THREE.EffectComposer( _this.renderer, rt );
  171. _compLight.addPass( _passLightFullscreen );
  172. _compLight.addPass( _passLight );
  173. }
  174. function initPassReconstruction() {
  175. _passReconstruction = new THREE.RenderPass();
  176. _passReconstruction.clear = true;
  177. var rt = new THREE.WebGLRenderTarget( _width, _height, {
  178. minFilter: THREE.NearestFilter,
  179. magFilter: THREE.NearestFilter,
  180. format: THREE.RGBAFormat,
  181. type: THREE.FloatType,
  182. depthTexture: _depthTexture
  183. } );
  184. rt.texture.generateMipamps = false;
  185. _compReconstruction = new THREE.EffectComposer( _this.renderer, rt );
  186. _compReconstruction.addPass( _passReconstruction );
  187. }
  188. function initPassFinal() {
  189. _passFinal = new THREE.ShaderPass( THREE.ShaderDeferred[ 'final' ] );
  190. _passFinal.clear = true;
  191. _passFinal.uniforms.samplerResult.value = _compLight.renderTarget2.texture;
  192. _passFinal.material.blending = THREE.NoBlending;
  193. _passFinal.material.depthWrite = false;
  194. _passFinal.material.depthTest = false;
  195. _passForward = new THREE.RenderPass();
  196. _passForward.clear = false;
  197. _passCopy = new THREE.ShaderPass( THREE.CopyShader );
  198. _passFXAA = new THREE.ShaderPass( THREE.FXAAShader );
  199. var rt = new THREE.WebGLRenderTarget( _width, _height, {
  200. minFilter: THREE.NearestFilter,
  201. magFilter: THREE.LinearFilter,
  202. format: THREE.RGBFormat,
  203. type: THREE.UnsignedByteType,
  204. depthTexture: _depthTexture
  205. } );
  206. rt.texture.generateMipamps = false;
  207. _compFinal = new THREE.EffectComposer( _this.renderer, rt );
  208. _compFinal.addPass( _passFinal );
  209. _compFinal.addPass( _passForward );
  210. _compFinal.addPass( _passCopy );
  211. _compFinal.addPass( _passFXAA );
  212. }
  213. function initLightScene( scene ) {
  214. var lightSceneData = _lightScenesCache[ scene.uuid ];
  215. var lightFullscreenSceneData = _lightFullscreenScenesCache[ scene.uuid ];
  216. if ( lightSceneData === undefined ) {
  217. var s = new THREE.Scene();
  218. s.userData.lights = {};
  219. lightSceneData = createCacheData();
  220. lightSceneData.scene = s;
  221. _lightScenesCache[ scene.uuid ] = lightSceneData;
  222. }
  223. if ( lightFullscreenSceneData === undefined ) {
  224. var s = new THREE.Scene();
  225. s.userData.lights = {};
  226. var emissiveLight = createDeferredEmissiveLight();
  227. s.userData.emissiveLight = emissiveLight;
  228. s.add( emissiveLight );
  229. lightFullscreenSceneData = createCacheData();
  230. lightFullscreenSceneData.scene = s;
  231. _lightFullscreenScenesCache[ scene.uuid ] = lightFullscreenSceneData;
  232. }
  233. lightSceneData.used = true;
  234. lightFullscreenSceneData.used = true;
  235. var lightScene = lightSceneData.scene;
  236. var lightFullscreenScene = lightFullscreenSceneData.scene;
  237. // emissiveLight is only for Classic Deferred Rendering
  238. lightFullscreenScene.userData.emissiveLight.visible = ! _lightPrePass;
  239. _lightScene = lightScene;
  240. _lightFullscreenScene = lightFullscreenScene;
  241. }
  242. function getMaterialFromCacheOrCreate( originalMaterial, cache, createFunc, updateFunc ) {
  243. var data = cache[ originalMaterial.uuid ];
  244. if ( data === undefined ) {
  245. data = createCacheData();
  246. data.material = createFunc( originalMaterial );
  247. cache[ originalMaterial.uuid ] = data;
  248. }
  249. data.used = true;
  250. updateFunc( data.material, originalMaterial );
  251. _originalMaterialsTable[ data.material.uuid ] = originalMaterial;
  252. return data.material;
  253. }
  254. function overrideMaterialAndOnBeforeRender( object, getMaterialFunc, onBeforeRender ) {
  255. if ( object.material === undefined ) return;
  256. if ( Array.isArray( object.material ) ) {
  257. for ( var i = 0, il = object.material.length; i < il; i ++ ) {
  258. object.material[ i ] = getMaterialFunc( object.material[ i ] );
  259. }
  260. } else {
  261. object.material = getMaterialFunc( object.material );
  262. }
  263. object.onBeforeRender = onBeforeRender;
  264. }
  265. function restoreOriginalMaterial( object ) {
  266. if ( object.material === undefined ) return;
  267. if ( Array.isArray( object.material ) ) {
  268. for ( var i = 0, il = object.material.length; i < il; i ++ ) {
  269. object.material[ i ] = _originalMaterialsTable[ object.material[ i ].uuid ];
  270. }
  271. } else {
  272. object.material = _originalMaterialsTable[ object.material.uuid ];
  273. }
  274. }
  275. function setMaterialNormalDepth( object ) {
  276. overrideMaterialAndOnBeforeRender( object, getNormalDepthMaterial, updateDeferredNormalDepthUniforms );
  277. }
  278. function getNormalDepthMaterial( originalMaterial ) {
  279. return getMaterialFromCacheOrCreate(
  280. originalMaterial,
  281. ( _lightPrePass ) ? _normalDepthShininessMaterialsCache : _normalDepthMaterialsCache,
  282. createDeferredNormalDepthMaterial,
  283. updateDeferredNormalDepthMaterial
  284. );
  285. }
  286. function createDeferredNormalDepthMaterial( originalMaterial ) {
  287. var shader = ( _lightPrePass ) ? THREE.ShaderDeferred[ 'normalDepthShininess' ] : THREE.ShaderDeferred[ 'normalDepth' ];
  288. return new THREE.ShaderMaterial( {
  289. uniforms: Object.assign( {}, shader.uniforms ),
  290. fragmentShader: shader.fragmentShader,
  291. vertexShader: shader.vertexShader,
  292. blending: THREE.NoBlending
  293. } );
  294. }
  295. function updateDeferredNormalDepthMaterial( material, originalMaterial ) {
  296. if ( originalMaterial.skinning !== undefined ) material.skinning = originalMaterial.skinning;
  297. if ( originalMaterial.morphTargets !== undefined ) material.morphTargets = originalMaterial.morphTargets;
  298. if ( originalMaterial.visible === true ) {
  299. material.visible = ! originalMaterial.transparent;
  300. } else {
  301. material.visible = false;
  302. }
  303. }
  304. function updateDeferredNormalDepthUniforms( renderer, scene, camera, geometry, material, group ) {
  305. if ( ! _lightPrePass ) return;
  306. var originalMaterial = _originalMaterialsTable[ material.uuid ];
  307. if ( originalMaterial === undefined || originalMaterial.shininess === undefined ) return;
  308. material.uniforms.shininess.value = originalMaterial.shininess;
  309. }
  310. function setMaterialColor( object ) {
  311. overrideMaterialAndOnBeforeRender( object, getColorMaterial, updateDeferredColorUniforms );
  312. }
  313. function getColorMaterial( originalMaterial ) {
  314. return getMaterialFromCacheOrCreate(
  315. originalMaterial,
  316. _colorMaterialsCache,
  317. createDeferredColorMaterial,
  318. updateDeferredColorMaterial
  319. );
  320. }
  321. function createDeferredColorMaterial( originalMaterial ) {
  322. var shader = THREE.ShaderDeferred[ 'color' ];
  323. var material = new THREE.ShaderMaterial( {
  324. uniforms: Object.assign( {}, shader.uniforms ),
  325. fragmentShader: shader.fragmentShader,
  326. vertexShader: shader.vertexShader,
  327. blending: THREE.NoBlending
  328. } );
  329. if ( originalMaterial.map !== undefined ) material.map = originalMaterial.map;
  330. return material;
  331. }
  332. function updateDeferredColorMaterial( material, originalMaterial ) {
  333. if ( originalMaterial.map !== undefined ) material.map = originalMaterial.map;
  334. if ( originalMaterial.skinning !== undefined ) material.skinning = originalMaterial.skinning;
  335. if ( originalMaterial.morphTargets !== undefined ) material.morphTargets = originalMaterial.morphTargets;
  336. if ( originalMaterial.visible === true ) {
  337. material.visible = ! originalMaterial.transparent;
  338. } else {
  339. material.visible = false;
  340. }
  341. }
  342. function updateDeferredColorUniforms( renderer, scene, camera, geometry, material, group ) {
  343. var originalMaterial = _originalMaterialsTable[ material.uuid ];
  344. var uniforms = material.uniforms;
  345. var diffuse, emissive;
  346. if ( originalMaterial.isMeshBasicMaterial === true ) {
  347. emissive = originalMaterial.color;
  348. } else {
  349. diffuse = originalMaterial.color;
  350. emissive = originalMaterial.emissive;
  351. }
  352. var specular = originalMaterial.specular;
  353. var shininess = originalMaterial.shininess;
  354. var map = originalMaterial.map;
  355. if ( diffuse !== undefined ) uniforms.diffuse.value.copy( diffuse );
  356. if ( emissive !== undefined ) uniforms.emissive.value.copy( emissive );
  357. if ( specular !== undefined ) uniforms.specular.value.copy( specular );
  358. if ( shininess !== undefined && uniforms.shininess !== undefined ) uniforms.shininess.value = shininess;
  359. if ( map !== undefined ) uniforms.map.value = map;
  360. }
  361. function setMaterialReconstruction( object ) {
  362. overrideMaterialAndOnBeforeRender( object, getReconstructionMaterial, updateDeferredReconstructionUniforms );
  363. }
  364. function getReconstructionMaterial( originalMaterial ) {
  365. if ( originalMaterial.transparent === true ) {
  366. _originalMaterialsTable[ originalMaterial.uuid ] = originalMaterial;
  367. return originalMaterial;
  368. }
  369. return getMaterialFromCacheOrCreate(
  370. originalMaterial,
  371. _reconstructionMaterialsCache,
  372. createDeferredReconstructionMaterial,
  373. updateDeferredReconstructionMaterial
  374. );
  375. }
  376. function createDeferredReconstructionMaterial( originalMaterial ) {
  377. var shader = THREE.ShaderDeferred[ 'reconstruction' ];
  378. var material = new THREE.ShaderMaterial( {
  379. uniforms: Object.assign( {}, shader.uniforms ),
  380. fragmentShader: shader.fragmentShader,
  381. vertexShader: shader.vertexShader,
  382. blending: THREE.NoBlending
  383. } );
  384. if ( originalMaterial.map !== undefined ) material.map = originalMaterial.map;
  385. return material;
  386. }
  387. function updateDeferredReconstructionMaterial( material, originalMaterial ) {
  388. updateDeferredColorMaterial( material, originalMaterial );
  389. }
  390. function updateDeferredReconstructionUniforms( renderer, scene, camera, geometry, material, group ) {
  391. if ( material.transparent === true ) {
  392. // 'this' is object here because this method is set as object.onBefore()
  393. var onBeforeRender = _originalOnBeforeRendersTable[ this.uuid ];
  394. if ( onBeforeRender ) {
  395. onBeforeRender.call( this, renderer, scene, camera, geometry, material, group );
  396. }
  397. return;
  398. }
  399. updateDeferredColorUniforms( renderer, scene, camera, geometry, material, group );
  400. material.uniforms.samplerLight.value = _compLight.renderTarget2.texture;
  401. }
  402. function setVisibleForForwardRendering( object ) {
  403. if ( object.material === undefined ) return;
  404. if ( Array.isArray( object.material ) ) {
  405. for ( var i = 0, il = object.material.length; i < il; i ++ ) {
  406. if ( _originalVisibleTable[ object.material[ i ].uuid ] === undefined ) {
  407. _originalVisibleTable[ object.material[ i ].uuid ] = object.material[ i ].visible;
  408. object.material[ i ].visible = object.material[ i ].transparent && object.material[ i ].visible;
  409. }
  410. }
  411. } else {
  412. if ( _originalVisibleTable[ object.material.uuid ] === undefined ) {
  413. _originalVisibleTable[ object.material.uuid ] = object.material.visible;
  414. object.material.visible = object.material.transparent && object.material.visible;
  415. }
  416. }
  417. }
  418. function restoreVisible( object ) {
  419. if ( object.material === undefined ) return;
  420. if ( Array.isArray( object.material ) ) {
  421. for ( var i = 0, il = object.material.length; i < il; i ++ ) {
  422. object.material[ i ].visible = _originalVisibleTable[ object.material[ i ].uuid ];
  423. }
  424. } else {
  425. object.material.visible = _originalVisibleTable[ object.material.uuid ];
  426. }
  427. }
  428. function createDeferredEmissiveLight() {
  429. var shader = THREE.ShaderDeferred[ 'emissiveLight' ];
  430. var material = new THREE.ShaderMaterial( {
  431. uniforms: Object.assign( {}, shader.uniforms ),
  432. vertexShader: shader.vertexShader,
  433. fragmentShader: shader.fragmentShader,
  434. blending: THREE.NoBlending,
  435. depthWrite: false
  436. } );
  437. var geometry = new THREE.PlaneBufferGeometry( 2, 2 );
  438. var mesh = new THREE.Mesh( geometry, material );
  439. mesh.onBeforeRender = function ( renderer, scene, camera, geometry, material, group ) {
  440. material.uniforms.samplerColor.value = _compColor.renderTarget2.texture;
  441. };
  442. return mesh;
  443. }
  444. function createDeferredLight( originalLight ) {
  445. if ( originalLight.isPointLight ) {
  446. return createDeferredPointLight( originalLight );
  447. } else if ( originalLight.isSpotLight ) {
  448. return createDeferredSpotLight( originalLight );
  449. } else if ( originalLight.isDirectionalLight ) {
  450. return createDeferredDirectionalLight( originalLight );
  451. }
  452. return null;
  453. }
  454. function createDeferredLightMaterial( originalLight ) {
  455. if ( originalLight.isPointLight ) {
  456. return createDeferredPointLightMaterial();
  457. } else if ( originalLight.isSpotLight ) {
  458. return createDeferredSpotLightMaterial();
  459. } else if ( originalLight.isDirectionalLight ) {
  460. return createDeferredDirectionalLightMaterial();
  461. }
  462. return null;
  463. }
  464. function getDeferredLightMaterial( light ) {
  465. var cache = ( _lightPrePass ) ? _lightPrePassMaterialsCache : _classicDeferredLightMaterialsCache;
  466. var data = cache[ light.uuid ];
  467. if ( data === undefined ) {
  468. data = createCacheData();
  469. data.material = createDeferredLightMaterial( light.userData.originalLight );
  470. cache[ light.uuid ] = data;
  471. }
  472. data.used = true;
  473. return data.material;
  474. }
  475. function updateDeferredLight( light ) {
  476. var originalLight = light.userData.originalLight;
  477. if ( originalLight.isPointLight ) {
  478. updateDeferredPointLight( light );
  479. }
  480. }
  481. function createDeferredLightMesh( light, geometry ) {
  482. var mesh = new THREE.Mesh( geometry, _tmpMaterial );
  483. mesh.userData.originalLight = light;
  484. return mesh;
  485. }
  486. function createDeferredLightShaderMaterial( shader ) {
  487. var material = new THREE.ShaderMaterial( {
  488. uniforms: Object.assign( {}, shader.uniforms ),
  489. vertexShader: shader.vertexShader,
  490. fragmentShader: shader.fragmentShader,
  491. transparent: true,
  492. blending: THREE.AdditiveBlending,
  493. depthWrite: false
  494. } );
  495. if ( _lightPrePass ) material.premultipliedAlpha = true;
  496. return material;
  497. }
  498. function updateDeferredLightCommonUniforms( uniforms ) {
  499. if ( _lightPrePass ) {
  500. uniforms.samplerNormalDepthShininess.value = _compNormalDepth.renderTarget2.texture;
  501. } else {
  502. uniforms.samplerNormalDepth.value = _compNormalDepth.renderTarget2.texture;
  503. uniforms.samplerColor.value = _compColor.renderTarget2.texture;
  504. }
  505. }
  506. function createDeferredPointLight( light ) {
  507. var mesh = createDeferredLightMesh( light, new THREE.SphereBufferGeometry( 1, 16, 8 ) );
  508. mesh.onBeforeRender = updateDeferredPointLightUniforms;
  509. return mesh;
  510. }
  511. /*
  512. * optimization:
  513. * Renders PointLight only back face with stencil test.
  514. */
  515. function createDeferredPointLightMaterial() {
  516. var shader = ( _lightPrePass ) ? THREE.ShaderDeferred[ 'pointLightPre' ] : THREE.ShaderDeferred[ 'pointLight' ];
  517. var material = createDeferredLightShaderMaterial( shader );
  518. material.side = THREE.BackSide;
  519. material.depthFunc = THREE.GreaterEqualDepth;
  520. return material;
  521. }
  522. function updateDeferredPointLight( light ) {
  523. var originalLight = light.userData.originalLight;
  524. var distance = originalLight.distance;
  525. if ( distance > 0 ) {
  526. light.scale.set( 1, 1, 1 ).multiplyScalar( distance );
  527. light.position.setFromMatrixPosition( originalLight.matrixWorld );
  528. }
  529. }
  530. function updateDeferredPointLightUniforms( renderer, scene, camera, geometry, material, group ) {
  531. var light = this;
  532. var originalLight = light.userData.originalLight;
  533. var distance = originalLight.distance;
  534. var uniforms = material.uniforms;
  535. uniforms.lightColor.value.copy( originalLight.color );
  536. if ( distance > 0 ) {
  537. uniforms.lightRadius.value = distance;
  538. uniforms.lightIntensity.value = originalLight.intensity;
  539. uniforms.lightPositionVS.value.setFromMatrixPosition( originalLight.matrixWorld ).applyMatrix4( _currentCamera.matrixWorldInverse );
  540. } else {
  541. uniforms.lightRadius.value = Infinity;
  542. }
  543. updateDeferredLightCommonUniforms( uniforms );
  544. }
  545. function createDeferredSpotLight( light ) {
  546. var mesh = createDeferredLightMesh( light, new THREE.PlaneBufferGeometry( 2, 2 ) );
  547. mesh.onBeforeRender = updateDeferredSpotLightUniforms;
  548. return mesh;
  549. }
  550. function createDeferredSpotLightMaterial() {
  551. var shader = ( _lightPrePass ) ? THREE.ShaderDeferred[ 'spotLightPre' ] : THREE.ShaderDeferred[ 'spotLight' ];
  552. var material = createDeferredLightShaderMaterial( shader );
  553. material.depthTest = false;
  554. return material;
  555. }
  556. function updateDeferredSpotLightUniforms( renderer, scene, camera, geometry, material, group ) {
  557. var light = this;
  558. var originalLight = light.userData.originalLight;
  559. var uniforms = light.material.uniforms;
  560. uniforms.lightAngle.value = originalLight.angle;
  561. uniforms.lightColor.value.copy( originalLight.color );
  562. uniforms.lightIntensity.value = originalLight.intensity;
  563. uniforms.lightPositionVS.value.setFromMatrixPosition( originalLight.matrixWorld ).applyMatrix4( _currentCamera.matrixWorldInverse );
  564. var vec = uniforms.lightDirectionVS.value;
  565. var vec2 = _tmpVector3;
  566. vec.setFromMatrixPosition( originalLight.matrixWorld );
  567. vec2.setFromMatrixPosition( originalLight.target.matrixWorld );
  568. vec.sub( vec2 ).normalize().transformDirection( _currentCamera.matrixWorldInverse );
  569. updateDeferredLightCommonUniforms( uniforms );
  570. }
  571. function createDeferredDirectionalLight( light ) {
  572. var mesh = createDeferredLightMesh( light, new THREE.PlaneBufferGeometry( 2, 2 ) );
  573. mesh.onBeforeRender = updateDeferredDirectionalLightUniforms;
  574. return mesh;
  575. }
  576. function createDeferredDirectionalLightMaterial() {
  577. var shader = ( _lightPrePass ) ? THREE.ShaderDeferred[ 'directionalLightPre' ] : THREE.ShaderDeferred[ 'directionalLight' ];
  578. var material = createDeferredLightShaderMaterial( shader );
  579. material.depthTest = false;
  580. return material;
  581. }
  582. function updateDeferredDirectionalLightUniforms( renderer, scene, camera, geometry, material, group ) {
  583. var light = this;
  584. var originalLight = light.userData.originalLight;
  585. var uniforms = light.material.uniforms;
  586. uniforms.lightColor.value.copy( originalLight.color );
  587. uniforms.lightIntensity.value = originalLight.intensity;
  588. var vec = uniforms.lightDirectionVS.value;
  589. var vec2 = _tmpVector3;
  590. vec.setFromMatrixPosition( originalLight.matrixWorld );
  591. vec2.setFromMatrixPosition( originalLight.target.matrixWorld );
  592. vec.sub( vec2 ).normalize().transformDirection( _currentCamera.matrixWorldInverse );
  593. updateDeferredLightCommonUniforms( uniforms );
  594. }
  595. function saveOriginalOnBeforeRenderAndCheckTransparency( object ) {
  596. if ( object.material === undefined ) return;
  597. _originalOnBeforeRendersTable[ object.uuid ] = object.onBeforeRender;
  598. // _hasTransparentObject is used only for Classic Deferred Rendering
  599. if ( _hasTransparentObject || _lightPrePass ) return;
  600. if ( ! object.visible ) return;
  601. if ( Array.isArray( object.material ) ) {
  602. for ( var i = 0, il = object.material.length; i < il; i ++ ) {
  603. if ( object.material[ i ].visible === true && object.material[ i ].transparent === true ) {
  604. _hasTransparentObject = true;
  605. break;
  606. }
  607. }
  608. } else {
  609. if ( object.material.visible === true && object.material.transparent === true ) _hasTransparentObject = true;
  610. }
  611. }
  612. function restoreOriginalOnBeforeRender( object ) {
  613. if ( object.material === undefined ) return;
  614. object.onBeforeRender = _originalOnBeforeRendersTable[ object.uuid ];
  615. }
  616. function addDeferredLightsToLightScene( object ) {
  617. if ( object.isLight !== true ) return;
  618. var data = _deferredLightsCache[ object.uuid ];
  619. if ( data === undefined ) {
  620. data = createCacheData();
  621. data.light = createDeferredLight( object );
  622. _deferredLightsCache[ object.uuid ] = data;
  623. }
  624. data.used = true;
  625. var light = data.light;
  626. if ( light === null ) return;
  627. var scene = ( object.isPointLight === true ) ? _lightScene : _lightFullscreenScene;
  628. var lights = scene.userData.lights;
  629. if ( lights[ light.uuid ] === undefined ) {
  630. scene.add( light );
  631. lights[ light.uuid ] = {
  632. light: light,
  633. found: true
  634. };
  635. }
  636. lights[ light.uuid ].found = true;
  637. }
  638. function updateDeferredLightsInLightScene( scene ) {
  639. var lights = scene.userData.lights;
  640. var keys = Object.keys( lights );
  641. for ( var i = 0, il = keys.length; i < il; i ++ ) {
  642. var key = keys[ i ];
  643. if ( lights[ key ].found === false ) {
  644. scene.remove( lights[ key ].light );
  645. delete lights[ key ];
  646. } else {
  647. var light = lights[ key ].light;
  648. light.material = getDeferredLightMaterial( light );
  649. updateDeferredLight( light );
  650. lights[ key ].found = false;
  651. }
  652. }
  653. }
  654. function updateDeferredCommonUniforms( camera ) {
  655. var uniforms = THREE.ShaderDeferredCommon[ 'commonUniforms' ];
  656. uniforms.viewWidth.value = _width;
  657. uniforms.viewHeight.value = _height;
  658. uniforms.matProjInverse.value.getInverse( camera.projectionMatrix );
  659. }
  660. function enableFinalPasses() {
  661. if ( _lightPrePass ) {
  662. _passForward.renderToScreen = false;
  663. _passForward.enabled = false;
  664. _passCopy.renderToScreen = false;
  665. _passCopy.enabled = false;
  666. if ( _antialias ) {
  667. _passFinal.renderToScreen = false;
  668. _passFXAA.renderToScreen = true;
  669. _passFXAA.enabled = true;
  670. } else {
  671. _passFinal.renderToScreen = true;
  672. _passFXAA.renderToScreen = false;
  673. _passFXAA.enabled = false;
  674. }
  675. } else {
  676. if ( _hasTransparentObject ) {
  677. if ( _antialias ) {
  678. _passFinal.renderToScreen = false;
  679. _passForward.renderToScreen = false;
  680. _passForward.enabled = true;
  681. _passCopy.renderToScreen = false;
  682. _passCopy.enabled = false;
  683. _passFXAA.renderToScreen = true;
  684. _passFXAA.enabled = true;
  685. } else {
  686. _passFinal.renderToScreen = false;
  687. _passForward.renderToScreen = false;
  688. _passForward.enabled = true;
  689. _passCopy.renderToScreen = true;
  690. _passCopy.enabled = true;
  691. _passFXAA.renderToScreen = false;
  692. _passFXAA.enabled = false;
  693. }
  694. } else {
  695. if ( _antialias ) {
  696. _passFinal.renderToScreen = false;
  697. _passForward.renderToScreen = false;
  698. _passForward.enabled = false;
  699. _passCopy.renderToScreen = false;
  700. _passCopy.enabled = false;
  701. _passFXAA.renderToScreen = true;
  702. _passFXAA.enabled = true;
  703. } else {
  704. _passFinal.renderToScreen = true;
  705. _passForward.renderToScreen = false;
  706. _passForward.enabled = false;
  707. _passCopy.renderToScreen = false;
  708. _passCopy.enabled = false;
  709. _passFXAA.renderToScreen = false;
  710. _passFXAA.enabled = false;
  711. }
  712. }
  713. }
  714. }
  715. function createCacheData() {
  716. return {
  717. used: true,
  718. keepAlive: _cacheKeepAlive,
  719. count: 0
  720. };
  721. }
  722. function cleanupCache( cache ) {
  723. var keys = Object.keys( cache );
  724. for ( var i = 0, il = keys.length; i < il; i ++ ) {
  725. var key = keys[ i ];
  726. if ( cache[ key ].used === false ) {
  727. cache[ key ].count ++;
  728. if ( cache[ key ].keepAlive === false && cache[ key ].count > _removeThresholdCount ) {
  729. delete cache[ key ];
  730. }
  731. } else {
  732. cache[ key ].used = false;
  733. cache[ key ].count = 0;
  734. }
  735. }
  736. }
  737. function cleanupTable( table ) {
  738. var keys = Object.keys( table );
  739. for ( var i = 0, il = keys.length; i < il; i ++ ) {
  740. var key = keys[ i ];
  741. table[ key ] = undefined;
  742. }
  743. }
  744. function cleanupCaches() {
  745. cleanupCache( _lightScenesCache );
  746. cleanupCache( _lightFullscreenScenesCache );
  747. cleanupCache( _normalDepthMaterialsCache );
  748. cleanupCache( _normalDepthShininessMaterialsCache );
  749. cleanupCache( _colorMaterialsCache );
  750. cleanupCache( _reconstructionMaterialsCache );
  751. cleanupCache( _classicDeferredLightMaterialsCache );
  752. cleanupCache( _lightPrePassMaterialsCache );
  753. cleanupCache( _deferredLightsCache );
  754. cleanupTable( _originalMaterialsTable );
  755. cleanupTable( _originalOnBeforeRendersTable );
  756. cleanupTable( _originalVisibleTable );
  757. }
  758. /*
  759. * Classic Deferred Rendering
  760. *
  761. * 1) g-buffer normal + depth pass
  762. *
  763. * RGB: normal
  764. * A: depth
  765. *
  766. *
  767. * Light Pre-Pass Rendering
  768. *
  769. * 1') g-buffer normal + depth pass + shininess
  770. *
  771. * RG: normal
  772. * B: shininess
  773. * A: depth
  774. */
  775. function renderNormalDepth( scene, camera ) {
  776. scene.traverse( setMaterialNormalDepth );
  777. _passNormalDepth.scene = scene;
  778. _passNormalDepth.camera = camera;
  779. _this.renderer.autoClearDepth = true;
  780. _this.renderer.autoClearStencil = true;
  781. _state.buffers.stencil.setTest( true );
  782. _state.buffers.stencil.setFunc( _context.ALWAYS, 1, 0xffffffff );
  783. _state.buffers.stencil.setOp( _context.REPLACE, _context.REPLACE, _context.REPLACE );
  784. _compNormalDepth.render();
  785. scene.traverse( restoreOriginalMaterial );
  786. }
  787. /*
  788. * Classic Deferred Rendering
  789. *
  790. * 2) g-buffer color pass
  791. *
  792. * R: diffuse
  793. * G: emissive
  794. * B: specular
  795. * A: shininess
  796. */
  797. function renderColor( scene, camera ) {
  798. scene.traverse( setMaterialColor );
  799. _passColor.scene = scene;
  800. _passColor.camera = camera;
  801. _this.renderer.autoClearDepth = false;
  802. _this.renderer.autoClearStencil = false;
  803. _state.buffers.stencil.setFunc( _context.EQUAL, 1, 0xffffffff );
  804. _state.buffers.stencil.setOp( _context.KEEP, _context.KEEP, _context.KEEP );
  805. _compColor.render();
  806. scene.traverse( restoreOriginalMaterial );
  807. }
  808. /*
  809. * Classic Deferred Rendering
  810. *
  811. * 3) light pass
  812. */
  813. function renderLight( scene, camera ) {
  814. scene.traverse( addDeferredLightsToLightScene );
  815. updateDeferredLightsInLightScene( _lightScene );
  816. updateDeferredLightsInLightScene( _lightFullscreenScene );
  817. _passLight.scene = _lightScene;
  818. _passLight.camera = camera;
  819. _passLightFullscreen.scene = _lightFullscreenScene;
  820. _this.renderer.autoClearDepth = false;
  821. _this.renderer.autoClearStencil = false;
  822. _compLight.render();
  823. _state.buffers.stencil.setTest( false );
  824. }
  825. /*
  826. * Light Pre-Pass Rendering
  827. *
  828. * 2') Light pre pass
  829. */
  830. function renderLightPre( scene, camera ) {
  831. scene.traverse( addDeferredLightsToLightScene );
  832. updateDeferredLightsInLightScene( _lightScene );
  833. updateDeferredLightsInLightScene( _lightFullscreenScene );
  834. _passLight.scene = _lightScene;
  835. _passLight.camera = camera;
  836. _passLightFullscreen.scene = _lightFullscreenScene;
  837. _this.renderer.autoClearDepth = false;
  838. _this.renderer.autoClearStencil = false;
  839. _state.buffers.stencil.setFunc( _context.EQUAL, 1, 0xffffffff );
  840. _state.buffers.stencil.setOp( _context.KEEP, _context.KEEP, _context.KEEP );
  841. _compLight.render();
  842. }
  843. /*
  844. * Light Pre-Pass Rendering
  845. *
  846. * 3') Reconstruction pass
  847. *
  848. * Transprency handling:
  849. * Here renders transparent objects with normal forward rendering.
  850. */
  851. function renderReconstruction( scene, camera ) {
  852. scene.traverse( setMaterialReconstruction );
  853. _passReconstruction.scene = scene;
  854. _passReconstruction.camera = camera;
  855. _this.renderer.autoClearDepth = false;
  856. _this.renderer.autoClearStencil = false;
  857. _compReconstruction.render();
  858. _state.buffers.stencil.setTest( false );
  859. scene.traverse( restoreOriginalMaterial );
  860. }
  861. /*
  862. * Classic Deferred Rendering
  863. *
  864. * 4) Final pass
  865. *
  866. * transparency handling:
  867. * If there's any transparent objects, here renders them on the deferred rendering result
  868. * with normal forward rendering. This may be the easist way but heavy.
  869. * We should consider any better ways someday.
  870. *
  871. *
  872. * Light Pre-Pass Rendering
  873. *
  874. * 4') Final pass
  875. *
  876. *
  877. * Common
  878. *
  879. * antialias handling:
  880. * Here uses postprocessing FXAA for antialias.
  881. *
  882. */
  883. function renderFinal( scene, camera ) {
  884. if ( ! _lightPrePass && _hasTransparentObject ) {
  885. scene.traverse( setVisibleForForwardRendering );
  886. scene.traverse( restoreOriginalOnBeforeRender );
  887. _passForward.scene = scene;
  888. _passForward.camera = camera;
  889. }
  890. enableFinalPasses();
  891. _this.renderer.autoClearDepth = false;
  892. _this.renderer.autoClearStencil = false;
  893. _compFinal.render();
  894. if ( ! _lightPrePass && _hasTransparentObject ) {
  895. scene.traverse( restoreVisible );
  896. }
  897. }
  898. // external APIs
  899. this.setSize = function ( width, height ) {
  900. _width = width;
  901. _height = height;
  902. this.renderer.setSize( _width, _height );
  903. _compNormalDepth.setSize( _width, _height );
  904. _compColor.setSize( _width, _height );
  905. _compLight.setSize( _width, _height );
  906. _compReconstruction.setSize( _width, _height );
  907. _compFinal.setSize( _width, _height );
  908. _depthTexture.image.width = _width;
  909. _depthTexture.image.height = _height;
  910. _depthTexture.needsUpdate = true;
  911. _passFXAA.uniforms.resolution.value.set( 1 / _width, 1 / _height );
  912. };
  913. this.setAntialias = function ( enabled ) {
  914. _antialias = enabled;
  915. };
  916. this.enableLightPrePass = function ( enabled ) {
  917. _lightPrePass = enabled;
  918. _passFinal.uniforms.samplerResult.value = ( _lightPrePass ) ? _compReconstruction.renderTarget2.texture : _compLight.renderTarget2.texture;
  919. };
  920. this.render = function ( scene, camera ) {
  921. // for debug to compare with normal forward rendering
  922. if ( this.forwardRendering ) {
  923. this.renderer.render( scene, camera );
  924. return;
  925. }
  926. var currentSceneAutoUpdate = scene.autoUpdate;
  927. var currentAutoClearColor = this.renderer.autoClearColor;
  928. var currentAutoClearDepth = this.renderer.autoClearDepth;
  929. var currentAutoClearStencil = this.renderer.autoClearStencil;
  930. _currentCamera = camera;
  931. initLightScene( scene );
  932. scene.autoUpdate = false;
  933. scene.updateMatrixWorld();
  934. _hasTransparentObject = false;
  935. scene.traverse( saveOriginalOnBeforeRenderAndCheckTransparency );
  936. updateDeferredCommonUniforms( camera );
  937. renderNormalDepth( scene, camera );
  938. if ( _lightPrePass ) {
  939. renderLightPre( scene, camera );
  940. renderReconstruction( scene, camera );
  941. } else {
  942. renderColor( scene, camera );
  943. renderLight( scene, camera );
  944. }
  945. renderFinal( scene, camera );
  946. scene.traverse( restoreOriginalOnBeforeRender );
  947. cleanupCaches();
  948. scene.autoUpdate = currentSceneAutoUpdate;
  949. this.renderer.autoClearColor = currentAutoClearColor;
  950. this.renderer.autoClearDepth = currentAutoClearDepth;
  951. this.renderer.autoClearStencil = currentAutoClearStencil;
  952. };
  953. // initialize
  954. init( parameters );
  955. };
  956. THREE.DeferredShaderChunk = {
  957. packVector3: [
  958. "float vec3_to_float( vec3 data ) {",
  959. " const float unit = 255.0/256.0;",
  960. " highp float compressed = fract( data.x * unit ) + floor( data.y * unit * 255.0 ) + floor( data.z * unit * 255.0 ) * 255.0;",
  961. " return compressed;",
  962. "}"
  963. ].join( "\n" ),
  964. unpackFloat: [
  965. "vec3 float_to_vec3( float data ) {",
  966. " const float unit = 255.0;",
  967. " vec3 uncompressed;",
  968. " uncompressed.x = fract( data );",
  969. " float zInt = floor( data / unit );",
  970. " uncompressed.z = fract( zInt / unit );",
  971. " uncompressed.y = fract( floor( data - ( zInt * unit ) ) / unit );",
  972. " return uncompressed;",
  973. "}"
  974. ].join( "\n" ),
  975. // Refer to http://aras-p.info/texts/CompactNormalStorage.html
  976. packNormal: [
  977. "vec2 normal_to_vec2( vec3 normal ) {",
  978. " return normal.xy / sqrt( normal.z * 8.0 + 8.0 ) + 0.5;",
  979. "}"
  980. ].join( "\n" ),
  981. unpackVector2: [
  982. "vec3 vec2_to_normal( vec2 data ) {",
  983. " vec2 fenc = data * 4.0 - 2.0;",
  984. " float f = dot( fenc, fenc );",
  985. " float g = sqrt( 1.0 - f / 4.0 );",
  986. " vec3 normal;",
  987. " normal.xy = fenc * g;",
  988. " normal.z = 1.0 - f / 2.0;",
  989. " return normal;",
  990. "}"
  991. ].join( "\n" ),
  992. computeTextureCoord: [
  993. "vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );"
  994. ].join( "\n" ),
  995. packNormalDepth: [
  996. "vec4 packedNormalDepth;",
  997. "packedNormalDepth.xyz = normal * 0.5 + 0.5;",
  998. "packedNormalDepth.w = position.z / position.w;"
  999. ].join( "\n" ),
  1000. unpackNormalDepth: [
  1001. "vec4 normalDepthMap = texture2D( samplerNormalDepth, texCoord );",
  1002. "float depth = normalDepthMap.w;",
  1003. "if ( depth == 0.0 ) discard;",
  1004. "vec3 normal = normalDepthMap.xyz * 2.0 - 1.0;"
  1005. ].join( "\n" ),
  1006. packNormalDepthShininess: [
  1007. "vec4 packedNormalDepthShininess;",
  1008. "packedNormalDepthShininess.xy = normal_to_vec2( normal );",
  1009. "packedNormalDepthShininess.z = shininess;",
  1010. "packedNormalDepthShininess.w = position.z / position.w;"
  1011. ].join( "\n" ),
  1012. unpackNormalDepthShininess: [
  1013. "vec4 normalDepthMap = texture2D( samplerNormalDepthShininess, texCoord );",
  1014. "float depth = normalDepthMap.w;",
  1015. "if ( depth == 0.0 ) discard;",
  1016. "vec3 normal = vec2_to_normal( normalDepthMap.xy );",
  1017. "float shininess = normalDepthMap.z;"
  1018. ].join( "\n" ),
  1019. packColor: [
  1020. "vec4 packedColor;",
  1021. "packedColor.x = vec3_to_float( diffuseColor.rgb );",
  1022. "packedColor.y = vec3_to_float( emissiveColor );",
  1023. "packedColor.z = vec3_to_float( specularColor );",
  1024. "packedColor.w = shininess;"
  1025. ].join( "\n" ),
  1026. unpackColor: [
  1027. "vec4 colorMap = texture2D( samplerColor, texCoord );",
  1028. "vec3 diffuseColor = float_to_vec3( colorMap.x );",
  1029. "vec3 emissiveColor = float_to_vec3( colorMap.y );",
  1030. "vec3 specularColor = float_to_vec3( colorMap.z );",
  1031. "float shininess = colorMap.w;"
  1032. ].join( "\n" ),
  1033. packLight: [
  1034. "vec4 packedLight;",
  1035. "packedLight.xyz = lightIntensity * lightColor * max( dot( lightVector, normal ), 0.0 ) * attenuation;",
  1036. "packedLight.w = lightIntensity * specular * max( dot( lightVector, normal ), 0.0 ) * attenuation;"
  1037. ].join( "\n" ),
  1038. computeVertexPositionVS: [
  1039. "vec2 xy = texCoord * 2.0 - 1.0;",
  1040. "vec4 vertexPositionProjected = vec4( xy, depth, 1.0 );",
  1041. "vec4 vertexPositionVS = matProjInverse * vertexPositionProjected;",
  1042. "vertexPositionVS.xyz /= vertexPositionVS.w;",
  1043. "vertexPositionVS.w = 1.0;"
  1044. ].join( "\n" ),
  1045. // TODO: calculate schlick
  1046. computeSpecular: [
  1047. "vec3 halfVector = normalize( lightVector - normalize( vertexPositionVS.xyz ) );",
  1048. "float dotNormalHalf = max( dot( normal, halfVector ), 0.0 );",
  1049. "float specular = 0.31830988618 * ( shininess * 0.5 + 1.0 ) * pow( dotNormalHalf, shininess );"
  1050. ].join( "\n" ),
  1051. combine: [
  1052. "gl_FragColor = vec4( lightIntensity * lightColor * max( dot( lightVector, normal ), 0.0 ) * ( diffuseColor + specular * specularColor ) * attenuation, 1.0 );"
  1053. ].join( "\n" )
  1054. };
  1055. THREE.ShaderDeferredCommon = {
  1056. commonUniforms: {
  1057. matProjInverse: new THREE.Uniform( new THREE.Matrix4() ),
  1058. viewWidth: new THREE.Uniform( 800 ),
  1059. viewHeight: new THREE.Uniform( 600 )
  1060. }
  1061. };
  1062. THREE.ShaderDeferred = {
  1063. normalDepth: {
  1064. uniforms: {},
  1065. vertexShader: [
  1066. "varying vec3 vNormal;",
  1067. "varying vec4 vPosition;",
  1068. "#include <morphtarget_pars_vertex>",
  1069. "#include <skinning_pars_vertex>",
  1070. "void main() {",
  1071. "#include <begin_vertex>",
  1072. "#include <beginnormal_vertex>",
  1073. "#include <skinbase_vertex>",
  1074. "#include <skinnormal_vertex>",
  1075. "#include <defaultnormal_vertex>",
  1076. "#include <morphtarget_vertex>",
  1077. "#include <skinning_vertex>",
  1078. "#include <project_vertex>",
  1079. " vNormal = normalize( transformedNormal );",
  1080. " vPosition = gl_Position;",
  1081. "}"
  1082. ].join( "\n" ),
  1083. fragmentShader: [
  1084. "varying vec3 vNormal;",
  1085. "varying vec4 vPosition;",
  1086. "void main() {",
  1087. " vec3 normal = vNormal;",
  1088. " vec4 position = vPosition;",
  1089. THREE.DeferredShaderChunk[ "packNormalDepth" ],
  1090. " gl_FragColor = packedNormalDepth;",
  1091. "}"
  1092. ].join( "\n" )
  1093. },
  1094. color: {
  1095. uniforms: {
  1096. map: new THREE.Uniform( null ),
  1097. offsetRepeat: new THREE.Uniform( new THREE.Vector4( 0, 0, 1, 1 ) ),
  1098. diffuse: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
  1099. emissive: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
  1100. specular: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
  1101. shininess: new THREE.Uniform( 30.0 )
  1102. },
  1103. vertexShader: [
  1104. "#include <uv_pars_vertex>",
  1105. "#include <morphtarget_pars_vertex>",
  1106. "#include <skinning_pars_vertex>",
  1107. "void main() {",
  1108. "#include <uv_vertex>",
  1109. "#include <begin_vertex>",
  1110. "#include <beginnormal_vertex>",
  1111. "#include <skinbase_vertex>",
  1112. "#include <skinnormal_vertex>",
  1113. "#include <defaultnormal_vertex>",
  1114. "#include <morphtarget_vertex>",
  1115. "#include <skinning_vertex>",
  1116. "#include <project_vertex>",
  1117. "}"
  1118. ].join( "\n" ),
  1119. fragmentShader: [
  1120. "uniform vec3 diffuse;",
  1121. "uniform vec3 emissive;",
  1122. "uniform vec3 specular;",
  1123. "uniform float shininess;",
  1124. "#include <uv_pars_fragment>",
  1125. "#include <map_pars_fragment>",
  1126. THREE.DeferredShaderChunk[ "packVector3" ],
  1127. "void main() {",
  1128. " vec4 diffuseColor = vec4( diffuse, 1.0 );",
  1129. " vec3 emissiveColor = emissive;",
  1130. " vec3 specularColor = specular;",
  1131. "#include <map_fragment>",
  1132. THREE.DeferredShaderChunk[ "packColor" ],
  1133. " gl_FragColor = packedColor;",
  1134. "}"
  1135. ].join( "\n" )
  1136. },
  1137. emissiveLight: {
  1138. uniforms: Object.assign(
  1139. {
  1140. samplerColor: new THREE.Uniform( null )
  1141. },
  1142. THREE.ShaderDeferredCommon[ 'commonUniforms' ]
  1143. ),
  1144. vertexShader: [
  1145. "void main() { ",
  1146. " gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
  1147. "}"
  1148. ].join( '\n' ),
  1149. fragmentShader: [
  1150. "uniform sampler2D samplerColor;",
  1151. "uniform float viewHeight;",
  1152. "uniform float viewWidth;",
  1153. THREE.DeferredShaderChunk[ "unpackFloat" ],
  1154. "void main() {",
  1155. THREE.DeferredShaderChunk[ "computeTextureCoord" ],
  1156. THREE.DeferredShaderChunk[ "unpackColor" ],
  1157. " gl_FragColor = vec4( emissiveColor, 1.0 );",
  1158. "}"
  1159. ].join( '\n' )
  1160. },
  1161. pointLight: {
  1162. uniforms: Object.assign(
  1163. {
  1164. samplerNormalDepth: new THREE.Uniform( null ),
  1165. samplerColor: new THREE.Uniform( null ),
  1166. lightColor: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
  1167. lightPositionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ),
  1168. lightIntensity: new THREE.Uniform( 1.0 ),
  1169. lightRadius: new THREE.Uniform( 1.0 )
  1170. },
  1171. THREE.ShaderDeferredCommon[ 'commonUniforms' ]
  1172. ),
  1173. vertexShader: [
  1174. "void main() {",
  1175. " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
  1176. "}"
  1177. ].join( "\n" ),
  1178. fragmentShader: [
  1179. "uniform sampler2D samplerNormalDepth;",
  1180. "uniform sampler2D samplerColor;",
  1181. "uniform float viewHeight;",
  1182. "uniform float viewWidth;",
  1183. "uniform vec3 lightColor;",
  1184. "uniform vec3 lightPositionVS;",
  1185. "uniform float lightIntensity;",
  1186. "uniform float lightRadius;",
  1187. "uniform mat4 matProjInverse;",
  1188. THREE.DeferredShaderChunk[ "unpackFloat" ],
  1189. "void main() {",
  1190. THREE.DeferredShaderChunk[ "computeTextureCoord" ],
  1191. THREE.DeferredShaderChunk[ "unpackNormalDepth" ],
  1192. THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
  1193. " vec3 lightVector = lightPositionVS - vertexPositionVS.xyz;",
  1194. " float distance = length( lightVector );",
  1195. " if ( distance > lightRadius ) discard;",
  1196. " lightVector = normalize( lightVector );",
  1197. THREE.DeferredShaderChunk[ "unpackColor" ],
  1198. THREE.DeferredShaderChunk[ "computeSpecular" ],
  1199. " //float cutoff = 0.3;",
  1200. " //float denom = distance / lightRadius + 1.0;",
  1201. " //float attenuation = 1.0 / ( denom * denom );",
  1202. " //attenuation = ( attenuation - cutoff ) / ( 1.0 - cutoff );",
  1203. " //attenuation = max( attenuation, 0.0 );",
  1204. " //attenuation *= attenuation;",
  1205. " //diffuseColor *= saturate( -distance / lightRadius + 1.0 );",
  1206. " //float attenuation = 1.0;",
  1207. " float attenuation = saturate( -distance / lightRadius + 1.0 );",
  1208. THREE.DeferredShaderChunk[ "combine" ],
  1209. "}"
  1210. ].join( "\n" )
  1211. },
  1212. spotLight: {
  1213. uniforms: Object.assign(
  1214. {
  1215. samplerNormalDepth: new THREE.Uniform( null ),
  1216. samplerColor: new THREE.Uniform( null ),
  1217. lightColor: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
  1218. lightDirectionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ),
  1219. lightPositionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ),
  1220. lightAngle: new THREE.Uniform( 1.0 ),
  1221. lightIntensity: new THREE.Uniform( 1.0 )
  1222. },
  1223. THREE.ShaderDeferredCommon[ 'commonUniforms' ]
  1224. ),
  1225. vertexShader: [
  1226. "void main() { ",
  1227. " gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
  1228. "}"
  1229. ].join( "\n" ),
  1230. fragmentShader: [
  1231. "uniform sampler2D samplerNormalDepth;",
  1232. "uniform sampler2D samplerColor;",
  1233. "uniform float viewHeight;",
  1234. "uniform float viewWidth;",
  1235. "uniform vec3 lightColor;",
  1236. "uniform vec3 lightPositionVS;",
  1237. "uniform vec3 lightDirectionVS;",
  1238. "uniform float lightAngle;",
  1239. "uniform float lightIntensity;",
  1240. "uniform mat4 matProjInverse;",
  1241. THREE.DeferredShaderChunk[ "unpackFloat" ],
  1242. "void main() {",
  1243. THREE.DeferredShaderChunk[ "computeTextureCoord" ],
  1244. THREE.DeferredShaderChunk[ "unpackNormalDepth" ],
  1245. THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
  1246. THREE.DeferredShaderChunk[ "unpackColor" ],
  1247. " vec3 lightVector = normalize( lightPositionVS.xyz - vertexPositionVS.xyz );",
  1248. " float rho = dot( lightDirectionVS, lightVector );",
  1249. " float rhoMax = cos( lightAngle );",
  1250. " if ( rho <= rhoMax ) discard;",
  1251. " float theta = rhoMax + 0.0001;",
  1252. " float phi = rhoMax + 0.05;",
  1253. " float falloff = 4.0;",
  1254. " float spot = 0.0;",
  1255. " if ( rho >= phi ) {",
  1256. " spot = 1.0;",
  1257. " } else if ( rho <= theta ) {",
  1258. " spot = 0.0;",
  1259. " } else { ",
  1260. " spot = pow( ( rho - theta ) / ( phi - theta ), falloff );",
  1261. " }",
  1262. " diffuseColor *= spot;",
  1263. THREE.DeferredShaderChunk[ "computeSpecular" ],
  1264. " const float attenuation = 1.0;",
  1265. THREE.DeferredShaderChunk[ "combine" ],
  1266. "}"
  1267. ].join( "\n" )
  1268. },
  1269. directionalLight: {
  1270. uniforms: Object.assign(
  1271. {
  1272. samplerNormalDepth: new THREE.Uniform( null ),
  1273. samplerColor: new THREE.Uniform( null ),
  1274. lightColor: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
  1275. lightDirectionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ),
  1276. lightIntensity: new THREE.Uniform( 1.0 )
  1277. },
  1278. THREE.ShaderDeferredCommon[ 'commonUniforms' ]
  1279. ),
  1280. vertexShader: [
  1281. "void main() { ",
  1282. " gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
  1283. "}"
  1284. ].join( '\n' ),
  1285. fragmentShader: [
  1286. "uniform sampler2D samplerNormalDepth;",
  1287. "uniform sampler2D samplerColor;",
  1288. "uniform float viewHeight;",
  1289. "uniform float viewWidth;",
  1290. "uniform vec3 lightColor;",
  1291. "uniform vec3 lightDirectionVS;",
  1292. "uniform float lightIntensity;",
  1293. "uniform mat4 matProjInverse;",
  1294. THREE.DeferredShaderChunk[ "unpackFloat" ],
  1295. "void main() {",
  1296. THREE.DeferredShaderChunk[ "computeTextureCoord" ],
  1297. THREE.DeferredShaderChunk[ "unpackNormalDepth" ],
  1298. THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
  1299. THREE.DeferredShaderChunk[ "unpackColor" ],
  1300. " vec3 lightVector = normalize( lightDirectionVS );",
  1301. THREE.DeferredShaderChunk[ "computeSpecular" ],
  1302. " const float attenuation = 1.0;",
  1303. THREE.DeferredShaderChunk[ "combine" ],
  1304. "}"
  1305. ].join( '\n' )
  1306. },
  1307. normalDepthShininess: {
  1308. uniforms: {
  1309. shininess: new THREE.Uniform( 30.0 )
  1310. },
  1311. vertexShader: [
  1312. "varying vec3 vNormal;",
  1313. "varying vec4 vPosition;",
  1314. "#include <morphtarget_pars_vertex>",
  1315. "#include <skinning_pars_vertex>",
  1316. "void main() {",
  1317. "#include <begin_vertex>",
  1318. "#include <beginnormal_vertex>",
  1319. "#include <skinbase_vertex>",
  1320. "#include <skinnormal_vertex>",
  1321. "#include <defaultnormal_vertex>",
  1322. "#include <morphtarget_vertex>",
  1323. "#include <skinning_vertex>",
  1324. "#include <project_vertex>",
  1325. " vNormal = normalize( transformedNormal );",
  1326. " vPosition = gl_Position;",
  1327. "}"
  1328. ].join( "\n" ),
  1329. fragmentShader: [
  1330. "varying vec3 vNormal;",
  1331. "varying vec4 vPosition;",
  1332. "uniform float shininess;",
  1333. THREE.DeferredShaderChunk[ "packNormal" ],
  1334. "void main() {",
  1335. " vec3 normal = vNormal;",
  1336. " vec4 position = vPosition;",
  1337. THREE.DeferredShaderChunk[ "packNormalDepthShininess" ],
  1338. " gl_FragColor = packedNormalDepthShininess;",
  1339. "}"
  1340. ].join( "\n" )
  1341. },
  1342. pointLightPre: {
  1343. uniforms: Object.assign(
  1344. {
  1345. samplerNormalDepthShininess: new THREE.Uniform( null ),
  1346. lightColor: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
  1347. lightPositionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ),
  1348. lightIntensity: new THREE.Uniform( 1.0 ),
  1349. lightRadius: new THREE.Uniform( 1.0 )
  1350. },
  1351. THREE.ShaderDeferredCommon[ 'commonUniforms' ]
  1352. ),
  1353. vertexShader: [
  1354. "void main() {",
  1355. " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
  1356. "}"
  1357. ].join( "\n" ),
  1358. fragmentShader: [
  1359. "uniform sampler2D samplerNormalDepthShininess;",
  1360. "uniform float viewHeight;",
  1361. "uniform float viewWidth;",
  1362. "uniform vec3 lightColor;",
  1363. "uniform vec3 lightPositionVS;",
  1364. "uniform float lightIntensity;",
  1365. "uniform float lightRadius;",
  1366. "uniform mat4 matProjInverse;",
  1367. THREE.DeferredShaderChunk[ "unpackFloat" ],
  1368. THREE.DeferredShaderChunk[ "unpackVector2" ],
  1369. "void main() {",
  1370. THREE.DeferredShaderChunk[ "computeTextureCoord" ],
  1371. THREE.DeferredShaderChunk[ "unpackNormalDepthShininess" ],
  1372. THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
  1373. " vec3 lightVector = lightPositionVS - vertexPositionVS.xyz;",
  1374. " float distance = length( lightVector );",
  1375. " if ( distance > lightRadius ) discard;",
  1376. " lightVector = normalize( lightVector );",
  1377. THREE.DeferredShaderChunk[ "computeSpecular" ],
  1378. " float attenuation = saturate( -distance / lightRadius + 1.0 );",
  1379. THREE.DeferredShaderChunk[ "packLight" ],
  1380. " gl_FragColor = packedLight;",
  1381. "}"
  1382. ].join( "\n" )
  1383. },
  1384. spotLightPre: {
  1385. uniforms: Object.assign(
  1386. {
  1387. samplerNormalDepthShininess: new THREE.Uniform( null ),
  1388. lightColor: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
  1389. lightDirectionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ),
  1390. lightPositionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ),
  1391. lightAngle: new THREE.Uniform( 1.0 ),
  1392. lightIntensity: new THREE.Uniform( 1.0 )
  1393. },
  1394. THREE.ShaderDeferredCommon[ 'commonUniforms' ]
  1395. ),
  1396. vertexShader: [
  1397. "void main() { ",
  1398. " gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
  1399. "}"
  1400. ].join( "\n" ),
  1401. fragmentShader: [
  1402. "uniform sampler2D samplerNormalDepthShininess;",
  1403. "uniform float viewHeight;",
  1404. "uniform float viewWidth;",
  1405. "uniform vec3 lightColor;",
  1406. "uniform vec3 lightPositionVS;",
  1407. "uniform vec3 lightDirectionVS;",
  1408. "uniform float lightAngle;",
  1409. "uniform float lightIntensity;",
  1410. "uniform mat4 matProjInverse;",
  1411. THREE.DeferredShaderChunk[ "unpackFloat" ],
  1412. THREE.DeferredShaderChunk[ "unpackVector2" ],
  1413. "void main() {",
  1414. THREE.DeferredShaderChunk[ "computeTextureCoord" ],
  1415. THREE.DeferredShaderChunk[ "unpackNormalDepthShininess" ],
  1416. THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
  1417. " vec3 lightVector = normalize( lightPositionVS.xyz - vertexPositionVS.xyz );",
  1418. " float rho = dot( lightDirectionVS, lightVector );",
  1419. " float rhoMax = cos( lightAngle );",
  1420. " if ( rho <= rhoMax ) discard;",
  1421. " float theta = rhoMax + 0.0001;",
  1422. " float phi = rhoMax + 0.05;",
  1423. " float falloff = 4.0;",
  1424. " float spot = 0.0;",
  1425. " if ( rho >= phi ) {",
  1426. " spot = 1.0;",
  1427. " } else if ( rho <= theta ) {",
  1428. " spot = 0.0;",
  1429. " } else { ",
  1430. " spot = pow( ( rho - theta ) / ( phi - theta ), falloff );",
  1431. " }",
  1432. THREE.DeferredShaderChunk[ "computeSpecular" ],
  1433. " const float attenuation = 1.0;",
  1434. THREE.DeferredShaderChunk[ "packLight" ],
  1435. " gl_FragColor = spot * packedLight;",
  1436. "}"
  1437. ].join( "\n" )
  1438. },
  1439. directionalLightPre: {
  1440. uniforms: Object.assign(
  1441. {
  1442. samplerNormalDepthShininess: new THREE.Uniform( null ),
  1443. lightColor: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
  1444. lightDirectionVS: new THREE.Uniform( new THREE.Vector3( 0, 1, 0 ) ),
  1445. lightIntensity: new THREE.Uniform( 1.0 )
  1446. },
  1447. THREE.ShaderDeferredCommon[ 'commonUniforms' ]
  1448. ),
  1449. vertexShader: [
  1450. "void main() { ",
  1451. " gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
  1452. "}"
  1453. ].join( '\n' ),
  1454. fragmentShader: [
  1455. "uniform sampler2D samplerNormalDepthShininess;",
  1456. "uniform float viewHeight;",
  1457. "uniform float viewWidth;",
  1458. "uniform vec3 lightColor;",
  1459. "uniform vec3 lightDirectionVS;",
  1460. "uniform float lightIntensity;",
  1461. "uniform mat4 matProjInverse;",
  1462. THREE.DeferredShaderChunk[ "unpackFloat" ],
  1463. THREE.DeferredShaderChunk[ "unpackVector2" ],
  1464. "void main() {",
  1465. THREE.DeferredShaderChunk[ "computeTextureCoord" ],
  1466. THREE.DeferredShaderChunk[ "unpackNormalDepthShininess" ],
  1467. THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
  1468. " vec3 lightVector = normalize( lightDirectionVS );",
  1469. THREE.DeferredShaderChunk[ "computeSpecular" ],
  1470. " const float attenuation = 1.0;",
  1471. THREE.DeferredShaderChunk[ "packLight" ],
  1472. " gl_FragColor = packedLight;",
  1473. "}"
  1474. ].join( '\n' )
  1475. },
  1476. reconstruction: {
  1477. uniforms: Object.assign(
  1478. {
  1479. samplerLight: new THREE.Uniform( null ),
  1480. map: new THREE.Uniform( null ),
  1481. offsetRepeat: new THREE.Uniform( new THREE.Vector4( 0, 0, 1, 1 ) ),
  1482. diffuse: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
  1483. emissive: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
  1484. specular: new THREE.Uniform( new THREE.Color( 0x000000 ) ),
  1485. shininess: new THREE.Uniform( 30.0 )
  1486. },
  1487. THREE.ShaderDeferredCommon[ 'commonUniforms' ]
  1488. ),
  1489. vertexShader: [
  1490. "#include <uv_pars_vertex>",
  1491. "#include <morphtarget_pars_vertex>",
  1492. "#include <skinning_pars_vertex>",
  1493. "void main() {",
  1494. "#include <uv_vertex>",
  1495. "#include <begin_vertex>",
  1496. "#include <beginnormal_vertex>",
  1497. "#include <skinbase_vertex>",
  1498. "#include <skinnormal_vertex>",
  1499. "#include <defaultnormal_vertex>",
  1500. "#include <morphtarget_vertex>",
  1501. "#include <skinning_vertex>",
  1502. "#include <project_vertex>",
  1503. "}"
  1504. ].join( "\n" ),
  1505. fragmentShader: [
  1506. "uniform sampler2D samplerLight;",
  1507. "uniform vec3 diffuse;",
  1508. "uniform vec3 emissive;",
  1509. "uniform vec3 specular;",
  1510. "uniform float shininess;",
  1511. "uniform float viewHeight;",
  1512. "uniform float viewWidth;",
  1513. "#include <uv_pars_fragment>",
  1514. "#include <map_pars_fragment>",
  1515. THREE.DeferredShaderChunk[ "unpackFloat" ],
  1516. "void main() {",
  1517. " vec4 diffuseColor = vec4( diffuse, 1.0 );",
  1518. " vec3 emissiveColor = emissive;",
  1519. " vec3 specularColor = specular;",
  1520. THREE.DeferredShaderChunk[ "computeTextureCoord" ],
  1521. " vec4 light = texture2D( samplerLight, texCoord );",
  1522. "#include <map_fragment>",
  1523. " vec3 diffuseFinal = diffuseColor.rgb * light.rgb;",
  1524. " vec3 emissiveFinal = emissiveColor;",
  1525. " vec3 specularFinal = specularColor * light.rgb * light.a;",
  1526. " gl_FragColor = vec4( diffuseFinal + emissiveFinal + specularFinal, 1.0 );",
  1527. "}"
  1528. ].join( "\n" )
  1529. },
  1530. // TODO: implement tone mapping
  1531. final: {
  1532. uniforms: {
  1533. samplerResult: new THREE.Uniform( null )
  1534. },
  1535. vertexShader: [
  1536. "varying vec2 texCoord;",
  1537. "void main() {",
  1538. " vec4 pos = vec4( sign( position.xy ), 0.0, 1.0 );",
  1539. " texCoord = pos.xy * vec2( 0.5 ) + 0.5;",
  1540. " gl_Position = pos;",
  1541. "}"
  1542. ].join( "\n" ),
  1543. fragmentShader: [
  1544. "varying vec2 texCoord;",
  1545. "uniform sampler2D samplerResult;",
  1546. "void main() {",
  1547. " gl_FragColor = texture2D( samplerResult, texCoord );",
  1548. "}"
  1549. ].join( "\n" )
  1550. }
  1551. };