webgl_lights_deferred_pointlights.html 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823
  1. <!DOCTYPE HTML>
  2. <html lang="en">
  3. <head>
  4. <title>three.js webgl - deferred rendering</title>
  5. <meta charset="utf-8" />
  6. <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
  7. <style>
  8. body {
  9. background-color: #000;
  10. margin: 0px;
  11. overflow: hidden;
  12. }
  13. #info {
  14. position: absolute;
  15. top: 0px; width: 100%;
  16. color: #ffffff;
  17. padding: 5px;
  18. font-family: Monospace;
  19. font-size: 13px;
  20. text-align: center;
  21. }
  22. a {
  23. color: #ff0080;
  24. text-decoration: none;
  25. }
  26. a:hover {
  27. color: #0080ff;
  28. }
  29. </style>
  30. </head>
  31. <body>
  32. <div id="info">
  33. <a href="http://threejs.org" target="_blank">three.js</a> - deferred point lights WebGL demo by <a href="http://de.redplant.de" target=_blank>redPlant</a>.<br />
  34. Walt Disney head by <a href="http://davidoreilly.com/post/18087489343/disneyhead" target="_blank">David OReilly</a><br>
  35. Point Light attenuation formula by <a href="http://imdoingitwrong.wordpress.com/tag/glsl/" target=_blank>Tom Madams</a>
  36. </div>
  37. <div id="container"></div>
  38. <script src="../build/three.min.js"></script>
  39. <script src="js/Detector.js"></script>
  40. <script src="js/libs/stats.min.js"></script>
  41. <script src="js/shaders/CopyShader.js"></script>
  42. <script src="js/postprocessing/EffectComposer.js"></script>
  43. <script src="js/postprocessing/RenderPass.js"></script>
  44. <script src="js/postprocessing/ShaderPass.js"></script>
  45. <script src="js/postprocessing/MaskPass.js"></script>
  46. <script src="js/controls/TrackballControls.js"></script>
  47. <script src="js/loaders/ctm/lzma.js"></script>
  48. <script src="js/loaders/ctm/ctm.js"></script>
  49. <script src="js/loaders/ctm/CTMLoader.js"></script>
  50. <script src="js/loaders/UTF8Loader.js"></script>
  51. <script src="js/loaders/MTLLoader.js"></script>
  52. <script>
  53. if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
  54. var WIDTH = window.innerWidth;
  55. var HEIGHT = window.innerHeight;
  56. var NEAR = 1.0, FAR = 250.0;
  57. var VIEW_ANGLE = 45;
  58. var ASPECT = WIDTH / HEIGHT;
  59. // core
  60. var renderer, camera, controls, stats, clock;
  61. // scenes and scene nodes
  62. var lightScene, lightNode, scene, sceneNode, emitterScene, emitterNode, quadScene, quadNode;
  63. // rendertargets
  64. var rtColor, rtNormals, rtDepth, rtLightBuffer, rtEmitter;
  65. // composer
  66. var compColor, compNormals, compDepth, compLightBuffer, compFinal, compEmitter, compositePass;
  67. // materials
  68. var matNormal, matClipDepth, matBasic, matUnlit;
  69. var numLights = 50;
  70. var lights = new Array();
  71. // -----------------------
  72. // shader definitions
  73. // -----------------------
  74. var clipdepth_frag = ""+
  75. "varying vec4 clipPos;"+
  76. "void main() {"+
  77. "gl_FragColor = vec4( clipPos.z / clipPos.w, 1.0, 1.0, 1.0 );"+
  78. "}";
  79. var clipdepth_vert = "" +
  80. "varying vec4 clipPos;"+
  81. "void main() {"+
  82. "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );"+
  83. "clipPos = gl_Position;"+
  84. "}";
  85. // -----------------------
  86. var normals_vert = "" +
  87. "varying vec3 normalView;"+
  88. "void main() {"+
  89. "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );"+
  90. "normalView = normalize( normalMatrix * normal );"+
  91. "}";
  92. var normals_frag = "" +
  93. "varying vec3 normalView;"+
  94. "void main() {"+
  95. "gl_FragColor = vec4( vec3( normalView * 0.5 + 0.5 ), 1.0 );"+
  96. "}";
  97. // -----------------------
  98. var unlit_vert = "" +
  99. "varying vec4 clipPos;"+
  100. "void main() {"+
  101. "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );"+
  102. "clipPos = gl_Position;"+
  103. "}";
  104. var unlit_frag = "" +
  105. "varying vec4 clipPos;"+
  106. "uniform sampler2D samplerDepth;"+
  107. "uniform float viewHeight;"+
  108. "uniform float viewWidth;"+
  109. "uniform vec3 lightColor;" +
  110. "void main() {"+
  111. "vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );"+
  112. "float z = texture2D( samplerDepth, texCoord ).x;"+
  113. "vec4 color = vec4( lightColor, 1.0 );"+
  114. "float depth = clipPos.z / clipPos.w;"+
  115. "if( depth > z && z > 0.0 ) color.w = 0.0;"+
  116. "gl_FragColor = color;"+
  117. "}";
  118. // -----------------------
  119. var deferredlight_vert = "" +
  120. "varying vec3 lightView;" +
  121. "uniform vec3 lightPos;" +
  122. "uniform mat4 matView;" +
  123. "void main() { " +
  124. "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );"+
  125. "lightView = vec3( matView * vec4( lightPos, 1.0 ) );" +
  126. "}"
  127. var deferredlight_frag = "" +
  128. "varying vec3 lightView;"+
  129. "uniform sampler2D samplerColor;"+
  130. "uniform sampler2D samplerDepth;"+
  131. "uniform sampler2D samplerNormals;"+
  132. "uniform sampler2D samplerLightBuffer;"+
  133. "uniform float lightRadius;"+
  134. "uniform float lightIntensity;"+
  135. "uniform float viewHeight;"+
  136. "uniform float viewWidth;"+
  137. "uniform vec3 lightColor;"+
  138. "uniform mat4 matProjInverse;"+
  139. "void main() {"+
  140. "vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );"+
  141. "float z = texture2D( samplerDepth, texCoord ).x;"+
  142. "if ( z == 0.0 ) {"+
  143. "gl_FragColor = vec4( vec3( 0.0 ), 1.0 );"+
  144. "return;"+
  145. "}"+
  146. "float x = texCoord.x * 2.0 - 1.0;"+
  147. "float y = texCoord.y * 2.0 - 1.0;"+
  148. "vec4 projectedPos = vec4( x, y, z, 1.0 );"+
  149. "vec4 viewPos = matProjInverse * projectedPos;"+
  150. "viewPos.xyz /= viewPos.w;"+
  151. "viewPos.w = 1.0;"+
  152. "vec3 lightDir = lightView - viewPos.xyz;"+
  153. "float dist = length( lightDir );"+
  154. "lightDir = normalize( lightDir );"+
  155. "float cutoff = 0.3;"+
  156. "float denom = dist/lightRadius + 1.0;"+
  157. "float attenuation = 1.0 / ( denom * denom );"+
  158. "attenuation = ( attenuation - cutoff ) / ( 1.0 - cutoff );"+
  159. "attenuation = max( attenuation, 0.0 );"+
  160. "vec3 normal = texture2D( samplerNormals, texCoord ).xyz * 2.0 - 1.0;" +
  161. "float diffuse = max( dot( normal, lightDir ), 0.0 );" +
  162. "const float shininess = 150.0;" +
  163. "vec3 halfVector = normalize( lightDir - normalize( viewPos.xyz ) );" +
  164. "float dotNormalHalf = max( dot( normal, halfVector ), 0.0 );" +
  165. "float specular = max( pow( dotNormalHalf, shininess ), 0.0 ) * diffuse;" +
  166. "vec4 albedo = texture2D( samplerColor, texCoord );"+
  167. "vec4 color = vec4( 0.0 );"+
  168. "color.xyz = albedo.xyz * lightColor * lightIntensity;"+
  169. "color.w = attenuation;"+
  170. "gl_FragColor = color * ( diffuse + specular );" +
  171. "}";
  172. var composite_vert = "" +
  173. "varying vec2 texCoord;"+
  174. "void main() {"+
  175. "vec4 pos = vec4( sign( position.xy ), 0.0, 1.0 );"+
  176. "texCoord = pos.xy * vec2( 0.5, 0.5 ) + 0.5;"+
  177. "gl_Position = pos;"+
  178. "}";
  179. var composite_frag = "" +
  180. "varying vec2 texCoord;"+
  181. "uniform sampler2D samplerLightBuffer;" +
  182. "uniform sampler2D samplerEmitter;" +
  183. "uniform vec3 lightPos;" +
  184. "void main() {" +
  185. "vec3 color = texture2D( samplerLightBuffer, texCoord ).xyz;" +
  186. "vec3 emitter = texture2D( samplerEmitter, texCoord ).xyz;"+
  187. "if ( emitter != vec3( 0.0 ) ) {"+
  188. "gl_FragColor = vec4( emitter, 1.0 );" +
  189. "} else {"+
  190. "gl_FragColor = vec4( color, 1.0 );" +
  191. "}"+
  192. "}"
  193. // -----------------------
  194. var normalShader = {
  195. uniforms: {},
  196. vertexShader: normals_vert,
  197. fragmentShader: normals_frag
  198. };
  199. // -----------------------
  200. var clipDepthShader = {
  201. uniforms: {},
  202. vertexShader: clipdepth_vert,
  203. fragmentShader: clipdepth_frag
  204. };
  205. // -----------------------
  206. var unlitShader = {
  207. uniforms: {
  208. samplerDepth: { type: "t", value: null },
  209. viewWidth: { type: "f", value: WIDTH },
  210. viewHeight: { type: "f", value: HEIGHT },
  211. lightColor: { type: "v3", value: new THREE.Vector3( 0, 0, 0 ) }
  212. },
  213. vertexShader: unlit_vert,
  214. fragmentShader: unlit_frag
  215. };
  216. // -----------------------
  217. var lightShader = {
  218. uniforms: {
  219. samplerLightBuffer: { type: "t", value: null },
  220. samplerNormals: { type: "t", value: null },
  221. samplerDepth: { type: "t", value: null },
  222. samplerColor: { type: "t", value: null },
  223. matView : { type: "m4", value: new THREE.Matrix4() },
  224. matProjInverse : { type: "m4", value: new THREE.Matrix4() },
  225. viewWidth: { type: "f", value: WIDTH },
  226. viewHeight: { type: "f", value: HEIGHT },
  227. lightPos: { type: "v3", value: new THREE.Vector3( 0, 0, 0 ) },
  228. lightColor: { type: "v3", value: new THREE.Vector3( 0, 0, 0 ) },
  229. lightIntensity: { type: "f", value: 1.0 },
  230. lightRadius: { type: "f", value: 1.0 }
  231. },
  232. vertexShader: deferredlight_vert,
  233. fragmentShader: deferredlight_frag
  234. };
  235. // -----------------------
  236. var compositeShader = {
  237. uniforms: {
  238. samplerLightBuffer: { type: "t", value: null },
  239. samplerEmitter: { type: "t", value: null }
  240. },
  241. vertexShader: composite_vert,
  242. fragmentShader: composite_frag
  243. };
  244. // -----------------------------
  245. function bootstrap() {
  246. renderer = new THREE.WebGLRenderer( { alpha: false } );
  247. renderer.setSize( WIDTH, HEIGHT );
  248. renderer.setClearColorHex( 0x000000, 1 );
  249. var container = document.getElementById( 'container' );
  250. container.appendChild( renderer.domElement );
  251. // scene camera
  252. camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR );
  253. camera.position.z = 150;
  254. controls = new THREE.TrackballControls( camera, renderer.domElement );
  255. // scene for walt's head model
  256. scene = new THREE.Scene();
  257. sceneNode = new THREE.Object3D();
  258. scene.add( sceneNode );
  259. scene.add( camera );
  260. // scene for light proxy geometry
  261. lightScene = new THREE.Scene();
  262. lightNode = new THREE.Object3D();
  263. lightScene.add( lightNode );
  264. // scene for the coloured emitter spheres
  265. emitterScene = new THREE.Scene();
  266. emitterNode = new THREE.Object3D();
  267. emitterScene.add( emitterNode );
  268. // full screen quad for compositing
  269. quadScene = new THREE.Scene();
  270. quadNode = new THREE.Object3D();
  271. quadScene.add( quadNode );
  272. quadNode.add( new THREE.Mesh( new THREE.PlaneGeometry( 1, 1 ) ) );
  273. // stats
  274. stats = new Stats();
  275. stats.domElement.style.position = 'absolute';
  276. stats.domElement.style.top = '8px';
  277. stats.domElement.style.zIndex = 100;
  278. container.appendChild( stats.domElement );
  279. // clock
  280. clock = new THREE.Clock();
  281. }
  282. // -----------------------------
  283. function createRenderTargets() {
  284. var rtParamsFloat = { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, stencilBuffer: false,
  285. format: THREE.RGBAFormat, type: THREE.FloatType };
  286. var rtParamsUByte = { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, stencilBuffer: false,
  287. format: THREE.RGBFormat, type: THREE.UnsignedByteType };
  288. // ----------------------------------------------------------
  289. // g-buffer
  290. // ----------------------------------------------------------
  291. rtNormals = new THREE.WebGLRenderTarget( WIDTH, HEIGHT, rtParamsFloat );
  292. rtDepth = new THREE.WebGLRenderTarget( WIDTH, HEIGHT, rtParamsFloat );
  293. rtColor = new THREE.WebGLRenderTarget( WIDTH, HEIGHT, rtParamsUByte );
  294. var passNormals = new THREE.RenderPass( scene, camera );
  295. compNormals = new THREE.EffectComposer( renderer, rtNormals );
  296. compNormals.addPass( passNormals );
  297. var passDepth = new THREE.RenderPass( scene, camera );
  298. compDepth = new THREE.EffectComposer( renderer, rtDepth );
  299. compDepth.addPass( passDepth );
  300. var passColor = new THREE.RenderPass( scene, camera );
  301. compColor = new THREE.EffectComposer( renderer, rtColor );
  302. compColor.addPass( passColor );
  303. // ----------------------------------------------------------
  304. // light emitter spheres
  305. // ----------------------------------------------------------
  306. var emitterPass = new THREE.RenderPass( emitterScene, camera );
  307. rtEmitter = new THREE.WebGLRenderTarget( WIDTH, HEIGHT, rtParamsFloat );
  308. compEmitter = new THREE.EffectComposer( renderer, rtEmitter );
  309. compEmitter.addPass( emitterPass );
  310. // ----------------------------------------------------------
  311. // lighting pass
  312. // ----------------------------------------------------------
  313. rtLightBuffer = new THREE.WebGLRenderTarget( WIDTH, HEIGHT, rtParamsFloat );
  314. rtLightBuffer.generateMipmaps = false;
  315. var passLight = new THREE.RenderPass( lightScene, camera );
  316. compLightBuffer = new THREE.EffectComposer( renderer, rtLightBuffer );
  317. compLightBuffer.addPass( passLight );
  318. lightShader.uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
  319. lightShader.uniforms[ 'samplerNormals' ].value = compNormals.renderTarget2;
  320. lightShader.uniforms[ 'samplerDepth' ].value = compDepth.renderTarget2;
  321. lightShader.uniforms[ 'samplerLightBuffer' ].value = rtLightBuffer;
  322. for ( var x = 0; x < numLights; x ++ ) {
  323. var light = lights[ x ];
  324. // setup material
  325. var matLight = new THREE.ShaderMaterial({
  326. uniforms: THREE.UniformsUtils.clone( lightShader.uniforms ),
  327. vertexShader: lightShader.vertexShader,
  328. fragmentShader: lightShader.fragmentShader
  329. });
  330. matLight.blending = THREE.AdditiveBlending;
  331. matLight.transparent = true;
  332. matLight.depthWrite = false;
  333. matLight.uniforms[ "lightPos" ].value = light.position;
  334. matLight.uniforms[ "lightRadius" ].value = light.distance;
  335. matLight.uniforms[ "lightIntensity" ].value = light.intensity;
  336. matLight.uniforms[ "lightColor" ].value = light.color;
  337. // setup proxy geometry for this light
  338. var geomLight = new THREE.SphereGeometry( light.distance, 16, 10 );
  339. var meshLight = new THREE.Mesh( geomLight, matLight );
  340. lightNode.add( meshLight );
  341. // create emitter sphere
  342. var geomEmitter = new THREE.SphereGeometry( 0.7, 7, 7 );
  343. var matEmitter = new THREE.ShaderMaterial({
  344. uniforms: THREE.UniformsUtils.clone( unlitShader.uniforms ),
  345. vertexShader: unlitShader.vertexShader,
  346. fragmentShader: unlitShader.fragmentShader
  347. });
  348. var meshEmitter = new THREE.Mesh( geomEmitter, matEmitter );
  349. meshEmitter.position = light.position;
  350. emitterNode.add( meshEmitter );
  351. // add emitter to light node
  352. meshLight.emitter = meshEmitter;
  353. }
  354. // ----------------------------------------------------------
  355. // composite
  356. // ----------------------------------------------------------
  357. compositeShader.uniforms['samplerLightBuffer'].value = compLightBuffer.renderTarget2;
  358. compositeShader.uniforms['samplerEmitter'].value = compEmitter.renderTarget2;
  359. compositePass = new THREE.ShaderPass( compositeShader );
  360. compositePass.needsSwap = true;
  361. compositePass.renderToScreen = true;
  362. compFinal = new THREE.EffectComposer( renderer );
  363. compFinal.addPass( compositePass );
  364. }
  365. // -----------------------------
  366. function initScene( object, y, scale ) {
  367. object.traverse( function( node ) {
  368. if ( node.material ) {
  369. var material = new THREE.MeshBasicMaterial();
  370. material.color.copy( node.material.color );
  371. material.map = node.material.map;
  372. if ( node.material.transparent ) {
  373. material.alphaTest = 0.1;
  374. }
  375. if ( node.material.name === "eyetrans" ) {
  376. material.visible = false;
  377. }
  378. node.colorMaterial = material;
  379. }
  380. } );
  381. object.position.y = y;
  382. object.scale.set( scale, scale, scale );
  383. sceneNode.add( object );
  384. }
  385. // -----------------------------
  386. function initMaterials() {
  387. matNormal = new THREE.ShaderMaterial({
  388. uniforms: normalShader.uniforms,
  389. vertexShader: normalShader.vertexShader,
  390. fragmentShader: normalShader.fragmentShader
  391. });
  392. matClipDepth = new THREE.ShaderMaterial({
  393. uniforms: clipDepthShader.uniforms,
  394. vertexShader: clipDepthShader.vertexShader,
  395. fragmentShader: clipDepthShader.fragmentShader
  396. });
  397. }
  398. // -----------------------------
  399. function initLights() {
  400. var distance = 25;
  401. // front light
  402. var light = new THREE.PointLight();
  403. light.color = new THREE.Vector3( 1, 1, 1 );
  404. light.intensity = 1.5;
  405. light.distance = 1.5 * distance;
  406. lights.push( light );
  407. // random lights
  408. for ( var i = 1; i < numLights; i ++ ) {
  409. var light = new THREE.PointLight();
  410. light.color = new THREE.Vector3( Math.random(), Math.random(), Math.random() ).normalize();
  411. light.intensity = 1.0;
  412. light.distance = distance;
  413. lights.push( light );
  414. }
  415. }
  416. // -----------------------------
  417. function animate() {
  418. var delta = clock.getDelta();
  419. requestAnimationFrame( animate );
  420. controls.update( delta );
  421. stats.update();
  422. render();
  423. }
  424. // -----------------------------
  425. function render() {
  426. // -----------------------------
  427. // g-buffer color
  428. // -----------------------------
  429. sceneNode.traverse( function( node ) {
  430. if ( node.material ) {
  431. node.material = node.colorMaterial;
  432. }
  433. } );
  434. compColor.render();
  435. // -----------------------------
  436. // g-buffer depth
  437. // -----------------------------
  438. sceneNode.traverse( function( node ) {
  439. if ( node.material ) {
  440. node.material = matClipDepth;
  441. }
  442. } );
  443. compDepth.render();
  444. // -----------------------------
  445. // g-buffer normals
  446. // -----------------------------
  447. sceneNode.traverse( function( node ) {
  448. if ( node.material ) {
  449. node.material = matNormal;
  450. }
  451. } );
  452. compNormals.render();
  453. // -----------------------------
  454. // emitter pass
  455. // -----------------------------
  456. for ( var i = 0, il = lightNode.children.length; i < il; i ++ ) {
  457. var light = lightNode.children[ i ];
  458. var color = light.material.uniforms[ "lightColor" ].value;
  459. var emitter = light.emitter;
  460. emitter.material.uniforms[ "samplerDepth" ].value = compDepth.renderTarget2;
  461. emitter.material.uniforms[ "lightColor" ].value = color;
  462. }
  463. compEmitter.render();
  464. // -----------------------------
  465. // light pass
  466. // -----------------------------
  467. for ( var i = 0, il = lightNode.children.length; i < il; i ++ ) {
  468. camera.projectionMatrixInverse.getInverse( camera.projectionMatrix );
  469. lightNode.children[ i ].material.uniforms[ "matProjInverse" ].value = camera.projectionMatrixInverse;
  470. lightNode.children[ i ].material.uniforms[ "matView" ].value = camera.matrixWorldInverse;
  471. }
  472. var time = Date.now() * 0.0005;
  473. // update lights
  474. var x, y, z;
  475. for ( var i = 0; i < numLights; i ++ ) {
  476. var lightPosition = lightNode.children[ i ].material.uniforms[ "lightPos" ].value;
  477. if ( i > 0 ) {
  478. x = Math.sin( time + i * 1.7 ) * 30;
  479. y = Math.cos( time + i * 1.5 ) * 40;
  480. z = Math.cos( time + i * 1.3 ) * 30;
  481. } else {
  482. x = Math.sin( time * 3 ) * 20;
  483. y = 15;
  484. z = Math.cos( time * 3 ) * 25 + 10;
  485. }
  486. lightPosition.x = x;
  487. lightPosition.y = y;
  488. lightPosition.z = z;
  489. lightNode.children[ i ].emitter.position = lightPosition;
  490. lightNode.children[ i ].position = lightPosition;
  491. lightNode.children[ i ].frustumCulled = false;
  492. }
  493. compLightBuffer.render();
  494. // -----------------------------
  495. // composite pass
  496. // -----------------------------
  497. compFinal.render();
  498. }
  499. // -----------------------------
  500. // entry point
  501. // -----------------------------
  502. var loader = new THREE.UTF8Loader();
  503. loader.load( "models/utf8/ben_dds.js", function ( object ) {
  504. bootstrap();
  505. initScene( object, -75, 150 );
  506. initMaterials();
  507. initLights();
  508. createRenderTargets();
  509. animate();
  510. }, { normalizeRGB: true } );
  511. /*
  512. loader.load( "models/utf8/WaltHi.js", function ( object ) {
  513. bootstrap();
  514. initScene( object, -35, 1 );
  515. initMaterials();
  516. initLights();
  517. createRenderTargets();
  518. animate();
  519. }, { normalizeRGB: true } );
  520. */
  521. </script>
  522. </body>
  523. </html>