WebGLBackground.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /**
  2. * @author mrdoob / http://mrdoob.com/
  3. */
  4. import { BackSide, FrontSide } from '../../constants.js';
  5. import { BoxBufferGeometry } from '../../geometries/BoxGeometry.js';
  6. import { PlaneBufferGeometry } from '../../geometries/PlaneGeometry.js';
  7. import { ShaderMaterial } from '../../materials/ShaderMaterial.js';
  8. import { Color } from '../../math/Color.js';
  9. import { Mesh } from '../../objects/Mesh.js';
  10. import { ShaderLib } from '../shaders/ShaderLib.js';
  11. import { cloneUniforms } from '../shaders/UniformsUtils.js';
  12. function WebGLBackground( renderer, state, objects, premultipliedAlpha ) {
  13. var clearColor = new Color( 0x000000 );
  14. var clearAlpha = 0;
  15. var planeMesh;
  16. var boxMesh;
  17. // Store the current background texture and its `version`
  18. // so we can recompile the material accordingly.
  19. var currentBackground = null;
  20. var currentBackgroundVersion = 0;
  21. function render( renderList, scene, camera, forceClear ) {
  22. var background = scene.background;
  23. if ( background === null ) {
  24. setClear( clearColor, clearAlpha );
  25. currentBackground = null;
  26. currentBackgroundVersion = 0;
  27. } else if ( background && background.isColor ) {
  28. setClear( background, 1 );
  29. forceClear = true;
  30. currentBackground = null;
  31. currentBackgroundVersion = 0;
  32. }
  33. if ( renderer.autoClear || forceClear ) {
  34. renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );
  35. }
  36. if ( background && ( background.isCubeTexture || background.isWebGLRenderTargetCube ) ) {
  37. if ( boxMesh === undefined ) {
  38. boxMesh = new Mesh(
  39. new BoxBufferGeometry( 1, 1, 1 ),
  40. new ShaderMaterial( {
  41. type: 'BackgroundCubeMaterial',
  42. uniforms: cloneUniforms( ShaderLib.cube.uniforms ),
  43. vertexShader: ShaderLib.cube.vertexShader,
  44. fragmentShader: ShaderLib.cube.fragmentShader,
  45. side: BackSide,
  46. depthTest: false,
  47. depthWrite: false,
  48. fog: false
  49. } )
  50. );
  51. boxMesh.geometry.removeAttribute( 'normal' );
  52. boxMesh.geometry.removeAttribute( 'uv' );
  53. boxMesh.onBeforeRender = function ( renderer, scene, camera ) {
  54. this.matrixWorld.copyPosition( camera.matrixWorld );
  55. };
  56. // enable code injection for non-built-in material
  57. Object.defineProperty( boxMesh.material, 'map', {
  58. get: function () {
  59. return this.uniforms.tCube.value;
  60. }
  61. } );
  62. objects.update( boxMesh );
  63. }
  64. var texture = background.isWebGLRenderTargetCube ? background.texture : background;
  65. boxMesh.material.uniforms.tCube.value = texture;
  66. boxMesh.material.uniforms.tFlip.value = ( background.isWebGLRenderTargetCube ) ? 1 : - 1;
  67. if ( currentBackground !== background ||
  68. currentBackgroundVersion !== texture.version ) {
  69. boxMesh.material.needsUpdate = true;
  70. currentBackground = background;
  71. currentBackgroundVersion = texture.version;
  72. }
  73. // push to the pre-sorted opaque render list
  74. renderList.unshift( boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null );
  75. } else if ( background && background.isTexture ) {
  76. if ( planeMesh === undefined ) {
  77. planeMesh = new Mesh(
  78. new PlaneBufferGeometry( 2, 2 ),
  79. new ShaderMaterial( {
  80. type: 'BackgroundMaterial',
  81. uniforms: cloneUniforms( ShaderLib.background.uniforms ),
  82. vertexShader: ShaderLib.background.vertexShader,
  83. fragmentShader: ShaderLib.background.fragmentShader,
  84. side: FrontSide,
  85. depthTest: false,
  86. depthWrite: false,
  87. fog: false
  88. } )
  89. );
  90. planeMesh.geometry.removeAttribute( 'normal' );
  91. // enable code injection for non-built-in material
  92. Object.defineProperty( planeMesh.material, 'map', {
  93. get: function () {
  94. return this.uniforms.t2D.value;
  95. }
  96. } );
  97. objects.update( planeMesh );
  98. }
  99. planeMesh.material.uniforms.t2D.value = background;
  100. if ( background.matrixAutoUpdate === true ) {
  101. background.updateMatrix();
  102. }
  103. planeMesh.material.uniforms.uvTransform.value.copy( background.matrix );
  104. if ( currentBackground !== background ||
  105. currentBackgroundVersion !== background.version ) {
  106. planeMesh.material.needsUpdate = true;
  107. currentBackground = background;
  108. currentBackgroundVersion = background.version;
  109. }
  110. // push to the pre-sorted opaque render list
  111. renderList.unshift( planeMesh, planeMesh.geometry, planeMesh.material, 0, 0, null );
  112. }
  113. }
  114. function setClear( color, alpha ) {
  115. state.buffers.color.setClear( color.r, color.g, color.b, alpha, premultipliedAlpha );
  116. }
  117. return {
  118. getClearColor: function () {
  119. return clearColor;
  120. },
  121. setClearColor: function ( color, alpha ) {
  122. clearColor.set( color );
  123. clearAlpha = alpha !== undefined ? alpha : 1;
  124. setClear( clearColor, clearAlpha );
  125. },
  126. getClearAlpha: function () {
  127. return clearAlpha;
  128. },
  129. setClearAlpha: function ( alpha ) {
  130. clearAlpha = alpha;
  131. setClear( clearColor, clearAlpha );
  132. },
  133. render: render
  134. };
  135. }
  136. export { WebGLBackground };
粤ICP备19079148号