EquirectangularToCubeGenerator.js 5.3 KB

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