WebGLDeferredRenderer.js 55 KB

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