WebGLDeferredRenderer.js 55 KB

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