webgl_lights_deferred_pointlights.html 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984
  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 bump_vert = "" +
  99. "varying vec3 normalView;"+
  100. "varying vec2 vUv;"+
  101. "varying vec3 vViewPosition;"+
  102. "uniform vec4 offsetRepeat;"+
  103. "void main() {"+
  104. "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );"+
  105. "gl_Position = projectionMatrix * mvPosition;"+
  106. "normalView = normalize( normalMatrix * normal );"+
  107. "vUv = uv * offsetRepeat.zw + offsetRepeat.xy;"+
  108. "vViewPosition = -mvPosition.xyz;"+
  109. "}";
  110. var bump_frag = "" +
  111. "#extension GL_OES_standard_derivatives : enable\n"+
  112. "varying vec3 normalView;"+
  113. "varying vec2 vUv;"+
  114. "varying vec3 vViewPosition;"+
  115. "uniform sampler2D bumpMap;"+
  116. "uniform float bumpScale;"+
  117. // Derivative maps - bump mapping unparametrized surfaces by Morten Mikkelsen
  118. // http://mmikkelsen3d.blogspot.sk/2011/07/derivative-maps.html
  119. // Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2)
  120. "vec2 dHdxy_fwd() {"+
  121. "vec2 dSTdx = dFdx( vUv );"+
  122. "vec2 dSTdy = dFdy( vUv );"+
  123. "float Hll = bumpScale * texture2D( bumpMap, vUv ).x;"+
  124. "float dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;"+
  125. "float dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;"+
  126. "return vec2( dBx, dBy );"+
  127. "}"+
  128. "vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {"+
  129. "vec3 vSigmaX = dFdx( surf_pos );"+
  130. "vec3 vSigmaY = dFdy( surf_pos );"+
  131. "vec3 vN = surf_norm;"+ // normalized
  132. "vec3 R1 = cross( vSigmaY, vN );"+
  133. "vec3 R2 = cross( vN, vSigmaX );"+
  134. "float fDet = dot( vSigmaX, R1 );"+
  135. "vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );"+
  136. "return normalize( abs( fDet ) * surf_norm - vGrad );"+
  137. "}"+
  138. "void main() {"+
  139. "vec3 normal = normalize( normalView );"+
  140. "normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );"+
  141. "gl_FragColor = vec4( vec3( normal * 0.5 + 0.5 ), 1.0 );"+
  142. "}";
  143. // -----------------------
  144. var unlit_vert = "" +
  145. "varying vec4 clipPos;"+
  146. "void main() {"+
  147. "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );"+
  148. "clipPos = gl_Position;"+
  149. "}";
  150. var unlit_frag = "" +
  151. "varying vec4 clipPos;"+
  152. "uniform sampler2D samplerDepth;"+
  153. "uniform float viewHeight;"+
  154. "uniform float viewWidth;"+
  155. "uniform vec3 lightColor;" +
  156. "void main() {"+
  157. "vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );"+
  158. "float z = texture2D( samplerDepth, texCoord ).x;"+
  159. "vec4 color = vec4( lightColor, 1.0 );"+
  160. "float depth = clipPos.z / clipPos.w;"+
  161. "if( depth > z && z > 0.0 ) color.w = 0.0;"+
  162. "gl_FragColor = color;"+
  163. "}";
  164. // -----------------------
  165. var deferredlight_vert = "" +
  166. "varying vec3 lightView;" +
  167. "uniform vec3 lightPos;" +
  168. "uniform mat4 matView;" +
  169. "void main() { " +
  170. "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );"+
  171. "lightView = vec3( matView * vec4( lightPos, 1.0 ) );" +
  172. "}"
  173. var deferredlight_frag = "" +
  174. "varying vec3 lightView;"+
  175. "uniform sampler2D samplerColor;"+
  176. "uniform sampler2D samplerDepth;"+
  177. "uniform sampler2D samplerNormals;"+
  178. "uniform sampler2D samplerLightBuffer;"+
  179. "uniform float lightRadius;"+
  180. "uniform float lightIntensity;"+
  181. "uniform float viewHeight;"+
  182. "uniform float viewWidth;"+
  183. "uniform vec3 lightColor;"+
  184. "uniform mat4 matProjInverse;"+
  185. "void main() {"+
  186. "vec2 texCoord = gl_FragCoord.xy / vec2( viewWidth, viewHeight );"+
  187. "float z = texture2D( samplerDepth, texCoord ).x;"+
  188. "if ( z == 0.0 ) {"+
  189. "gl_FragColor = vec4( vec3( 0.0 ), 1.0 );"+
  190. "return;"+
  191. "}"+
  192. "float x = texCoord.x * 2.0 - 1.0;"+
  193. "float y = texCoord.y * 2.0 - 1.0;"+
  194. "vec4 projectedPos = vec4( x, y, z, 1.0 );"+
  195. "vec4 viewPos = matProjInverse * projectedPos;"+
  196. "viewPos.xyz /= viewPos.w;"+
  197. "viewPos.w = 1.0;"+
  198. "vec3 lightDir = lightView - viewPos.xyz;"+
  199. "float dist = length( lightDir );"+
  200. "lightDir = normalize( lightDir );"+
  201. "float cutoff = 0.3;"+
  202. "float denom = dist/lightRadius + 1.0;"+
  203. "float attenuation = 1.0 / ( denom * denom );"+
  204. "attenuation = ( attenuation - cutoff ) / ( 1.0 - cutoff );"+
  205. "attenuation = max( attenuation, 0.0 );"+
  206. "vec3 normal = texture2D( samplerNormals, texCoord ).xyz * 2.0 - 1.0;" +
  207. // wrap around lighting
  208. "float diffuseFull = max( dot( normal, lightDir ), 0.0 );" +
  209. "float diffuseHalf = max( 0.5 + 0.5 * dot( normal, lightDir ), 0.0 );" +
  210. "const vec3 wrapRGB = vec3( 0.8, 0.5, 0.5 );"+
  211. "vec3 diffuse = mix( vec3 ( diffuseFull ), vec3( diffuseHalf ), wrapRGB );"+
  212. // simple lighting
  213. //"float diffuseFull = max( dot( normal, lightDir ), 0.0 );" +
  214. //"vec3 diffuse = vec3 ( diffuseFull );"+
  215. // specular
  216. "const float shininess = 75.0;" +
  217. "const float specularIntensity = 0.4;"+
  218. "vec3 halfVector = normalize( lightDir - normalize( viewPos.xyz ) );" +
  219. "float dotNormalHalf = max( dot( normal, halfVector ), 0.0 );" +
  220. "vec3 specular = specularIntensity * max( pow( dotNormalHalf, shininess ), 0.0 ) * diffuse;" +
  221. // color
  222. "vec4 albedo = texture2D( samplerColor, texCoord );"+
  223. // combine
  224. "vec4 color = vec4( 0.0 );"+
  225. "color.xyz = albedo.xyz * lightColor * lightIntensity;"+
  226. "color.w = attenuation;"+
  227. "gl_FragColor = color * vec4( diffuse + specular, 1.0 );" +
  228. "}";
  229. var composite_vert = "" +
  230. "varying vec2 texCoord;"+
  231. "void main() {"+
  232. "vec4 pos = vec4( sign( position.xy ), 0.0, 1.0 );"+
  233. "texCoord = pos.xy * vec2( 0.5, 0.5 ) + 0.5;"+
  234. "gl_Position = pos;"+
  235. "}";
  236. var composite_frag = "" +
  237. "varying vec2 texCoord;"+
  238. "uniform sampler2D samplerLightBuffer;" +
  239. "uniform sampler2D samplerEmitter;" +
  240. "uniform vec3 lightPos;" +
  241. "void main() {" +
  242. "vec3 color = texture2D( samplerLightBuffer, texCoord ).xyz;" +
  243. "vec3 emitter = texture2D( samplerEmitter, texCoord ).xyz;"+
  244. "if ( emitter != vec3( 0.0 ) ) {"+
  245. "gl_FragColor = vec4( emitter, 1.0 );" +
  246. "} else {"+
  247. "gl_FragColor = vec4( sqrt( color ), 1.0 );" +
  248. "}"+
  249. "}"
  250. // -----------------------
  251. var normalShader = {
  252. uniforms: {},
  253. vertexShader: normals_vert,
  254. fragmentShader: normals_frag
  255. };
  256. // -----------------------
  257. var bumpShader = {
  258. uniforms: {
  259. bumpMap: { type: "t", value: null },
  260. bumpScale: { type: "f", value: 1 },
  261. offsetRepeat : { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) }
  262. },
  263. vertexShader: bump_vert,
  264. fragmentShader: bump_frag
  265. };
  266. // -----------------------
  267. var clipDepthShader = {
  268. uniforms: {},
  269. vertexShader: clipdepth_vert,
  270. fragmentShader: clipdepth_frag
  271. };
  272. // -----------------------
  273. var unlitShader = {
  274. uniforms: {
  275. samplerDepth: { type: "t", value: null },
  276. viewWidth: { type: "f", value: WIDTH },
  277. viewHeight: { type: "f", value: HEIGHT },
  278. lightColor: { type: "v3", value: new THREE.Vector3( 0, 0, 0 ) }
  279. },
  280. vertexShader: unlit_vert,
  281. fragmentShader: unlit_frag
  282. };
  283. // -----------------------
  284. var lightShader = {
  285. uniforms: {
  286. samplerLightBuffer: { type: "t", value: null },
  287. samplerNormals: { type: "t", value: null },
  288. samplerDepth: { type: "t", value: null },
  289. samplerColor: { type: "t", value: null },
  290. matView : { type: "m4", value: new THREE.Matrix4() },
  291. matProjInverse : { type: "m4", value: new THREE.Matrix4() },
  292. viewWidth: { type: "f", value: WIDTH },
  293. viewHeight: { type: "f", value: HEIGHT },
  294. lightPos: { type: "v3", value: new THREE.Vector3( 0, 0, 0 ) },
  295. lightColor: { type: "v3", value: new THREE.Vector3( 0, 0, 0 ) },
  296. lightIntensity: { type: "f", value: 1.0 },
  297. lightRadius: { type: "f", value: 1.0 }
  298. },
  299. vertexShader: deferredlight_vert,
  300. fragmentShader: deferredlight_frag
  301. };
  302. // -----------------------
  303. var compositeShader = {
  304. uniforms: {
  305. samplerLightBuffer: { type: "t", value: null },
  306. samplerEmitter: { type: "t", value: null }
  307. },
  308. vertexShader: composite_vert,
  309. fragmentShader: composite_frag
  310. };
  311. // -----------------------------
  312. function bootstrap() {
  313. renderer = new THREE.WebGLRenderer( { alpha: false } );
  314. renderer.setSize( WIDTH, HEIGHT );
  315. renderer.setClearColorHex( 0x000000, 1 );
  316. var container = document.getElementById( 'container' );
  317. container.appendChild( renderer.domElement );
  318. // scene camera
  319. camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR );
  320. camera.position.z = 150;
  321. controls = new THREE.TrackballControls( camera, renderer.domElement );
  322. // scene for walt's head model
  323. scene = new THREE.Scene();
  324. sceneNode = new THREE.Object3D();
  325. scene.add( sceneNode );
  326. scene.add( camera );
  327. // scene for light proxy geometry
  328. lightScene = new THREE.Scene();
  329. lightNode = new THREE.Object3D();
  330. lightScene.add( lightNode );
  331. // scene for the coloured emitter spheres
  332. emitterScene = new THREE.Scene();
  333. emitterNode = new THREE.Object3D();
  334. emitterScene.add( emitterNode );
  335. // full screen quad for compositing
  336. quadScene = new THREE.Scene();
  337. quadNode = new THREE.Object3D();
  338. quadScene.add( quadNode );
  339. quadNode.add( new THREE.Mesh( new THREE.PlaneGeometry( 1, 1 ) ) );
  340. // stats
  341. stats = new Stats();
  342. stats.domElement.style.position = 'absolute';
  343. stats.domElement.style.top = '8px';
  344. stats.domElement.style.zIndex = 100;
  345. container.appendChild( stats.domElement );
  346. // clock
  347. clock = new THREE.Clock();
  348. }
  349. // -----------------------------
  350. function createRenderTargets() {
  351. var rtParamsFloat = { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, stencilBuffer: false,
  352. format: THREE.RGBAFormat, type: THREE.FloatType };
  353. var rtParamsUByte = { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, stencilBuffer: false,
  354. format: THREE.RGBFormat, type: THREE.UnsignedByteType };
  355. // ----------------------------------------------------------
  356. // g-buffer
  357. // ----------------------------------------------------------
  358. rtNormals = new THREE.WebGLRenderTarget( WIDTH, HEIGHT, rtParamsFloat );
  359. rtDepth = new THREE.WebGLRenderTarget( WIDTH, HEIGHT, rtParamsFloat );
  360. rtColor = new THREE.WebGLRenderTarget( WIDTH, HEIGHT, rtParamsUByte );
  361. var passNormals = new THREE.RenderPass( scene, camera );
  362. compNormals = new THREE.EffectComposer( renderer, rtNormals );
  363. compNormals.addPass( passNormals );
  364. var passDepth = new THREE.RenderPass( scene, camera );
  365. compDepth = new THREE.EffectComposer( renderer, rtDepth );
  366. compDepth.addPass( passDepth );
  367. var passColor = new THREE.RenderPass( scene, camera );
  368. compColor = new THREE.EffectComposer( renderer, rtColor );
  369. compColor.addPass( passColor );
  370. // ----------------------------------------------------------
  371. // light emitter spheres
  372. // ----------------------------------------------------------
  373. var emitterPass = new THREE.RenderPass( emitterScene, camera );
  374. rtEmitter = new THREE.WebGLRenderTarget( WIDTH, HEIGHT, rtParamsFloat );
  375. compEmitter = new THREE.EffectComposer( renderer, rtEmitter );
  376. compEmitter.addPass( emitterPass );
  377. // ----------------------------------------------------------
  378. // lighting pass
  379. // ----------------------------------------------------------
  380. rtLightBuffer = new THREE.WebGLRenderTarget( WIDTH, HEIGHT, rtParamsFloat );
  381. rtLightBuffer.generateMipmaps = false;
  382. var passLight = new THREE.RenderPass( lightScene, camera );
  383. compLightBuffer = new THREE.EffectComposer( renderer, rtLightBuffer );
  384. compLightBuffer.addPass( passLight );
  385. lightShader.uniforms[ 'samplerColor' ].value = compColor.renderTarget2;
  386. lightShader.uniforms[ 'samplerNormals' ].value = compNormals.renderTarget2;
  387. lightShader.uniforms[ 'samplerDepth' ].value = compDepth.renderTarget2;
  388. lightShader.uniforms[ 'samplerLightBuffer' ].value = rtLightBuffer;
  389. for ( var x = 0; x < numLights; x ++ ) {
  390. var light = lights[ x ];
  391. // setup material
  392. var matLight = new THREE.ShaderMaterial({
  393. uniforms: THREE.UniformsUtils.clone( lightShader.uniforms ),
  394. vertexShader: lightShader.vertexShader,
  395. fragmentShader: lightShader.fragmentShader
  396. });
  397. matLight.blending = THREE.AdditiveBlending;
  398. matLight.transparent = true;
  399. matLight.depthWrite = false;
  400. matLight.uniforms[ "lightPos" ].value = light.position;
  401. matLight.uniforms[ "lightRadius" ].value = light.distance;
  402. matLight.uniforms[ "lightIntensity" ].value = light.intensity;
  403. matLight.uniforms[ "lightColor" ].value = light.color;
  404. // setup proxy geometry for this light
  405. var geomLight = new THREE.SphereGeometry( light.distance, 16, 10 );
  406. var meshLight = new THREE.Mesh( geomLight, matLight );
  407. lightNode.add( meshLight );
  408. // create emitter sphere
  409. var geomEmitter = new THREE.SphereGeometry( 0.7, 7, 7 );
  410. var matEmitter = new THREE.ShaderMaterial({
  411. uniforms: THREE.UniformsUtils.clone( unlitShader.uniforms ),
  412. vertexShader: unlitShader.vertexShader,
  413. fragmentShader: unlitShader.fragmentShader
  414. });
  415. var meshEmitter = new THREE.Mesh( geomEmitter, matEmitter );
  416. meshEmitter.position = light.position;
  417. emitterNode.add( meshEmitter );
  418. // add emitter to light node
  419. meshLight.emitter = meshEmitter;
  420. }
  421. // ----------------------------------------------------------
  422. // composite
  423. // ----------------------------------------------------------
  424. compositeShader.uniforms['samplerLightBuffer'].value = compLightBuffer.renderTarget2;
  425. compositeShader.uniforms['samplerEmitter'].value = compEmitter.renderTarget2;
  426. compositePass = new THREE.ShaderPass( compositeShader );
  427. compositePass.needsSwap = true;
  428. compositePass.renderToScreen = true;
  429. compFinal = new THREE.EffectComposer( renderer );
  430. compFinal.addPass( compositePass );
  431. }
  432. // -----------------------------
  433. function initScene( object, y, scale ) {
  434. var shader = THREE.ShaderLib[ "basic" ];
  435. object.traverse( function( node ) {
  436. if ( node.material ) {
  437. // color material
  438. var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
  439. var defines = { "USE_MAP": !!node.material.map, "GAMMA_INPUT": true };
  440. var material = new THREE.ShaderMaterial( { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, defines: defines } );
  441. uniforms.diffuse.value.copy( node.material.color );
  442. uniforms.map.value = node.material.map;
  443. if ( node.material.transparent ) {
  444. material.alphaTest = 0.1;
  445. }
  446. if ( node.material.name === "eyetrans" ) {
  447. material.visible = false;
  448. }
  449. node.properties.colorMaterial = material;
  450. // normal material
  451. if ( node.material.bumpMap ) {
  452. var uniforms = THREE.UniformsUtils.clone( bumpShader.uniforms );
  453. var normalMaterial = new THREE.ShaderMaterial( { uniforms: uniforms, vertexShader: bumpShader.vertexShader, fragmentShader: bumpShader.fragmentShader } );
  454. uniforms.bumpMap.value = node.material.bumpMap;
  455. uniforms.bumpScale.value = node.material.bumpScale;
  456. var offset = node.material.bumpMap.offset;
  457. var repeat = node.material.bumpMap.repeat;
  458. uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );
  459. node.properties.normalMaterial = normalMaterial;
  460. } else {
  461. node.properties.normalMaterial = matNormal;
  462. }
  463. // depth material
  464. node.properties.depthMaterial = matClipDepth;
  465. }
  466. } );
  467. object.position.y = y;
  468. object.scale.set( scale, scale, scale );
  469. sceneNode.add( object );
  470. }
  471. // -----------------------------
  472. function initMaterials() {
  473. matNormal = new THREE.ShaderMaterial({
  474. uniforms: normalShader.uniforms,
  475. vertexShader: normalShader.vertexShader,
  476. fragmentShader: normalShader.fragmentShader
  477. });
  478. matClipDepth = new THREE.ShaderMaterial({
  479. uniforms: clipDepthShader.uniforms,
  480. vertexShader: clipDepthShader.vertexShader,
  481. fragmentShader: clipDepthShader.fragmentShader
  482. });
  483. }
  484. // -----------------------------
  485. function initLights() {
  486. var distance = 25;
  487. // front light
  488. var light = new THREE.PointLight();
  489. light.color = new THREE.Vector3( 1, 1, 1 );
  490. light.intensity = 1.5;
  491. light.distance = 1.5 * distance;
  492. lights.push( light );
  493. // random lights
  494. for ( var i = 1; i < numLights; i ++ ) {
  495. var light = new THREE.PointLight();
  496. light.color = new THREE.Vector3( Math.random(), Math.random(), Math.random() ).normalize();
  497. light.intensity = 1.0;
  498. light.distance = distance;
  499. lights.push( light );
  500. }
  501. }
  502. // -----------------------------
  503. function animate() {
  504. var delta = clock.getDelta();
  505. requestAnimationFrame( animate );
  506. controls.update( delta );
  507. stats.update();
  508. render();
  509. }
  510. // -----------------------------
  511. function render() {
  512. // -----------------------------
  513. // g-buffer color
  514. // -----------------------------
  515. sceneNode.traverse( function( node ) {
  516. if ( node.material ) {
  517. node.material = node.properties.colorMaterial;
  518. }
  519. } );
  520. compColor.render();
  521. // -----------------------------
  522. // g-buffer depth
  523. // -----------------------------
  524. sceneNode.traverse( function( node ) {
  525. if ( node.material ) {
  526. node.material = node.properties.depthMaterial;
  527. }
  528. } );
  529. compDepth.render();
  530. // -----------------------------
  531. // g-buffer normals
  532. // -----------------------------
  533. sceneNode.traverse( function( node ) {
  534. if ( node.material ) {
  535. node.material = node.properties.normalMaterial;
  536. }
  537. } );
  538. compNormals.render();
  539. // -----------------------------
  540. // emitter pass
  541. // -----------------------------
  542. for ( var i = 0, il = lightNode.children.length; i < il; i ++ ) {
  543. var light = lightNode.children[ i ];
  544. var color = light.material.uniforms[ "lightColor" ].value;
  545. var emitter = light.emitter;
  546. emitter.material.uniforms[ "samplerDepth" ].value = compDepth.renderTarget2;
  547. emitter.material.uniforms[ "lightColor" ].value = color;
  548. }
  549. compEmitter.render();
  550. // -----------------------------
  551. // light pass
  552. // -----------------------------
  553. for ( var i = 0, il = lightNode.children.length; i < il; i ++ ) {
  554. camera.projectionMatrixInverse.getInverse( camera.projectionMatrix );
  555. lightNode.children[ i ].material.uniforms[ "matProjInverse" ].value = camera.projectionMatrixInverse;
  556. lightNode.children[ i ].material.uniforms[ "matView" ].value = camera.matrixWorldInverse;
  557. }
  558. var time = Date.now() * 0.0005;
  559. // update lights
  560. var x, y, z;
  561. for ( var i = 0; i < numLights; i ++ ) {
  562. var lightPosition = lightNode.children[ i ].material.uniforms[ "lightPos" ].value;
  563. if ( i > 0 ) {
  564. x = Math.sin( time + i * 1.7 ) * 30;
  565. y = Math.cos( time + i * 1.5 ) * 40;
  566. z = Math.cos( time + i * 1.3 ) * 30;
  567. } else {
  568. x = Math.sin( time * 3 ) * 20;
  569. y = 15;
  570. z = Math.cos( time * 3 ) * 25 + 10;
  571. }
  572. lightPosition.x = x;
  573. lightPosition.y = y;
  574. lightPosition.z = z;
  575. lightNode.children[ i ].emitter.position = lightPosition;
  576. lightNode.children[ i ].position = lightPosition;
  577. lightNode.children[ i ].frustumCulled = false;
  578. }
  579. compLightBuffer.render();
  580. // -----------------------------
  581. // composite pass
  582. // -----------------------------
  583. compFinal.render();
  584. }
  585. // -----------------------------
  586. // entry point
  587. // -----------------------------
  588. bootstrap();
  589. initMaterials();
  590. initLights();
  591. createRenderTargets();
  592. var loader = new THREE.UTF8Loader();
  593. /*
  594. loader.load( "models/utf8/ben_dds.js", function ( object ) {
  595. initScene( object, -75, 150 );
  596. animate();
  597. }, { normalizeRGB: true } );
  598. */
  599. /*
  600. loader.load( "models/utf8/WaltHi.js", function ( object ) {
  601. initScene( object, -35, 1 );
  602. animate();
  603. }, { normalizeRGB: true } );
  604. */
  605. var loader = new THREE.JSONLoader();
  606. loader.load( "obj/leeperrysmith/LeePerrySmith.js", function( geometry, materials ) {
  607. var mapColor = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Map-COL.jpg" );
  608. var mapHeight = THREE.ImageUtils.loadTexture( "obj/leeperrysmith/Infinite-Level_02_Disp_NoSmoothUV-4096.jpg" );
  609. mapHeight.repeat.set( 0.998, 0.998 );
  610. mapHeight.offset.set( 0.001, 0.001 )
  611. mapHeight.wrapS = mapHeight.wrapT = THREE.RepeatWrapping;
  612. mapHeight.anisotropy = 4;
  613. mapHeight.format = THREE.RGBFormat;
  614. var material = new THREE.MeshPhongMaterial( { map: mapColor, bumpMap: mapHeight, bumpScale: 2.5 } );
  615. var object = new THREE.Mesh( geometry, material );
  616. initScene( object, 0, 10 );
  617. animate();
  618. } );
  619. </script>
  620. </body>
  621. </html>
粤ICP备19079148号