WebGLDeferredRenderer.js 53 KB

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