WebGLCubeRenderTarget.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import { BackSide, LinearFilter, LinearMipmapLinearFilter, NoBlending, RGBAFormat } from '../constants.js';
  2. import { Mesh } from '../objects/Mesh.js';
  3. import { BoxGeometry } from '../geometries/BoxGeometry.js';
  4. import { ShaderMaterial } from '../materials/ShaderMaterial.js';
  5. import { cloneUniforms } from './shaders/UniformsUtils.js';
  6. import { WebGLRenderTarget } from './WebGLRenderTarget.js';
  7. import { CubeCamera } from '../cameras/CubeCamera.js';
  8. import { CubeTexture } from '../textures/CubeTexture.js';
  9. class WebGLCubeRenderTarget extends WebGLRenderTarget {
  10. constructor( size, options, dummy ) {
  11. if ( Number.isInteger( options ) ) {
  12. console.warn( 'THREE.WebGLCubeRenderTarget: constructor signature is now WebGLCubeRenderTarget( size, options )' );
  13. options = dummy;
  14. }
  15. super( size, size, options );
  16. options = options || {};
  17. // By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js)
  18. // in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words,
  19. // in a left-handed coordinate system. By continuing this convention, preexisting cube maps continued to render correctly.
  20. // three.js uses a right-handed coordinate system. So environment maps used in three.js appear to have px and nx swapped
  21. // and the flag isRenderTargetTexture controls this conversion. The flip is not required when using WebGLCubeRenderTarget.texture
  22. // as a cube texture (this is detected when isRenderTargetTexture is set to true for cube textures).
  23. this.texture = new CubeTexture( undefined, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding );
  24. this.texture.isRenderTargetTexture = true;
  25. this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false;
  26. this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter;
  27. this.texture._needsFlipEnvMap = false;
  28. }
  29. fromEquirectangularTexture( renderer, texture ) {
  30. this.texture.type = texture.type;
  31. this.texture.format = RGBAFormat; // see #18859
  32. this.texture.encoding = texture.encoding;
  33. this.texture.generateMipmaps = texture.generateMipmaps;
  34. this.texture.minFilter = texture.minFilter;
  35. this.texture.magFilter = texture.magFilter;
  36. const shader = {
  37. uniforms: {
  38. tEquirect: { value: null },
  39. },
  40. vertexShader: /* glsl */`
  41. varying vec3 vWorldDirection;
  42. vec3 transformDirection( in vec3 dir, in mat4 matrix ) {
  43. return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );
  44. }
  45. void main() {
  46. vWorldDirection = transformDirection( position, modelMatrix );
  47. #include <begin_vertex>
  48. #include <project_vertex>
  49. }
  50. `,
  51. fragmentShader: /* glsl */`
  52. uniform sampler2D tEquirect;
  53. varying vec3 vWorldDirection;
  54. #include <common>
  55. void main() {
  56. vec3 direction = normalize( vWorldDirection );
  57. vec2 sampleUV = equirectUv( direction );
  58. gl_FragColor = texture2D( tEquirect, sampleUV );
  59. }
  60. `
  61. };
  62. const geometry = new BoxGeometry( 5, 5, 5 );
  63. const material = new ShaderMaterial( {
  64. name: 'CubemapFromEquirect',
  65. uniforms: cloneUniforms( shader.uniforms ),
  66. vertexShader: shader.vertexShader,
  67. fragmentShader: shader.fragmentShader,
  68. side: BackSide,
  69. blending: NoBlending
  70. } );
  71. material.uniforms.tEquirect.value = texture;
  72. const mesh = new Mesh( geometry, material );
  73. const currentMinFilter = texture.minFilter;
  74. // Avoid blurred poles
  75. if ( texture.minFilter === LinearMipmapLinearFilter ) texture.minFilter = LinearFilter;
  76. const camera = new CubeCamera( 1, 10, this );
  77. camera.update( renderer, mesh );
  78. texture.minFilter = currentMinFilter;
  79. mesh.geometry.dispose();
  80. mesh.material.dispose();
  81. return this;
  82. }
  83. clear( renderer, color, depth, stencil ) {
  84. const currentRenderTarget = renderer.getRenderTarget();
  85. for ( let i = 0; i < 6; i ++ ) {
  86. renderer.setRenderTarget( this, i );
  87. renderer.clear( color, depth, stencil );
  88. }
  89. renderer.setRenderTarget( currentRenderTarget );
  90. }
  91. }
  92. WebGLCubeRenderTarget.prototype.isWebGLCubeRenderTarget = true;
  93. export { WebGLCubeRenderTarget };
粤ICP备19079148号