three.js後處理之 聚焦效果focus

類似於舞臺聚光燈的效果

 

引入的js

<script src="../../plugins/threeLibrary/three.min.js"></script>
<script src="../../plugins/threeLibrary/js/controls/OrbitControls.js"></script>
<script src="../../plugins/CopyShader.js"></script>
<script src="../../plugins/EffectComposer.js"></script>
<script src="../../plugins/RenderPass.js"></script>
<script src="../../plugins/ShaderPass.js"></script>
<script src="../../plugins/LuminosityHighPassShader.js"></script>
<script src="../../plugins/FocusShader.js"></script>
<script src="../../plugins/UnrealBloomPass.js"></script>

 

<script>
    function initThree(elid,options) {
        let  scene,camera ,renderer,viewer
        viewer={}
        el =  document.getElementById(elid)
        const  width = el.offsetWidth, height = el.offsetHeight,asp =  width / height
        renderer = new THREE.WebGLRenderer({antialias : true});
        renderer.setSize(width, height);
        el.append(renderer.domElement);
        renderer.setClearColor('#000')
        scene = new THREE.Scene()
        camera = new THREE.PerspectiveCamera(45, asp, 1, 10000)
        camera.position.set(10,10,10)
        camera.lookAt(0,0,0)
        scene.add(camera)
        viewer.scene=scene
        viewer.camera=camera
        viewer.renderer=renderer
        const controls = new THREE.OrbitControls( camera, renderer.domElement );
        // 如果使用animate方法時,將此函數刪除
        controls.addEventListener( 'change', ()=>{
            renderer.render( scene, camera );
        });
        viewer.controls=controls
        renderer.render( scene, camera );

        return viewer
    }

    let app=new initThree('box')
    let scene=app.scene
    let renderer=app.renderer
    let camera=app.camera
    let controls=app.controls
    const clock = new THREE.Clock()

    //add light
    const directionalLight = new THREE.DirectionalLight( '#fff' )
    directionalLight.position.set( 30, 30, 30 ).normalize()
    scene.add( directionalLight )
    const ambientLight = new THREE.AmbientLight('#fff',0.3) // obj 唯一 id
    scene.add(ambientLight)


    /*  **** **** ****   ****/
    // renderer.toneMapping = THREE.ReinhardToneMapping;

    const box = new THREE.Mesh(new THREE.BoxGeometry(1,1,1),new THREE.MeshBasicMaterial({color:'red'}))
    scene.add(box)


    const  geometry = new THREE.IcosahedronBufferGeometry( 1, 4 );
    for ( let i = 0; i < 100; i ++ ) {
        const  color = new THREE.Color();
        color.setHSL( Math.random(), 0.7, Math.random() * 0.2 + 0.05 );

        const material = new THREE.MeshBasicMaterial( { color: color } );
        const sphere = new THREE.Mesh( geometry, material );
        sphere.position.x = Math.random() * 100 - 50;
        sphere.position.y = Math.random() * 100 - 50;
        sphere.position.z = Math.random() * 100 - 50
        sphere.scale.setScalar( Math.random() * Math.random() + 0.5 );
        scene.add( sphere );

    }

    //創建 RenderPass
    const renderScene = new THREE.RenderPass( scene, camera )

    //創建 bloomPass
    const  bloomPass = new THREE.UnrealBloomPass( new THREE.Vector2( el.offsetWidth, el.offsetHeight  ), 1.5, 0.4, 0.85 );
    bloomPass.renderToScreen = true;
    bloomPass.threshold = 0;
    bloomPass.strength = 5;
    bloomPass.radius = 0;

    // 創建focusShader
    const focusPass = new THREE.ShaderPass(THREE.FocusShader);
    focusPass.uniforms["screenWidth"].value =  el.offsetWidth;
    focusPass.uniforms["screenHeight"].value = el.offsetHeight;
    focusPass.uniforms["sampleDistance"].value = 5; //通過調控此只來控制聚焦範圍。

    const copyPass = new THREE.ShaderPass(THREE.CopyShader);
    // 讓effectCopy渲染到屏幕上 沒這句不會再屏幕上渲染
    copyPass.renderToScreen = true;

    //創建 EffectComposer
    const  bloomComposer = new THREE.EffectComposer( renderer )
    bloomComposer.renderTarget1.stencilBuffer = true;
    bloomComposer.renderTarget2.stencilBuffer = true;
    bloomComposer.setSize( el.offsetWidth,  el.offsetHeight );
    bloomComposer.addPass( renderScene );
    // 眩光通道bloomPass插入到composer
    bloomComposer.addPass( bloomPass )
    bloomComposer.addPass( focusPass )
    bloomComposer.addPass( copyPass )

    bloomComposer.render()


    //set controls
    controls.addEventListener( 'change', function () {
        bloomComposer.render()
    } )
    controls.autoRotate = false


    function render() {
        controls.update(clock.getDelta())
        bloomComposer.render()
        requestAnimationFrame(render)

    }
    render()

</script>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章