Spaces:
Running
Running
| /** | |
| * @author mrdoob / http://mrdoob.com/ | |
| */ | |
| import { BackSide, FrontSide } from '../../constants.js'; | |
| import { BoxBufferGeometry } from '../../geometries/BoxGeometry.js'; | |
| import { PlaneBufferGeometry } from '../../geometries/PlaneGeometry.js'; | |
| import { ShaderMaterial } from '../../materials/ShaderMaterial.js'; | |
| import { Color } from '../../math/Color.js'; | |
| import { Mesh } from '../../objects/Mesh.js'; | |
| import { ShaderLib } from '../shaders/ShaderLib.js'; | |
| import { cloneUniforms } from '../shaders/UniformsUtils.js'; | |
| function WebGLBackground( renderer, state, objects, premultipliedAlpha ) { | |
| var clearColor = new Color( 0x000000 ); | |
| var clearAlpha = 0; | |
| var planeMesh; | |
| var boxMesh; | |
| // Store the current background texture and its `version` | |
| // so we can recompile the material accordingly. | |
| var currentBackground = null; | |
| var currentBackgroundVersion = 0; | |
| function render( renderList, scene, camera, forceClear ) { | |
| var background = scene.background; | |
| // Ignore background in AR | |
| // TODO: Reconsider this. | |
| var vr = renderer.vr; | |
| var session = vr.getSession && vr.getSession(); | |
| if ( session && session.environmentBlendMode === 'additive' ) { | |
| background = null; | |
| } | |
| if ( background === null ) { | |
| setClear( clearColor, clearAlpha ); | |
| currentBackground = null; | |
| currentBackgroundVersion = 0; | |
| } else if ( background && background.isColor ) { | |
| setClear( background, 1 ); | |
| forceClear = true; | |
| currentBackground = null; | |
| currentBackgroundVersion = 0; | |
| } | |
| if ( renderer.autoClear || forceClear ) { | |
| renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil ); | |
| } | |
| if ( background && ( background.isCubeTexture || background.isWebGLRenderTargetCube ) ) { | |
| if ( boxMesh === undefined ) { | |
| boxMesh = new Mesh( | |
| new BoxBufferGeometry( 1, 1, 1 ), | |
| new ShaderMaterial( { | |
| type: 'BackgroundCubeMaterial', | |
| uniforms: cloneUniforms( ShaderLib.cube.uniforms ), | |
| vertexShader: ShaderLib.cube.vertexShader, | |
| fragmentShader: ShaderLib.cube.fragmentShader, | |
| side: BackSide, | |
| depthTest: false, | |
| depthWrite: false, | |
| fog: false | |
| } ) | |
| ); | |
| boxMesh.geometry.removeAttribute( 'normal' ); | |
| boxMesh.geometry.removeAttribute( 'uv' ); | |
| boxMesh.onBeforeRender = function ( renderer, scene, camera ) { | |
| this.matrixWorld.copyPosition( camera.matrixWorld ); | |
| }; | |
| // enable code injection for non-built-in material | |
| Object.defineProperty( boxMesh.material, 'map', { | |
| get: function () { | |
| return this.uniforms.tCube.value; | |
| } | |
| } ); | |
| objects.update( boxMesh ); | |
| } | |
| var texture = background.isWebGLRenderTargetCube ? background.texture : background; | |
| boxMesh.material.uniforms.tCube.value = texture; | |
| boxMesh.material.uniforms.tFlip.value = ( background.isWebGLRenderTargetCube ) ? 1 : - 1; | |
| if ( currentBackground !== background || | |
| currentBackgroundVersion !== texture.version ) { | |
| boxMesh.material.needsUpdate = true; | |
| currentBackground = background; | |
| currentBackgroundVersion = texture.version; | |
| } | |
| // push to the pre-sorted opaque render list | |
| renderList.unshift( boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null ); | |
| } else if ( background && background.isTexture ) { | |
| if ( planeMesh === undefined ) { | |
| planeMesh = new Mesh( | |
| new PlaneBufferGeometry( 2, 2 ), | |
| new ShaderMaterial( { | |
| type: 'BackgroundMaterial', | |
| uniforms: cloneUniforms( ShaderLib.background.uniforms ), | |
| vertexShader: ShaderLib.background.vertexShader, | |
| fragmentShader: ShaderLib.background.fragmentShader, | |
| side: FrontSide, | |
| depthTest: false, | |
| depthWrite: false, | |
| fog: false | |
| } ) | |
| ); | |
| planeMesh.geometry.removeAttribute( 'normal' ); | |
| // enable code injection for non-built-in material | |
| Object.defineProperty( planeMesh.material, 'map', { | |
| get: function () { | |
| return this.uniforms.t2D.value; | |
| } | |
| } ); | |
| objects.update( planeMesh ); | |
| } | |
| planeMesh.material.uniforms.t2D.value = background; | |
| if ( background.matrixAutoUpdate === true ) { | |
| background.updateMatrix(); | |
| } | |
| planeMesh.material.uniforms.uvTransform.value.copy( background.matrix ); | |
| if ( currentBackground !== background || | |
| currentBackgroundVersion !== background.version ) { | |
| planeMesh.material.needsUpdate = true; | |
| currentBackground = background; | |
| currentBackgroundVersion = background.version; | |
| } | |
| // push to the pre-sorted opaque render list | |
| renderList.unshift( planeMesh, planeMesh.geometry, planeMesh.material, 0, 0, null ); | |
| } | |
| } | |
| function setClear( color, alpha ) { | |
| state.buffers.color.setClear( color.r, color.g, color.b, alpha, premultipliedAlpha ); | |
| } | |
| return { | |
| getClearColor: function () { | |
| return clearColor; | |
| }, | |
| setClearColor: function ( color, alpha ) { | |
| clearColor.set( color ); | |
| clearAlpha = alpha !== undefined ? alpha : 1; | |
| setClear( clearColor, clearAlpha ); | |
| }, | |
| getClearAlpha: function () { | |
| return clearAlpha; | |
| }, | |
| setClearAlpha: function ( alpha ) { | |
| clearAlpha = alpha; | |
| setClear( clearColor, clearAlpha ); | |
| }, | |
| render: render | |
| }; | |
| } | |
| export { WebGLBackground }; | |