WebGLDeferredRenderer.js 56 KB

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