WebGLDeferredRenderer.js 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574
  1. /**
  2. * @author alteredq / http://alteredqualia.com/
  3. * @author MPanknin / http://www.redplant.de/
  4. * @author takahiro / https://github.com/takahirox
  5. *
  6. * Dependencies
  7. * - THREE.CopyShader
  8. * - THREE.RenderPass
  9. * - THREE.ShaderPass
  10. * - THREE.EffectComposer
  11. * - THREE.FXAAShader
  12. *
  13. * TODO
  14. * - reuse existing glsl
  15. * - shared material
  16. * - shadow
  17. * - optimization
  18. * - MRT (when it's available on Three.js)
  19. * - AmbientLight
  20. * - HemisphereLight
  21. * - PointLight (distance < 0)
  22. * - morphNormals
  23. * - BumpMap
  24. * - ToneMap
  25. * - envMap
  26. * - wrapAround
  27. * - addEffect
  28. */
  29. THREE.WebGLDeferredRenderer = function ( parameters ) {
  30. parameters = parameters || {};
  31. // private properties
  32. var _this = this;
  33. var _gl;
  34. var _width, _height;
  35. var _compColor, _compNormalDepth, _compLight, _compFinal;
  36. var _passColor, _passNormalDepth, _passLight, _passLightFullscreen, _passFinal, _passForward, _passCopy, _passFXAA;
  37. var _lightScene, _lightFullscreenScene;
  38. var _antialias = false, _hasTransparentObject = false;
  39. var _invisibleMaterial = new THREE.ShaderMaterial( { visible: false } );
  40. var _tmpVector3 = new THREE.Vector3();
  41. // external properties
  42. this.renderer;
  43. this.domElement;
  44. this.forwardRendering = false; // for debug
  45. // private methods
  46. var init = function ( parameters ) {
  47. _this.renderer = parameters.renderer !== undefined ? parameters.renderer : new THREE.WebGLRenderer( { antialias: false } );
  48. _this.domElement = _this.renderer.domElement;
  49. _gl = _this.renderer.context;
  50. _width = parameters.width !== undefined ? parameters.width : _this.renderer.getSize().width;
  51. _height = parameters.height !== undefined ? parameters.height : _this.renderer.getSize().height;
  52. var antialias = parameters.antialias !== undefined ? parameters.antialias : false;
  53. initPassFXAA();
  54. initPassNormalDepth();
  55. initPassColor();
  56. initPassLight();
  57. initPassFinal();
  58. _this.setSize( _width, _height );
  59. _this.setAntialias( antialias );
  60. };
  61. var initPassFXAA = function () {
  62. _passFXAA = new THREE.ShaderPass( THREE.FXAAShader );
  63. };
  64. var initPassNormalDepth = function () {
  65. _passNormalDepth = new THREE.RenderPass();
  66. _passNormalDepth.clear = true;
  67. var rt = new THREE.WebGLRenderTarget( _width, _height, {
  68. minFilter: THREE.NearestFilter,
  69. magFilter: THREE.NearestFilter,
  70. format: THREE.RGBAFormat,
  71. type: THREE.FloatType,
  72. stencilBuffer: true,
  73. depthTexture: new THREE.DepthTexture(
  74. _width,
  75. _height,
  76. THREE.UnsignedInt248Type,
  77. undefined,
  78. undefined,
  79. undefined,
  80. undefined,
  81. undefined,
  82. undefined,
  83. THREE.DepthStencilFormat
  84. )
  85. } );
  86. rt.texture.generateMipamps = false;
  87. _compNormalDepth = new THREE.EffectComposer( _this.renderer, rt );
  88. _compNormalDepth.addPass( _passNormalDepth );
  89. };
  90. var initPassColor = function () {
  91. _passColor = new THREE.RenderPass();
  92. _passColor.clear = true;
  93. var rt = new THREE.WebGLRenderTarget( _width, _height, {
  94. minFilter: THREE.NearestFilter,
  95. magFilter: THREE.NearestFilter,
  96. format: THREE.RGBAFormat,
  97. type: THREE.FloatType,
  98. depthTexture: _compNormalDepth.renderTarget2.depthTexture
  99. } );
  100. rt.texture.generateMipamps = false;
  101. _compColor = new THREE.EffectComposer( _this.renderer, rt );
  102. _compColor.addPass( _passColor );
  103. };
  104. var initPassLight = function () {
  105. _passLightFullscreen = new THREE.RenderPass();
  106. _passLightFullscreen.clear = true;
  107. _passLightFullscreen.camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 0, 1 );
  108. _passLight = new THREE.RenderPass();
  109. _passLight.clear = false;
  110. var rt = new THREE.WebGLRenderTarget( _width, _height, {
  111. minFilter: THREE.NearestFilter,
  112. magFilter: THREE.NearestFilter,
  113. format: THREE.RGBAFormat,
  114. type: THREE.FloatType,
  115. depthTexture: _compNormalDepth.renderTarget2.depthTexture
  116. } );
  117. rt.texture.generateMipamps = false;
  118. _compLight = new THREE.EffectComposer( _this.renderer, rt );
  119. _compLight.addPass( _passLightFullscreen );
  120. _compLight.addPass( _passLight );
  121. };
  122. var initPassFinal = function () {
  123. _passFinal = new THREE.ShaderPass( THREE.ShaderDeferred[ 'composite' ] );
  124. _passFinal.clear = true;
  125. _passFinal.uniforms.samplerLight.value = _compLight.renderTarget2.texture;
  126. _passFinal.material.blending = THREE.NoBlending;
  127. _passFinal.material.depthWrite = false;
  128. _passFinal.material.depthTest = false;
  129. _passForward = new THREE.RenderPass();
  130. _passForward.clear = false;
  131. _passCopy = new THREE.ShaderPass( THREE.CopyShader );
  132. var rt = new THREE.WebGLRenderTarget( _width, _height, {
  133. minFilter: THREE.NearestFilter,
  134. magFilter: THREE.LinearFilter,
  135. format: THREE.RGBFormat,
  136. type: THREE.UnsignedByteType,
  137. depthTexture: _compNormalDepth.renderTarget2.depthTexture
  138. } );
  139. rt.texture.generateMipamps = false;
  140. _compFinal = new THREE.EffectComposer( _this.renderer, rt );
  141. _compFinal.addPass( _passFinal );
  142. _compFinal.addPass( _passForward );
  143. _compFinal.addPass( _passCopy );
  144. _compFinal.addPass( _passFXAA );
  145. };
  146. var initLightScene = function ( scene ) {
  147. if ( scene.userData.lightScene === undefined ) {
  148. var lightScene = new THREE.Scene();
  149. lightScene.userData.lights = {};
  150. scene.userData.lightScene = lightScene;
  151. }
  152. if ( scene.userData.lightFullscreenScene === undefined ) {
  153. var lightScene = new THREE.Scene();
  154. lightScene.userData.lights = {};
  155. lightScene.userData.emissiveLight = createDeferredEmissiveLight();
  156. lightScene.add( lightScene.userData.emissiveLight );
  157. scene.userData.lightFullscreenScene = lightScene;
  158. }
  159. _lightScene = scene.userData.lightScene;
  160. _lightFullscreenScene = scene.userData.lightFullscreenScene;
  161. };
  162. var initDeferredProperties = function ( object ) {
  163. if ( object.userData.deferredInitialized === true ) return;
  164. if ( object.material ) initDeferredMaterials( object );
  165. if ( object instanceof THREE.Light ) initDeferredLight( object );
  166. object.userData.deferredInitialized = true;
  167. };
  168. var initDeferredMaterials = function ( object ) {
  169. if ( object.material instanceof THREE.MultiMaterial ) {
  170. var normalDepthMaterials = [];
  171. var colorMaterials = [];
  172. var forwardMaterials = [];
  173. var materials = object.material.materials;
  174. for ( var i = 0, il = materials.length; i < il; i ++ ) {
  175. normalDepthMaterials.push( createDeferredNormalDepthMaterial( materials[ i ] ) );
  176. colorMaterials.push( createDeferredColorMaterial( materials[ i ] ) );
  177. forwardMaterials.push( _invisibleMaterial );
  178. }
  179. object.userData.normalDepthMaterial = new THREE.MultiMaterial( normalDepthMaterials );
  180. object.userData.colorMaterial = new THREE.MultiMaterial( colorMaterials );
  181. object.userData.forwardMaterial = new THREE.MultiMaterial( forwardMaterials );
  182. } else {
  183. object.userData.normalDepthMaterial = createDeferredNormalDepthMaterial( object.material );
  184. object.userData.colorMaterial = createDeferredColorMaterial( object.material );
  185. }
  186. };
  187. var createDeferredNormalDepthMaterial = function ( originalMaterial ) {
  188. var shader = THREE.ShaderDeferred[ 'normalDepth' ];
  189. var material = new THREE.ShaderMaterial( {
  190. uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
  191. fragmentShader: shader.fragmentShader,
  192. vertexShader: shader.vertexShader,
  193. blending: THREE.NoBlending
  194. } );
  195. return material;
  196. };
  197. var updateDeferredNormalDepthMaterial = function ( material, originalMaterial ) {
  198. if ( originalMaterial.skinning !== undefined ) material.skinning = originalMaterial.skinning;
  199. if ( originalMaterial.morphTargets !== undefined ) material.morphTargets = originalMaterial.morphTargets;
  200. if ( originalMaterial.visible === true ) {
  201. material.visible = ! originalMaterial.transparent;
  202. } else {
  203. material.visible = false;
  204. }
  205. };
  206. var createDeferredColorMaterial = function ( originalMaterial ) {
  207. var shader = THREE.ShaderDeferred[ 'color' ];
  208. var material = new THREE.ShaderMaterial( {
  209. uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
  210. fragmentShader: shader.fragmentShader,
  211. vertexShader: shader.vertexShader,
  212. blending: THREE.NoBlending
  213. } );
  214. if ( originalMaterial.map !== undefined ) material.map = originalMaterial.map;
  215. return material;
  216. };
  217. var updateDeferredColorMaterial = function ( material, originalMaterial ) {
  218. var diffuse, emissive;
  219. if ( originalMaterial instanceof THREE.MeshBasicMaterial ) {
  220. emissive = originalMaterial.color;
  221. } else {
  222. diffuse = originalMaterial.color;
  223. emissive = originalMaterial.emissive;
  224. }
  225. var specular = originalMaterial.specular;
  226. var shininess = originalMaterial.shininess;
  227. var map = originalMaterial.map;
  228. if ( ( originalMaterial instanceof THREE.ShaderMaterial ) && originalMaterial.uniforms !== undefined ) {
  229. if ( diffuse === undefined && originalMaterial.uniforms.diffuse !== undefined ) diffuse = originalMaterial.uniforms.diffuse.value;
  230. if ( emissive === undefined && originalMaterial.uniforms.emissive !== undefined ) emissive = originalMaterial.uniforms.emissive.value;
  231. if ( specular === undefined && originalMaterial.uniforms.specular !== undefined ) specular = originalMaterial.uniforms.specular.value;
  232. if ( shininess === undefined && originalMaterial.uniforms.shininess !== undefined ) shininess = originalMaterial.uniforms.shininess.value;
  233. }
  234. if ( diffuse !== undefined ) material.uniforms.diffuse.value.copy( diffuse );
  235. if ( emissive !== undefined ) material.uniforms.emissive.value.copy( emissive );
  236. if ( specular !== undefined ) material.uniforms.specular.value.copy( specular );
  237. if ( shininess !== undefined ) material.uniforms.shininess.value = shininess;
  238. if ( map !== undefined ) {
  239. material.map = map;
  240. material.uniforms.map.value = map;
  241. }
  242. if ( originalMaterial.skinning !== undefined ) material.skinning = originalMaterial.skinning;
  243. if ( originalMaterial.morphTargets !== undefined ) material.morphTargets = originalMaterial.morphTargets;
  244. if ( originalMaterial.visible === true ) {
  245. material.visible = ! originalMaterial.transparent;
  246. } else {
  247. material.visible = false;
  248. }
  249. };
  250. var getForwardRenderingMaterial = function ( originalMaterial ) {
  251. if ( originalMaterial.transparent === true && originalMaterial.visible === true ) {
  252. return originalMaterial
  253. } else {
  254. return _invisibleMaterial;
  255. }
  256. };
  257. var initDeferredLight = function ( light ) {
  258. var deferredLight;
  259. if ( light instanceof THREE.PointLight ) {
  260. deferredLight = createDeferredPointLight( light );
  261. } else if ( light instanceof THREE.SpotLight ) {
  262. deferredLight = createDeferredSpotLight( light );
  263. } else if ( light instanceof THREE.DirectionalLight ) {
  264. deferredLight = createDeferredDirectionalLight( light );
  265. }
  266. light.userData.deferredLight = deferredLight;
  267. };
  268. var updateDeferredLight = function ( light, camera ) {
  269. var originalLight = light.userData.originalLight;
  270. if ( originalLight instanceof THREE.PointLight ) {
  271. updateDeferredPointLight( light, camera );
  272. } else if ( originalLight instanceof THREE.SpotLight ) {
  273. updateDeferredSpotLight( light, camera );
  274. } else if ( originalLight instanceof THREE.DirectionalLight ) {
  275. updateDeferredDirectionalLight( light, camera );
  276. }
  277. };
  278. var createDeferredEmissiveLight = function () {
  279. var shader = THREE.ShaderDeferred[ 'emissiveLight' ];
  280. var material = new THREE.ShaderMaterial( {
  281. uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
  282. vertexShader: shader.vertexShader,
  283. fragmentShader: shader.fragmentShader,
  284. blending: THREE.NoBlending,
  285. depthWrite: false
  286. } );
  287. material.uniforms.samplerColor.value = _compColor.renderTarget2.texture;
  288. var geometry = new THREE.PlaneBufferGeometry( 2, 2 );
  289. var mesh = new THREE.Mesh( geometry, material );
  290. return mesh;
  291. };
  292. var updateDeferredEmissiveLight = function ( light, camera ) {
  293. var uniforms = light.material.uniforms;
  294. uniforms.viewWidth.value = _width;
  295. uniforms.viewHeight.value = _height;
  296. };
  297. var createDeferredPointLight = function ( light ) {
  298. var shader = THREE.ShaderDeferred[ 'pointLight' ];
  299. var material = new THREE.ShaderMaterial( {
  300. uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
  301. vertexShader: shader.vertexShader,
  302. fragmentShader: shader.fragmentShader,
  303. transparent: true,
  304. side: THREE.BackSide,
  305. blending: THREE.AdditiveBlending,
  306. depthWrite: false,
  307. depthFunc: THREE.GreaterEqualDepth
  308. } );
  309. material.uniforms.samplerNormalDepth.value = _compNormalDepth.renderTarget2.texture;
  310. material.uniforms.samplerColor.value = _compColor.renderTarget2.texture;
  311. var geometry = new THREE.SphereGeometry( 1, 16, 8 );
  312. var mesh = new THREE.Mesh( geometry, material );
  313. mesh.userData.originalLight = light;
  314. return mesh;
  315. };
  316. var updateDeferredPointLight = function ( light, camera ) {
  317. var originalLight = light.userData.originalLight;
  318. var distance = originalLight.distance;
  319. var uniforms = light.material.uniforms;
  320. uniforms.matProjInverse.value.getInverse( camera.projectionMatrix );
  321. uniforms.viewWidth.value = _width;
  322. uniforms.viewHeight.value = _height;
  323. uniforms.lightColor.value.copy( originalLight.color );
  324. if ( distance > 0 ) {
  325. light.scale.set( 1, 1, 1 ).multiplyScalar( distance );
  326. uniforms.lightRadius.value = distance;
  327. uniforms.lightIntensity.value = originalLight.intensity;
  328. uniforms.lightPositionVS.value.setFromMatrixPosition( originalLight.matrixWorld ).applyMatrix4( camera.matrixWorldInverse );
  329. light.position.setFromMatrixPosition( originalLight.matrixWorld );
  330. } else {
  331. uniforms.lightRadius.value = Infinity;
  332. }
  333. };
  334. var createDeferredSpotLight = function ( light ) {
  335. var shader = THREE.ShaderDeferred[ 'spotLight' ];
  336. var material = new THREE.ShaderMaterial( {
  337. uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
  338. vertexShader: shader.vertexShader,
  339. fragmentShader: shader.fragmentShader,
  340. transparent: true,
  341. blending: THREE.AdditiveBlending,
  342. depthWrite: false,
  343. depthTest: false
  344. } );
  345. material.uniforms.samplerNormalDepth.value = _compNormalDepth.renderTarget2.texture;
  346. material.uniforms.samplerColor.value = _compColor.renderTarget2.texture;
  347. var geometry = new THREE.PlaneBufferGeometry( 2, 2 );
  348. var mesh = new THREE.Mesh( geometry, material );
  349. mesh.userData.originalLight = light;
  350. return mesh;
  351. };
  352. var updateDeferredSpotLight = function ( light, camera ) {
  353. var originalLight = light.userData.originalLight;
  354. var uniforms = light.material.uniforms;
  355. uniforms.matProjInverse.value.getInverse( camera.projectionMatrix );
  356. uniforms.viewWidth.value = _width;
  357. uniforms.viewHeight.value = _height;
  358. uniforms.lightAngle.value = originalLight.angle;
  359. uniforms.lightColor.value.copy( originalLight.color );
  360. uniforms.lightIntensity.value = originalLight.intensity;
  361. uniforms.lightPositionVS.value.setFromMatrixPosition( originalLight.matrixWorld ).applyMatrix4( camera.matrixWorldInverse );
  362. var vec = uniforms.lightDirectionVS.value;
  363. var vec2 = _tmpVector3;
  364. vec.setFromMatrixPosition( originalLight.matrixWorld );
  365. vec2.setFromMatrixPosition( originalLight.target.matrixWorld );
  366. vec.sub( vec2 ).normalize().transformDirection( camera.matrixWorldInverse );
  367. };
  368. var createDeferredDirectionalLight = function ( light ) {
  369. var shader = THREE.ShaderDeferred[ 'directionalLight' ];
  370. var material = new THREE.ShaderMaterial( {
  371. uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
  372. vertexShader: shader.vertexShader,
  373. fragmentShader: shader.fragmentShader,
  374. transparent: true,
  375. blending: THREE.AdditiveBlending,
  376. depthWrite: false,
  377. depthTest: false
  378. } );
  379. material.uniforms.samplerNormalDepth.value = _compNormalDepth.renderTarget2.texture;
  380. material.uniforms.samplerColor.value = _compColor.renderTarget2.texture;
  381. var geometry = new THREE.PlaneBufferGeometry( 2, 2 );
  382. var mesh = new THREE.Mesh( geometry, material );
  383. mesh.userData.originalLight = light;
  384. return mesh;
  385. };
  386. var updateDeferredDirectionalLight = function ( light, camera ) {
  387. var originalLight = light.userData.originalLight;
  388. var uniforms = light.material.uniforms;
  389. uniforms.matProjInverse.value.getInverse( camera.projectionMatrix );
  390. uniforms.viewWidth.value = _width;
  391. uniforms.viewHeight.value = _height;
  392. uniforms.lightColor.value.copy( originalLight.color );
  393. uniforms.lightIntensity.value = originalLight.intensity;
  394. var vec = uniforms.lightDirectionVS.value;
  395. var vec2 = _tmpVector3;
  396. vec.setFromMatrixPosition( originalLight.matrixWorld );
  397. vec2.setFromMatrixPosition( originalLight.target.matrixWorld );
  398. vec.sub( vec2 ).normalize().transformDirection( camera.matrixWorldInverse );
  399. };
  400. var setMaterialNormalDepth = function ( object ) {
  401. if ( object.material === undefined ) return;
  402. if ( object.userData.normalDepthMaterial !== undefined ) {
  403. object.material = object.userData.normalDepthMaterial;
  404. if ( object.userData.originalMaterial instanceof THREE.MultiMaterial ) {
  405. for ( var i = 0, il = object.userData.originalMaterial.materials.length; i < il; i ++ ) {
  406. updateDeferredNormalDepthMaterial( object.material.materials[ i ], object.userData.originalMaterial.materials[ i ] );
  407. }
  408. } else {
  409. updateDeferredNormalDepthMaterial( object.material, object.userData.originalMaterial );
  410. }
  411. }
  412. };
  413. var setMaterialColor = function ( object ) {
  414. if ( object.material === undefined ) return;
  415. if ( object.userData.colorMaterial !== undefined ) {
  416. object.material = object.userData.colorMaterial;
  417. if ( object.userData.originalMaterial instanceof THREE.MultiMaterial ) {
  418. for ( var i = 0, il = object.userData.originalMaterial.materials.length; i < il; i ++ ) {
  419. updateDeferredColorMaterial( object.material.materials[ i ], object.userData.originalMaterial.materials[ i ] );
  420. }
  421. } else {
  422. updateDeferredColorMaterial( object.material, object.userData.originalMaterial );
  423. }
  424. }
  425. };
  426. var setMaterialForwardRendering = function ( object ) {
  427. if ( object.material === undefined ) return;
  428. if ( object.userData.originalMaterial instanceof THREE.MultiMaterial ) {
  429. object.material = object.userData.forwardMaterial;
  430. for ( var i = 0, il = object.userData.originalMaterial.materials.length; i < il; i ++ ) {
  431. object.material.materials[ i ] = getForwardRenderingMaterial( object.userData.originalMaterial.materials[ i ] );
  432. }
  433. } else {
  434. object.material = getForwardRenderingMaterial( object.userData.originalMaterial );
  435. }
  436. };
  437. var saveOriginalMaterialAndCheckTransparency = function ( object ) {
  438. if ( object.material !== undefined ) {
  439. object.userData.originalMaterial = object.material;
  440. if ( object.material instanceof THREE.MultiMaterial ) {
  441. for ( var i = 0, il = object.material.materials.length; i < il; i ++ ) {
  442. if ( object.material.materials[ i ].transparent === true ) _hasTransparentObject = true;
  443. }
  444. } else {
  445. if ( object.material.transparent === true ) _hasTransparentObject = true;
  446. }
  447. }
  448. };
  449. var restoreOriginalMaterial = function ( object ) {
  450. if ( object.userData.originalMaterial !== undefined ) object.material = object.userData.originalMaterial;
  451. };
  452. var enableCompositePasses = function () {
  453. if ( _hasTransparentObject ) {
  454. if ( _antialias ) {
  455. _passFinal.renderToScreen = false;
  456. _passForward.renderToScreen = false;
  457. _passForward.enabled = true;
  458. _passCopy.renderToScreen = false;
  459. _passCopy.enabled = false;
  460. _passFXAA.renderToScreen = true;
  461. _passFXAA.enabled = true;
  462. } else {
  463. _passFinal.renderToScreen = false;
  464. _passForward.renderToScreen = false;
  465. _passForward.enabled = true;
  466. _passCopy.renderToScreen = true;
  467. _passCopy.enabled = true;
  468. _passFXAA.renderToScreen = false;
  469. _passFXAA.enabled = false;
  470. }
  471. } else {
  472. if ( _antialias ) {
  473. _passFinal.renderToScreen = false;
  474. _passForward.renderToScreen = false;
  475. _passForward.enabled = false;
  476. _passCopy.renderToScreen = false;
  477. _passCopy.enabled = false;
  478. _passFXAA.renderToScreen = true;
  479. _passFXAA.enabled = true;
  480. } else {
  481. _passFinal.renderToScreen = true;
  482. _passForward.renderToScreen = false;
  483. _passForward.enabled = false;
  484. _passCopy.renderToScreen = false;
  485. _passCopy.enabled = false;
  486. _passFXAA.renderToScreen = false;
  487. _passFXAA.enabled = false;
  488. }
  489. }
  490. };
  491. var addDeferredLightsToLightScene = function ( object ) {
  492. var light = object.userData.deferredLight;
  493. if ( light !== undefined ) {
  494. var originalLight = light.userData.originalLight;
  495. var scene;
  496. if ( originalLight instanceof THREE.PointLight ) {
  497. scene = _lightScene;
  498. } else {
  499. scene = _lightFullscreenScene;
  500. }
  501. var lights = scene.userData.lights;
  502. if ( lights[ light.uuid ] === undefined ) {
  503. scene.add( light );
  504. lights[ light.uuid ] = {
  505. light: light,
  506. found: true
  507. };
  508. }
  509. lights[ light.uuid ].found = true;
  510. }
  511. };
  512. var updateDeferredLightsInLightScene = function ( scene, camera ) {
  513. var lights = scene.userData.lights;
  514. var keys = Object.keys( lights );
  515. for ( var i = 0, il = keys.length; i < il; i ++ ) {
  516. var key = keys[ i ];
  517. if ( lights[ key ].found === false ) {
  518. scene.remove( lights[ key ].light );
  519. delete lights[ key ];
  520. } else {
  521. updateDeferredLight( lights[ key ].light, camera );
  522. lights[ key ].found = false;
  523. }
  524. }
  525. };
  526. /*
  527. * 1) g-buffer normal + depth pass
  528. *
  529. * RGB: normal
  530. * A: depth
  531. */
  532. var renderNormalDepth = function ( scene, camera ) {
  533. scene.traverse( setMaterialNormalDepth );
  534. _passNormalDepth.scene = scene;
  535. _passNormalDepth.camera = camera;
  536. _this.renderer.autoClearDepth = true;
  537. _this.renderer.autoClearStencil = true;
  538. _gl.enable( _gl.STENCIL_TEST );
  539. _gl.stencilFunc( _gl.ALWAYS, 1, 0xffffffff );
  540. _gl.stencilOp( _gl.REPLACE, _gl.REPLACE, _gl.REPLACE );
  541. _compNormalDepth.render();
  542. };
  543. /*
  544. * 2) g-buffer color pass
  545. *
  546. * R: diffuse
  547. * G: emissive
  548. * B: specular
  549. * A: shininess
  550. */
  551. var renderColor = function ( scene, camera ) {
  552. scene.traverse( setMaterialColor );
  553. _passColor.scene = scene;
  554. _passColor.camera = camera;
  555. _this.renderer.autoClearDepth = false;
  556. _this.renderer.autoClearStencil = false;
  557. _gl.stencilFunc( _gl.EQUAL, 1, 0xffffffff );
  558. _gl.stencilOp( _gl.KEEP, _gl.KEEP, _gl.KEEP );
  559. _compColor.render();
  560. };
  561. /*
  562. * 3) light pass
  563. *
  564. * optimization:
  565. * Here renders PointLight only back face with stencil test.
  566. */
  567. var renderLight = function ( scene, camera ) {
  568. updateDeferredEmissiveLight( _lightFullscreenScene.userData.emissiveLight, camera );
  569. scene.traverse( addDeferredLightsToLightScene );
  570. updateDeferredLightsInLightScene( _lightScene, camera );
  571. updateDeferredLightsInLightScene( _lightFullscreenScene, camera );
  572. _passLight.scene = _lightScene;
  573. _passLight.camera = camera;
  574. _passLightFullscreen.scene = _lightFullscreenScene;
  575. _this.renderer.autoClearDepth = false;
  576. _this.renderer.autoClearStencil = false;
  577. _compLight.render();
  578. _gl.disable( _gl.STENCIL_TEST );
  579. };
  580. /*
  581. * 4) composite pass
  582. *
  583. * transparency handling:
  584. * If there's any transparent objects, here renders them on the deferred rendering result
  585. * with forward rendering. This may be the easist way but heavy.
  586. * We should consider any better ways someday.
  587. *
  588. * antialias handling:
  589. * Here uses postprocessing FXAA for antialias.
  590. */
  591. var renderComposite = function ( scene, camera ) {
  592. if ( _hasTransparentObject ) {
  593. scene.traverse( setMaterialForwardRendering );
  594. _passForward.scene = scene;
  595. _passForward.camera = camera;
  596. }
  597. enableCompositePasses();
  598. _this.renderer.autoClearDepth = false;
  599. _this.renderer.autoClearStencil = false;
  600. _compFinal.render();
  601. };
  602. // external APIs
  603. this.setSize = function ( width, height ) {
  604. _width = width;
  605. _height = height;
  606. this.renderer.setSize( _width, _height );
  607. _compNormalDepth.setSize( _width, _height );
  608. _compColor.setSize( _width, _height );
  609. _compLight.setSize( _width, _height );
  610. _compFinal.setSize( _width, _height );
  611. _compNormalDepth.renderTarget2.depthTexture.image.width = _width;
  612. _compNormalDepth.renderTarget2.depthTexture.image.height = _height;
  613. _compNormalDepth.renderTarget2.depthTexture.needsUpdate = true;
  614. _passFXAA.uniforms.resolution.value.set( 1 / _width, 1 / _height );
  615. };
  616. this.setAntialias = function ( enabled ) {
  617. _antialias = enabled;
  618. };
  619. this.render = function ( scene, camera ) {
  620. // for debug to compare with normal forward rendering
  621. if ( this.forwardRendering ) {
  622. this.renderer.render( scene, camera );
  623. return;
  624. }
  625. var tmpSceneAutoUpdate = scene.autoUpdate;
  626. var tmpAutoClearColor = this.renderer.autoClearColor;
  627. var tmpAutoClearDepth = this.renderer.autoClearDepth;
  628. var tmpAutoClearStencil = this.renderer.autoClearStencil;
  629. initLightScene( scene );
  630. scene.autoUpdate = false;
  631. scene.updateMatrixWorld();
  632. _hasTransparentObject = false;
  633. scene.traverse( initDeferredProperties );
  634. scene.traverse( saveOriginalMaterialAndCheckTransparency );
  635. renderNormalDepth( scene, camera );
  636. renderColor( scene, camera );
  637. renderLight( scene, camera );
  638. renderComposite( scene, camera );
  639. scene.traverse( restoreOriginalMaterial );
  640. scene.autoUpdate = tmpSceneAutoUpdate;
  641. this.renderer.autoClearColor = tmpAutoClearColor;
  642. this.renderer.autoClearDepth = tmpAutoClearDepth;
  643. this.renderer.autoClearStencil = tmpAutoClearStencil;
  644. };
  645. // initialize
  646. init( parameters );
  647. };
  648. THREE.DeferredShaderChunk = {
  649. packVector3: [
  650. "float vec3_to_float( vec3 data ) {",
  651. "const float unit = 255.0/256.0;",
  652. "highp float compressed = fract( data.x * unit ) + floor( data.y * unit * 255.0 ) + floor( data.z * unit * 255.0 ) * 255.0;",
  653. "return compressed;",
  654. "}"
  655. ].join( "\n" ),
  656. unpackFloat: [
  657. "vec3 float_to_vec3( float data ) {",
  658. "const float unit = 255.0;",
  659. "vec3 uncompressed;",
  660. "uncompressed.x = fract( data );",
  661. "float zInt = floor( data / unit );",
  662. "uncompressed.z = fract( zInt / unit );",
  663. "uncompressed.y = fract( floor( data - ( zInt * unit ) ) / unit );",
  664. "return uncompressed;",
  665. "}"
  666. ].join( "\n" ),
  667. computeTextureCoord: [
  668. "vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );"
  669. ].join( "\n" ),
  670. packNormalDepth: [
  671. "vec4 packedNormalDepth;",
  672. "packedNormalDepth.xyz = normal * 0.5 + 0.5;",
  673. "packedNormalDepth.w = position.z / position.w;",
  674. ].join( "\n" ),
  675. unpackNormalDepth: [
  676. "vec4 normalDepthMap = texture2D( samplerNormalDepth, texCoord );",
  677. "float depth = normalDepthMap.w;",
  678. "if ( depth == 0.0 ) discard;",
  679. "vec3 normal = normalDepthMap.xyz * 2.0 - 1.0;"
  680. ].join( "\n" ),
  681. packColor: [
  682. "vec4 packedColor;",
  683. "packedColor.x = vec3_to_float( diffuseColor );",
  684. "packedColor.y = vec3_to_float( emissiveColor );",
  685. "packedColor.z = vec3_to_float( specularColor );",
  686. "packedColor.w = shininess;"
  687. ].join( "\n" ),
  688. unpackColor: [
  689. "vec4 colorMap = texture2D( samplerColor, texCoord );",
  690. "vec3 diffuseColor = float_to_vec3( colorMap.x );",
  691. "vec3 emissiveColor = float_to_vec3( colorMap.y );",
  692. "vec3 specularColor = float_to_vec3( colorMap.z );",
  693. "float shininess = colorMap.w;",
  694. ].join( "\n" ),
  695. computeVertexPositionVS: [
  696. "vec2 xy = texCoord * 2.0 - 1.0;",
  697. "vec4 vertexPositionProjected = vec4( xy, depth, 1.0 );",
  698. "vec4 vertexPositionVS = matProjInverse * vertexPositionProjected;",
  699. "vertexPositionVS.xyz /= vertexPositionVS.w;",
  700. "vertexPositionVS.w = 1.0;"
  701. ].join( "\n" ),
  702. computeSpecular: [
  703. "vec3 halfVector = normalize( lightVector - normalize( vertexPositionVS.xyz ) );",
  704. "float dotNormalHalf = max( dot( normal, halfVector ), 0.0 );",
  705. "float specularNormalization = ( shininess + 2.0001 ) / 8.0;",
  706. "vec3 schlick = specularColor + vec3( 1.0 - specularColor ) * pow( 1.0 - dot( lightVector, halfVector ), 5.0 );",
  707. "vec3 specular = schlick * max( pow( dotNormalHalf, shininess ), 0.0 ) * diffuseColor * max( dot( normal, lightVector ), 0.0 ) * specularNormalization;"
  708. ].join( "\n" ),
  709. combine: [
  710. "gl_FragColor = vec4( lightIntensity * lightColor * ( diffuseColor * max( dot( normal, lightVector ), 0.0 ) + specular ), attenuation );"
  711. ].join( "\n" )
  712. };
  713. THREE.ShaderDeferred = {
  714. normalDepth: {
  715. uniforms: {},
  716. vertexShader: [
  717. "varying vec3 vNormal;",
  718. "varying vec4 vPosition;",
  719. THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
  720. THREE.ShaderChunk[ "skinning_pars_vertex" ],
  721. "void main() {",
  722. THREE.ShaderChunk[ "begin_vertex" ],
  723. THREE.ShaderChunk[ "beginnormal_vertex" ],
  724. THREE.ShaderChunk[ "skinbase_vertex" ],
  725. THREE.ShaderChunk[ "skinnormal_vertex" ],
  726. THREE.ShaderChunk[ "defaultnormal_vertex" ],
  727. THREE.ShaderChunk[ "morphtarget_vertex" ],
  728. THREE.ShaderChunk[ "skinning_vertex" ],
  729. THREE.ShaderChunk[ "project_vertex" ],
  730. "vNormal = normalize( normalMatrix * objectNormal );",
  731. "vPosition = gl_Position;",
  732. "}"
  733. ].join( "\n" ),
  734. fragmentShader: [
  735. "varying vec3 vNormal;",
  736. "varying vec4 vPosition;",
  737. "void main() {",
  738. "vec3 normal = vNormal;",
  739. "vec4 position = vPosition;",
  740. THREE.DeferredShaderChunk[ "packNormalDepth" ],
  741. "gl_FragColor = packedNormalDepth;",
  742. "}"
  743. ].join( "\n" )
  744. },
  745. color: {
  746. uniforms: {
  747. map: { type: "t", value: null },
  748. offsetRepeat: { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) },
  749. diffuse: { type: "c", value: new THREE.Color( 0x000000 ) },
  750. emissive: { type: "c", value: new THREE.Color( 0x000000 ) },
  751. specular: { type: "c", value: new THREE.Color( 0x000000 ) },
  752. shininess: { type: "f", value: 30.0 }
  753. },
  754. vertexShader: [
  755. THREE.ShaderChunk[ "uv_pars_vertex" ],
  756. THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
  757. THREE.ShaderChunk[ "skinning_pars_vertex" ],
  758. "void main() {",
  759. THREE.ShaderChunk[ "uv_vertex" ],
  760. THREE.ShaderChunk[ "begin_vertex" ],
  761. THREE.ShaderChunk[ "beginnormal_vertex" ],
  762. THREE.ShaderChunk[ "skinbase_vertex" ],
  763. THREE.ShaderChunk[ "skinnormal_vertex" ],
  764. THREE.ShaderChunk[ "defaultnormal_vertex" ],
  765. THREE.ShaderChunk[ "morphtarget_vertex" ],
  766. THREE.ShaderChunk[ "skinning_vertex" ],
  767. THREE.ShaderChunk[ "project_vertex" ],
  768. "}"
  769. ].join( "\n" ),
  770. fragmentShader: [
  771. "uniform vec3 diffuse;",
  772. "uniform vec3 emissive;",
  773. "uniform vec3 specular;",
  774. "uniform float shininess;",
  775. THREE.ShaderChunk[ "uv_pars_fragment" ],
  776. THREE.ShaderChunk[ "map_pars_fragment" ],
  777. THREE.DeferredShaderChunk[ "packVector3" ],
  778. "void main() {",
  779. "vec3 diffuseColor = diffuse;",
  780. "vec3 emissiveColor = emissive;",
  781. "vec3 specularColor = specular;",
  782. THREE.ShaderChunk[ "map_fragment" ],
  783. THREE.DeferredShaderChunk[ "packColor" ],
  784. "gl_FragColor = packedColor;",
  785. "}"
  786. ].join( "\n" )
  787. },
  788. emissiveLight: {
  789. uniforms: {
  790. samplerColor: { type: "t", value: null },
  791. viewWidth: { type: "f", value: 800 },
  792. viewHeight: { type: "f", value: 600 }
  793. },
  794. vertexShader: [
  795. "void main() { ",
  796. "gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
  797. "}"
  798. ].join( '\n' ),
  799. fragmentShader: [
  800. "uniform sampler2D samplerColor;",
  801. "uniform float viewHeight;",
  802. "uniform float viewWidth;",
  803. THREE.DeferredShaderChunk[ "unpackFloat" ],
  804. "void main() {",
  805. THREE.DeferredShaderChunk[ "computeTextureCoord" ],
  806. THREE.DeferredShaderChunk[ "unpackColor" ],
  807. "gl_FragColor = vec4( emissiveColor, 1.0 );",
  808. "}"
  809. ].join( '\n' )
  810. },
  811. pointLight: {
  812. uniforms: {
  813. samplerNormalDepth: { type: "t", value: null },
  814. samplerColor: { type: "t", value: null },
  815. matProjInverse: { type: "m4", value: new THREE.Matrix4() },
  816. viewWidth: { type: "f", value: 800 },
  817. viewHeight: { type: "f", value: 600 },
  818. lightColor: { type: "c", value: new THREE.Color( 0x000000 ) },
  819. lightPositionVS: { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
  820. lightIntensity: { type: "f", value: 1.0 },
  821. lightRadius: { type: "f", value: 1.0 }
  822. },
  823. vertexShader: [
  824. "void main() {",
  825. "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
  826. "}"
  827. ].join( "\n" ),
  828. fragmentShader: [
  829. "uniform sampler2D samplerNormalDepth;",
  830. "uniform sampler2D samplerColor;",
  831. "uniform float viewHeight;",
  832. "uniform float viewWidth;",
  833. "uniform vec3 lightColor;",
  834. "uniform vec3 lightPositionVS;",
  835. "uniform float lightIntensity;",
  836. "uniform float lightRadius;",
  837. "uniform mat4 matProjInverse;",
  838. THREE.DeferredShaderChunk[ "unpackFloat" ],
  839. "void main() {",
  840. THREE.DeferredShaderChunk[ "computeTextureCoord" ],
  841. THREE.DeferredShaderChunk[ "unpackNormalDepth" ],
  842. THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
  843. "vec3 lightVector = lightPositionVS - vertexPositionVS.xyz;",
  844. "float distance = length( lightVector );",
  845. "if ( distance > lightRadius ) discard;",
  846. "lightVector = normalize( lightVector );",
  847. THREE.DeferredShaderChunk[ "unpackColor" ],
  848. THREE.DeferredShaderChunk[ "computeSpecular" ],
  849. "//float cutoff = 0.3;",
  850. "//float denom = distance / lightRadius + 1.0;",
  851. "//float attenuation = 1.0 / ( denom * denom );",
  852. "//attenuation = ( attenuation - cutoff ) / ( 1.0 - cutoff );",
  853. "//attenuation = max( attenuation, 0.0 );",
  854. "//attenuation *= attenuation;",
  855. "//diffuseColor *= saturate( -distance / lightRadius + 1.0 );",
  856. "//float attenuation = 1.0;",
  857. "float attenuation = saturate( -distance / lightRadius + 1.0 );",
  858. THREE.DeferredShaderChunk[ "combine" ],
  859. "}"
  860. ].join( "\n" )
  861. },
  862. spotLight: {
  863. uniforms: {
  864. samplerNormalDepth: { type: "t", value: null },
  865. samplerColor: { type: "t", value: null },
  866. matProjInverse: { type: "m4", value: new THREE.Matrix4() },
  867. viewWidth: { type: "f", value: 800 },
  868. viewHeight: { type: "f", value: 600 },
  869. lightColor: { type: "c", value: new THREE.Color( 0x000000 ) },
  870. lightDirectionVS: { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
  871. lightPositionVS: { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
  872. lightAngle: { type: "f", value: 1.0 },
  873. lightIntensity: { type: "f", value: 1.0 }
  874. },
  875. vertexShader: [
  876. "void main() { ",
  877. "gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
  878. "}"
  879. ].join( "\n" ),
  880. fragmentShader: [
  881. "uniform sampler2D samplerNormalDepth;",
  882. "uniform sampler2D samplerColor;",
  883. "uniform float viewHeight;",
  884. "uniform float viewWidth;",
  885. "uniform vec3 lightColor;",
  886. "uniform vec3 lightPositionVS;",
  887. "uniform vec3 lightDirectionVS;",
  888. "uniform float lightAngle;",
  889. "uniform float lightIntensity;",
  890. "uniform mat4 matProjInverse;",
  891. THREE.DeferredShaderChunk[ "unpackFloat" ],
  892. "void main() {",
  893. THREE.DeferredShaderChunk[ "computeTextureCoord" ],
  894. THREE.DeferredShaderChunk[ "unpackNormalDepth" ],
  895. THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
  896. THREE.DeferredShaderChunk[ "unpackColor" ],
  897. "vec3 lightVector = normalize( lightPositionVS.xyz - vertexPositionVS.xyz );",
  898. "float rho = dot( lightDirectionVS, lightVector );",
  899. "float rhoMax = cos( lightAngle * 0.5 );",
  900. "if ( rho <= rhoMax ) discard;",
  901. "float theta = rhoMax + 0.0001;",
  902. "float phi = rhoMax + 0.05;",
  903. "float falloff = 4.0;",
  904. "float spot = 0.0;",
  905. "if ( rho >= phi ) {",
  906. "spot = 1.0;",
  907. "} else if ( rho <= theta ) {",
  908. "spot = 0.0;",
  909. "} else { ",
  910. "spot = pow( ( rho - theta ) / ( phi - theta ), falloff );",
  911. "}",
  912. "diffuseColor *= spot;",
  913. THREE.DeferredShaderChunk[ "computeSpecular" ],
  914. "const float attenuation = 1.0;",
  915. THREE.DeferredShaderChunk[ "combine" ],
  916. "}"
  917. ].join( "\n" )
  918. },
  919. directionalLight: {
  920. uniforms: {
  921. samplerNormalDepth: { type: "t", value: null },
  922. samplerColor: { type: "t", value: null },
  923. matProjInverse: { type: "m4", value: new THREE.Matrix4() },
  924. viewWidth: { type: "f", value: 800 },
  925. viewHeight: { type: "f", value: 600 },
  926. lightColor: { type: "c", value: new THREE.Color( 0x000000 ) },
  927. lightDirectionVS : { type: "v3", value: new THREE.Vector3( 0, 1, 0 ) },
  928. lightIntensity: { type: "f", value: 1.0 }
  929. },
  930. vertexShader: [
  931. "void main() { ",
  932. "gl_Position = vec4( sign( position.xy ), 0.0, 1.0 );",
  933. "}"
  934. ].join( '\n' ),
  935. fragmentShader: [
  936. "uniform sampler2D samplerNormalDepth;",
  937. "uniform sampler2D samplerColor;",
  938. "uniform float viewHeight;",
  939. "uniform float viewWidth;",
  940. "uniform vec3 lightColor;",
  941. "uniform vec3 lightDirectionVS;",
  942. "uniform float lightIntensity;",
  943. "uniform mat4 matProjInverse;",
  944. THREE.DeferredShaderChunk[ "unpackFloat" ],
  945. "void main() {",
  946. THREE.DeferredShaderChunk[ "computeTextureCoord" ],
  947. THREE.DeferredShaderChunk[ "unpackNormalDepth" ],
  948. THREE.DeferredShaderChunk[ "computeVertexPositionVS" ],
  949. THREE.DeferredShaderChunk[ "unpackColor" ],
  950. "vec3 lightVector = normalize( lightDirectionVS );",
  951. THREE.DeferredShaderChunk[ "computeSpecular" ],
  952. "const float attenuation = 1.0;",
  953. THREE.DeferredShaderChunk[ "combine" ],
  954. "}"
  955. ].join( '\n' ),
  956. },
  957. composite: {
  958. uniforms: {
  959. samplerLight: { type: "t", value: null }
  960. },
  961. vertexShader: [
  962. "varying vec2 texCoord;",
  963. "void main() {",
  964. "vec4 pos = vec4( sign( position.xy ), 0.0, 1.0 );",
  965. "texCoord = pos.xy * vec2( 0.5 ) + 0.5;",
  966. "gl_Position = pos;",
  967. "}"
  968. ].join( "\n" ),
  969. fragmentShader: [
  970. "varying vec2 texCoord;",
  971. "uniform sampler2D samplerLight;",
  972. "void main() {",
  973. "gl_FragColor = texture2D( samplerLight, texCoord );",
  974. "}"
  975. ].join( "\n" )
  976. }
  977. };