#
luxiaotao1123
2021-12-31 d11d1de794f544d88ed6dbdb5fe86e27d7e017f4
#
4个文件已添加
2 文件已重命名
1个文件已修改
588 ■■■■■ 已修改文件
static/js/app.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
static/js/lib/EffectComposer.js 318 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
static/js/lib/postprocessing/MaskPass.js 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
static/js/lib/postprocessing/OutlinePass.js 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
static/js/lib/postprocessing/Pass.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
static/js/lib/postprocessing/RenderPass.js 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
static/js/lib/postprocessing/ShaderPass.js 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
static/js/app.js
@@ -1,7 +1,10 @@
import {OrbitControls} from './lib/OrbitControls.js';
import { PointerLockControls } from './lib/PointerLockControls.js';
import Stats from './lib/stats.module.js';
import { OutlinePass } from './lib/OutlinePass.js';
import { EffectComposer } from './lib/EffectComposer.js';
import { RenderPass } from './lib/postprocessing/RenderPass.js';
import { ShaderPass } from './lib/postprocessing/ShaderPass.js';
import { OutlinePass } from './lib/postprocessing/OutlinePass.js';
import {MTLLoader} from './lib/MTLLoader.js';
import {OBJLoader} from './lib/OBJLoader.js';
import {StoreShelf} from './object/StoreShelf.js';
@@ -49,6 +52,7 @@
            this.initLight();
            this.initReSize(this);
            this.initOutLine();
            this.initComposer();
            this.initObjectSelect();
            this.initPointLockControl(this);
            this.initFloor();
@@ -192,6 +196,12 @@
            this.outlinePass.visibleEdgeColor.set('#B31985');//包围线颜色
            this.outlinePass.hiddenEdgeColor.set('#190a05');//被遮挡的边界线颜色
        }
        this.initComposer = function(){
            this.composer = new EffectComposer(this.renderer);
            const renderPass = new RenderPass( this.scene, this.camera );
            this.composer.addPass( renderPass );
            this.composer.addPass(this.outlinePass);
        }
        this.initObjectSelect = function(){
            new ObjectSelect(this.scene, this.camera, this.outlinePass);
        }
