WebGLDeferredRenderer.js 54 KB

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