WebGLBackground.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  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. var session = renderer.vr.getSession();
  24. if ( session && session.environmentBlendMode === 'additive' ) background = null;
  25. if ( background === null ) {
  26. setClear( clearColor, clearAlpha );
  27. currentBackground = null;
  28. currentBackgroundVersion = 0;
  29. } else if ( background && background.isColor ) {
  30. setClear( background, 1 );
  31. forceClear = true;
  32. currentBackground = null;
  33. currentBackgroundVersion = 0;
  34. }
  35. if ( renderer.autoClear || forceClear ) {
  36. renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );
  37. }
  38. if ( background && ( background.isCubeTexture || background.isWebGLRenderTargetCube ) ) {
  39. if ( boxMesh === undefined ) {
  40. boxMesh = new Mesh(
  41. new BoxBufferGeometry( 1, 1, 1 ),
  42. new ShaderMaterial( {
  43. type: 'BackgroundCubeMaterial',
  44. uniforms: cloneUniforms( ShaderLib.cube.uniforms ),
  45. vertexShader: ShaderLib.cube.vertexShader,
  46. fragmentShader: ShaderLib.cube.fragmentShader,
  47. side: BackSide,
  48. depthTest: false,
  49. depthWrite: false,
  50. fog: false
  51. } )
  52. );
  53. boxMesh.geometry.removeAttribute( 'normal' );
  54. boxMesh.geometry.removeAttribute( 'uv' );
  55. boxMesh.onBeforeRender = function ( renderer, scene, camera ) {
  56. this.matrixWorld.copyPosition( camera.matrixWorld );
  57. };
  58. // enable code injection for non-built-in material
  59. Object.defineProperty( boxMesh.material, 'map', {
  60. get: function () {
  61. return this.uniforms.tCube.value;
  62. }
  63. } );
  64. objects.update( boxMesh );
  65. }
  66. var texture = background.isWebGLRenderTargetCube ? background.texture : background;
  67. boxMesh.material.uniforms.tCube.value = texture;
  68. boxMesh.material.uniforms.tFlip.value = ( background.isWebGLRenderTargetCube ) ? 1 : - 1;
  69. if ( currentBackground !== background ||
  70. currentBackgroundVersion !== texture.version ) {
  71. boxMesh.material.needsUpdate = true;
  72. currentBackground = background;
  73. currentBackgroundVersion = texture.version;
  74. }
  75. // push to the pre-sorted opaque render list
  76. renderList.unshift( boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null );
  77. } else if ( background && background.isTexture ) {
  78. if ( planeMesh === undefined ) {
  79. planeMesh = new Mesh(
  80. new PlaneBufferGeometry( 2, 2 ),
  81. new ShaderMaterial( {
  82. type: 'BackgroundMaterial',
  83. uniforms: cloneUniforms( ShaderLib.background.uniforms ),
  84. vertexShader: ShaderLib.background.vertexShader,
  85. fragmentShader: ShaderLib.background.fragmentShader,
  86. side: FrontSide,
  87. depthTest: false,
  88. depthWrite: false,
  89. fog: false
  90. } )
  91. );
  92. planeMesh.geometry.removeAttribute( 'normal' );
  93. // enable code injection for non-built-in material
  94. Object.defineProperty( planeMesh.material, 'map', {
  95. get: function () {
  96. return this.uniforms.t2D.value;
  97. }
  98. } );
  99. objects.update( planeMesh );
  100. }
  101. planeMesh.material.uniforms.t2D.value = background;
  102. if ( background.matrixAutoUpdate === true ) {
  103. background.updateMatrix();
  104. }
  105. planeMesh.material.uniforms.uvTransform.value.copy( background.matrix );
  106. if ( currentBackground !== background ||
  107. currentBackgroundVersion !== background.version ) {
  108. planeMesh.material.needsUpdate = true;
  109. currentBackground = background;
  110. currentBackgroundVersion = background.version;
  111. }
  112. // push to the pre-sorted opaque render list
  113. renderList.unshift( planeMesh, planeMesh.geometry, planeMesh.material, 0, 0, null );
  114. }
  115. }
  116. function setClear( color, alpha ) {
  117. state.buffers.color.setClear( color.r, color.g, color.b, alpha, premultipliedAlpha );
  118. }
  119. return {
  120. getClearColor: function () {
  121. return clearColor;
  122. },
  123. setClearColor: function ( color, alpha ) {
  124. clearColor.set( color );
  125. clearAlpha = alpha !== undefined ? alpha : 1;
  126. setClear( clearColor, clearAlpha );
  127. },
  128. getClearAlpha: function () {
  129. return clearAlpha;
  130. },
  131. setClearAlpha: function ( alpha ) {
  132. clearAlpha = alpha;
  133. setClear( clearColor, clearAlpha );
  134. },
  135. render: render
  136. };
  137. }
  138. export { WebGLBackground };
粤ICP备19079148号