static/js/lib/EffectComposer.js
New file
@@ -0,0 +1,318 @@
import {
    BufferGeometry,
    Clock,
    Float32BufferAttribute,
    LinearFilter,
    Mesh,
    OrthographicCamera,
    RGBAFormat,
    Vector2,
    WebGLRenderTarget
} from '../three.module.js';
import { CopyShader } from '../lib/CopyShader.js';
import { ShaderPass } from '../lib/postprocessing/ShaderPass.js';
import { MaskPass } from '../lib/postprocessing/MaskPass.js';
import { ClearMaskPass } from '../lib/postprocessing/MaskPass.js';
class EffectComposer {
    constructor( renderer, renderTarget ) {
        this.renderer = renderer;
        if ( renderTarget === undefined ) {
            const parameters = {
                minFilter: LinearFilter,
                magFilter: LinearFilter,
                format: RGBAFormat
            };
            const size = renderer.getSize( new Vector2() );
            this._pixelRatio = renderer.getPixelRatio();
            this._width = size.width;
            this._height = size.height;
            renderTarget = new WebGLRenderTarget( this._width * this._pixelRatio, this._height * this._pixelRatio, parameters );
            renderTarget.texture.name = 'EffectComposer.rt1';
        } else {
            this._pixelRatio = 1;
            this._width = renderTarget.width;
            this._height = renderTarget.height;
        }
        this.renderTarget1 = renderTarget;
        this.renderTarget2 = renderTarget.clone();
        this.renderTarget2.texture.name = 'EffectComposer.rt2';
        this.writeBuffer = this.renderTarget1;
        this.readBuffer = this.renderTarget2;
        this.renderToScreen = true;
        this.passes = [];
        // dependencies
        if ( CopyShader === undefined ) {
            console.error( 'THREE.EffectComposer relies on CopyShader' );
        }
        if ( ShaderPass === undefined ) {
            console.error( 'THREE.EffectComposer relies on ShaderPass' );
        }
        this.copyPass = new ShaderPass( CopyShader );
        this.clock = new Clock();
    }
    swapBuffers() {
        const tmp = this.readBuffer;
        this.readBuffer = this.writeBuffer;
        this.writeBuffer = tmp;
    }
    addPass( pass ) {
        this.passes.push( pass );
        pass.setSize( this._width * this._pixelRatio, this._height * this._pixelRatio );
    }
    insertPass( pass, index ) {
        this.passes.splice( index, 0, pass );
        pass.setSize( this._width * this._pixelRatio, this._height * this._pixelRatio );
    }
    removePass( pass ) {
        const index = this.passes.indexOf( pass );
        if ( index !== - 1 ) {
            this.passes.splice( index, 1 );
        }
    }
    isLastEnabledPass( passIndex ) {
        for ( let i = passIndex + 1; i < this.passes.length; i ++ ) {
            if ( this.passes[ i ].enabled ) {
                return false;
            }
        }
        return true;
    }
    render( deltaTime ) {
        // deltaTime value is in seconds
        if ( deltaTime === undefined ) {
            deltaTime = this.clock.getDelta();
        }
        const currentRenderTarget = this.renderer.getRenderTarget();
        let maskActive = false;
        for ( let i = 0, il = this.passes.length; i < il; i ++ ) {
            const pass = this.passes[ i ];
            if ( pass.enabled === false ) continue;
            pass.renderToScreen = ( this.renderToScreen && this.isLastEnabledPass( i ) );
            pass.render( this.renderer, this.writeBuffer, this.readBuffer, deltaTime, maskActive );
            if ( pass.needsSwap ) {
                if ( maskActive ) {
                    const context = this.renderer.getContext();
                    const stencil = this.renderer.state.buffers.stencil;
                    //context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );
                    stencil.setFunc( context.NOTEQUAL, 1, 0xffffffff );
                    this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, deltaTime );
                    //context.stencilFunc( context.EQUAL, 1, 0xffffffff );
                    stencil.setFunc( context.EQUAL, 1, 0xffffffff );
                }
                this.swapBuffers();
            }
            if ( MaskPass !== undefined ) {
                if ( pass instanceof MaskPass ) {
                    maskActive = true;
                } else if ( pass instanceof ClearMaskPass ) {
                    maskActive = false;
                }
            }
        }
        this.renderer.setRenderTarget( currentRenderTarget );
    }
    reset( renderTarget ) {
        if ( renderTarget === undefined ) {
            const size = this.renderer.getSize( new Vector2() );
            this._pixelRatio = this.renderer.getPixelRatio();
            this._width = size.width;
            this._height = size.height;
            renderTarget = this.renderTarget1.clone();
            renderTarget.setSize( this._width * this._pixelRatio, this._height * this._pixelRatio );
        }
        this.renderTarget1.dispose();
        this.renderTarget2.dispose();
        this.renderTarget1 = renderTarget;
        this.renderTarget2 = renderTarget.clone();
        this.writeBuffer = this.renderTarget1;
        this.readBuffer = this.renderTarget2;
    }
    setSize( width, height ) {
        this._width = width;
        this._height = height;
        const effectiveWidth = this._width * this._pixelRatio;
        const effectiveHeight = this._height * this._pixelRatio;
        this.renderTarget1.setSize( effectiveWidth, effectiveHeight );
        this.renderTarget2.setSize( effectiveWidth, effectiveHeight );
        for ( let i = 0; i < this.passes.length; i ++ ) {
            this.passes[ i ].setSize( effectiveWidth, effectiveHeight );
        }
    }
    setPixelRatio( pixelRatio ) {
        this._pixelRatio = pixelRatio;
        this.setSize( this._width, this._height );
    }
}
class Pass {
    constructor() {
        // if set to true, the pass is processed by the composer
        this.enabled = true;
        // if set to true, the pass indicates to swap read and write buffer after rendering
        this.needsSwap = true;
        // if set to true, the pass clears its buffer before rendering
        this.clear = false;
        // if set to true, the result of the pass is rendered to screen. This is set automatically by EffectComposer.
        this.renderToScreen = false;
    }
    setSize( /* width, height */ ) {}
    render( /* renderer, writeBuffer, readBuffer, deltaTime, maskActive */ ) {
        console.error( 'THREE.Pass: .render() must be implemented in derived pass.' );
    }
}
// Helper for passes that need to fill the viewport with a single quad.
const _camera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
// https://github.com/mrdoob/three.js/pull/21358
const _geometry = new BufferGeometry();
_geometry.setAttribute( 'position', new Float32BufferAttribute( [ - 1, 3, 0, - 1, - 1, 0, 3, - 1, 0 ], 3 ) );
_geometry.setAttribute( 'uv', new Float32BufferAttribute( [ 0, 2, 0, 0, 2, 0 ], 2 ) );
class FullScreenQuad {
    constructor( material ) {
        this._mesh = new Mesh( _geometry, material );
    }
    dispose() {
        this._mesh.geometry.dispose();
    }
    render( renderer ) {
        renderer.render( this._mesh, _camera );
    }
    get material() {
        return this._mesh.material;
    }
    set material( value ) {
        this._mesh.material = value;
    }
}
export { EffectComposer, Pass, FullScreenQuad };
static/js/lib/postprocessing/MaskPass.js
New file
@@ -0,0 +1,101 @@
import { Pass } from '../../lib/postprocessing/Pass.js';
class MaskPass extends Pass {
    constructor( scene, camera ) {
        super();
        this.scene = scene;
        this.camera = camera;
        this.clear = true;
        this.needsSwap = false;
        this.inverse = false;
    }
    render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) {
        const context = renderer.getContext();
        const state = renderer.state;
        // don't update color or depth
        state.buffers.color.setMask( false );
        state.buffers.depth.setMask( false );
        // lock buffers
        state.buffers.color.setLocked( true );
        state.buffers.depth.setLocked( true );
        // set up stencil
        let writeValue, clearValue;
        if ( this.inverse ) {
            writeValue = 0;
            clearValue = 1;
        } else {
            writeValue = 1;
            clearValue = 0;
        }
        state.buffers.stencil.setTest( true );
        state.buffers.stencil.setOp( context.REPLACE, context.REPLACE, context.REPLACE );
        state.buffers.stencil.setFunc( context.ALWAYS, writeValue, 0xffffffff );
        state.buffers.stencil.setClear( clearValue );
        state.buffers.stencil.setLocked( true );
        // draw into the stencil buffer
        renderer.setRenderTarget( readBuffer );
        if ( this.clear ) renderer.clear();
        renderer.render( this.scene, this.camera );
        renderer.setRenderTarget( writeBuffer );
        if ( this.clear ) renderer.clear();
        renderer.render( this.scene, this.camera );
        // unlock color and depth buffer for subsequent rendering
        state.buffers.color.setLocked( false );
        state.buffers.depth.setLocked( false );
        // only render where stencil is set to 1
        state.buffers.stencil.setLocked( false );
        state.buffers.stencil.setFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1
        state.buffers.stencil.setOp( context.KEEP, context.KEEP, context.KEEP );
        state.buffers.stencil.setLocked( true );
    }
}
class ClearMaskPass extends Pass {
    constructor() {
        super();
        this.needsSwap = false;
    }
    render( renderer /*, writeBuffer, readBuffer, deltaTime, maskActive */ ) {
        renderer.state.buffers.stencil.setLocked( false );
        renderer.state.buffers.stencil.setTest( false );
    }
}
export { MaskPass, ClearMaskPass };
static/js/lib/postprocessing/OutlinePass.js
File was renamed from static/js/lib/OutlinePass.js
@@ -14,9 +14,9 @@
    Vector2,
    Vector3,
    WebGLRenderTarget
} from '../three.module.js';
import { Pass, FullScreenQuad } from '../lib/Pass.js';
import { CopyShader } from '../lib/CopyShader.js';
} from '../../three.module.js';
import { Pass, FullScreenQuad } from '../../lib/postprocessing/Pass.js';
import { CopyShader } from '../../lib/CopyShader.js';
class OutlinePass extends Pass {
static/js/lib/postprocessing/Pass.js
File was renamed from static/js/lib/Pass.js
@@ -3,7 +3,7 @@
    Float32BufferAttribute,
    OrthographicCamera,
    Mesh
} from '../three.module.js';
} from '../../three.module.js';
class Pass {
static/js/lib/postprocessing/RenderPass.js
New file
@@ -0,0 +1,81 @@
import {
    Color
} from '../../three.module.js';
import { Pass } from '../../lib/postprocessing/Pass.js';
class RenderPass extends Pass {
    constructor( scene, camera, overrideMaterial, clearColor, clearAlpha ) {
        super();
        this.scene = scene;
        this.camera = camera;
        this.overrideMaterial = overrideMaterial;
        this.clearColor = clearColor;
        this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 0;
        this.clear = true;
        this.clearDepth = false;
        this.needsSwap = false;
        this._oldClearColor = new Color();
    }
    render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) {
        const oldAutoClear = renderer.autoClear;
        renderer.autoClear = false;
        let oldClearAlpha, oldOverrideMaterial;
        if ( this.overrideMaterial !== undefined ) {
            oldOverrideMaterial = this.scene.overrideMaterial;
            this.scene.overrideMaterial = this.overrideMaterial;
        }
        if ( this.clearColor ) {
            renderer.getClearColor( this._oldClearColor );
            oldClearAlpha = renderer.getClearAlpha();
            renderer.setClearColor( this.clearColor, this.clearAlpha );
        }
        if ( this.clearDepth ) {
            renderer.clearDepth();
        }
        renderer.setRenderTarget( this.renderToScreen ? null : readBuffer );
        // TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600
        if ( this.clear ) renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );
        renderer.render( this.scene, this.camera );
        if ( this.clearColor ) {
            renderer.setClearColor( this._oldClearColor, oldClearAlpha );
        }
        if ( this.overrideMaterial !== undefined ) {
            this.scene.overrideMaterial = oldOverrideMaterial;
        }
        renderer.autoClear = oldAutoClear;
    }
}
export { RenderPass };
static/js/lib/postprocessing/ShaderPass.js
New file
@@ -0,0 +1,68 @@
import {
    ShaderMaterial,
    UniformsUtils
} from '../../three.module.js';
import { Pass, FullScreenQuad } from '../../lib/postprocessing/Pass.js';
class ShaderPass extends Pass {
    constructor( shader, textureID ) {
        super();
        this.textureID = ( textureID !== undefined ) ? textureID : 'tDiffuse';
        if ( shader instanceof ShaderMaterial ) {
            this.uniforms = shader.uniforms;
            this.material = shader;
        } else if ( shader ) {
            this.uniforms = UniformsUtils.clone( shader.uniforms );
            this.material = new ShaderMaterial( {
                defines: Object.assign( {}, shader.defines ),
                uniforms: this.uniforms,
                vertexShader: shader.vertexShader,
                fragmentShader: shader.fragmentShader
            } );
        }
        this.fsQuad = new FullScreenQuad( this.material );
    }
    render( renderer, writeBuffer, readBuffer /*, deltaTime, maskActive */ ) {
        if ( this.uniforms[ this.textureID ] ) {
            this.uniforms[ this.textureID ].value = readBuffer.texture;
        }
        this.fsQuad.material = this.material;
        if ( this.renderToScreen ) {
            renderer.setRenderTarget( null );
            this.fsQuad.render( renderer );
        } else {
            renderer.setRenderTarget( writeBuffer );
            // TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600
            if ( this.clear ) renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );
            this.fsQuad.render( renderer );
        }
    }
}
export { ShaderPass };