EquirectangularToCubeGenerator.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /**
  2. * @author Richard M. / https://github.com/richardmonette
  3. * @author WestLangley / http://github.com/WestLangley
  4. */
  5. THREE.CubemapGenerator = function ( renderer ) {
  6. this.renderer = renderer;
  7. };
  8. THREE.CubemapGenerator.prototype.fromEquirectangular = function ( texture, options ) {
  9. options = options || {};
  10. var scene = new THREE.Scene();
  11. var shader = {
  12. uniforms: {
  13. tEquirect: { value: null },
  14. },
  15. vertexShader:
  16. `
  17. varying vec3 vWorldDirection;
  18. //include <common>
  19. vec3 transformDirection( in vec3 dir, in mat4 matrix ) {
  20. return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );
  21. }
  22. void main() {
  23. vWorldDirection = transformDirection( position, modelMatrix );
  24. #include <begin_vertex>
  25. #include <project_vertex>
  26. }
  27. `,
  28. fragmentShader:
  29. `
  30. uniform sampler2D tEquirect;
  31. varying vec3 vWorldDirection;
  32. //include <common>
  33. #define RECIPROCAL_PI 0.31830988618
  34. #define RECIPROCAL_PI2 0.15915494
  35. void main() {
  36. vec3 direction = normalize( vWorldDirection );
  37. vec2 sampleUV;
  38. sampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;
  39. sampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;
  40. gl_FragColor = texture2D( tEquirect, sampleUV );
  41. }
  42. `
  43. };
  44. var material = new THREE.ShaderMaterial( {
  45. type: 'CubemapFromEquirect',
  46. uniforms: THREE.UniformsUtils.clone( shader.uniforms ),
  47. vertexShader: shader.vertexShader,
  48. fragmentShader: shader.fragmentShader,
  49. side: THREE.BackSide,
  50. blending: THREE.NoBlending
  51. } );
  52. material.uniforms.tEquirect.value = texture;
  53. var mesh = new THREE.Mesh( new THREE.BoxBufferGeometry( 5, 5, 5 ), material );
  54. scene.add( mesh );
  55. var resolution = options.resolution || 512;
  56. var params = {
  57. type: texture.type,
  58. format: texture.format,
  59. encoding: texture.encoding,
  60. generateMipmaps: ( options.generateMipmaps !== undefined ) ? options.generateMipmaps : texture.generateMipmaps,
  61. minFilter: ( options.minFilter !== undefined ) ? options.minFilter : texture.minFilter,
  62. magFilter: ( options.magFilter !== undefined ) ? options.magFilter : texture.magFilter
  63. };
  64. var camera = new THREE.CubeCamera( 1, 10, resolution, params );
  65. camera.update( this.renderer, scene );
  66. mesh.geometry.dispose();
  67. mesh.material.dispose();
  68. return camera.renderTarget;
  69. };
  70. //
  71. THREE.EquirectangularToCubeGenerator = ( function () {
  72. var camera = new THREE.PerspectiveCamera( 90, 1, 0.1, 10 );
  73. var scene = new THREE.Scene();
  74. var boxMesh = new THREE.Mesh( new THREE.BoxBufferGeometry( 1, 1, 1 ), getShader() );
  75. boxMesh.material.side = THREE.BackSide;
  76. scene.add( boxMesh );
  77. var EquirectangularToCubeGenerator = function ( sourceTexture, options ) {
  78. options = options || {};
  79. this.sourceTexture = sourceTexture;
  80. this.resolution = options.resolution || 512;
  81. this.views = [
  82. { t: [ 1, 0, 0 ], u: [ 0, - 1, 0 ] },
  83. { t: [ - 1, 0, 0 ], u: [ 0, - 1, 0 ] },
  84. { t: [ 0, 1, 0 ], u: [ 0, 0, 1 ] },
  85. { t: [ 0, - 1, 0 ], u: [ 0, 0, - 1 ] },
  86. { t: [ 0, 0, 1 ], u: [ 0, - 1, 0 ] },
  87. { t: [ 0, 0, - 1 ], u: [ 0, - 1, 0 ] },
  88. ];
  89. var params = {
  90. format: options.format || this.sourceTexture.format,
  91. magFilter: this.sourceTexture.magFilter,
  92. minFilter: this.sourceTexture.minFilter,
  93. type: options.type || this.sourceTexture.type,
  94. generateMipmaps: this.sourceTexture.generateMipmaps,
  95. anisotropy: this.sourceTexture.anisotropy,
  96. encoding: this.sourceTexture.encoding
  97. };
  98. this.renderTarget = new THREE.WebGLRenderTargetCube( this.resolution, this.resolution, params );
  99. };
  100. EquirectangularToCubeGenerator.prototype = {
  101. constructor: EquirectangularToCubeGenerator,
  102. update: function ( renderer ) {
  103. var currentRenderTarget = renderer.getRenderTarget();
  104. boxMesh.material.uniforms.equirectangularMap.value = this.sourceTexture;
  105. for ( var i = 0; i < 6; i ++ ) {
  106. var v = this.views[ i ];
  107. camera.position.set( 0, 0, 0 );
  108. camera.up.set( v.u[ 0 ], v.u[ 1 ], v.u[ 2 ] );
  109. camera.lookAt( v.t[ 0 ], v.t[ 1 ], v.t[ 2 ] );
  110. renderer.setRenderTarget( this.renderTarget, i );
  111. renderer.clear();
  112. renderer.render( scene, camera );
  113. }
  114. renderer.setRenderTarget( currentRenderTarget );
  115. return this.renderTarget.texture;
  116. },
  117. dispose: function () {
  118. this.renderTarget.dispose();
  119. }
  120. };
  121. function getShader() {
  122. var shaderMaterial = new THREE.ShaderMaterial( {
  123. uniforms: {
  124. "equirectangularMap": { value: null },
  125. },
  126. vertexShader:
  127. "varying vec3 localPosition;\n\
  128. \n\
  129. void main() {\n\
  130. localPosition = position;\n\
  131. gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\
  132. }",
  133. fragmentShader:
  134. "#include <common>\n\
  135. varying vec3 localPosition;\n\
  136. uniform sampler2D equirectangularMap;\n\
  137. \n\
  138. vec2 EquirectangularSampleUV(vec3 v) {\n\
  139. vec2 uv = vec2(atan(v.z, v.x), asin(v.y));\n\
  140. uv *= vec2(0.1591, 0.3183); // inverse atan\n\
  141. uv += 0.5;\n\
  142. return uv;\n\
  143. }\n\
  144. \n\
  145. void main() {\n\
  146. vec2 uv = EquirectangularSampleUV(normalize(localPosition));\n\
  147. gl_FragColor = texture2D(equirectangularMap, uv);\n\
  148. }",
  149. blending: THREE.NoBlending
  150. } );
  151. shaderMaterial.type = 'EquirectangularToCubeGenerator';
  152. return shaderMaterial;
  153. }
  154. return EquirectangularToCubeGenerator;
  155. } )();