three.js 後處理-自定義shader 掃光效果

先上效果吧

shader來源於

https://www.cnblogs.com/eco-just/p/11667713.html ,實現了自定義shader,那麼就可以將很多網站上的效果搬過來用了

 

源代碼:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="renderer" content="webkit|ie-comp|ie-stand">
    <meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
    <title>OutlinePass</title>
    <style>
        #box{
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
        }
    </style>
</head>
<body>
<div class="ys-absolute-container" id="box" style="overflow: hidden"></div>

</body>

<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>
    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('#B4D3BA')
        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()




    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)


    const box = new THREE.Mesh(
        new THREE.BoxGeometry(1,1,1),
        new THREE.MeshBasicMaterial({color:'red'}))
    scene.add(box)
    //座標軸輔助
    var axes = new THREE.AxesHelper(10); //紅x 綠y 藍z
    scene.add(axes);
    box.position.set(0,0,0)

    let SweepingLightShader = {
        uniforms: {
            "tDiffuse": {type: "t", value: 0.0},
            "time":{type: "f", value: 1.0}
        },
        vertexShader:`
        varying vec2 vUv;
        varying vec3 iPosition;
        void main(){
            vUv = uv;
            iPosition = position;
            gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
        }
    `,
        fragmentShader:`
        uniform float time;
        uniform sampler2D tDiffuse;
        varying vec2 vUv;
        varying vec3 iPosition;
        void main(){
            vec4 texel = texture2D(tDiffuse, vUv);
            float x = iPosition.x;
            float lighty = x*1.2 + time;
            float alpha = abs(iPosition.y - lighty);
            if(alpha < 0.1){
                float a = 1.0 -  alpha / 0.1;
                float enda = smoothstep(0.0,1.0,a) + 0.3;
                gl_FragColor = texel * enda;
            }else{
                gl_FragColor = texel * 0.3;
            }


        }
    `
    };

    // setup effects
    var renderPass = new THREE.RenderPass(scene, camera);
    var customGrayScale = new THREE.ShaderPass(SweepingLightShader);
    customGrayScale.needsUpdate=true
    window.customGrayScale=customGrayScale
    var effectCopy = new THREE.ShaderPass(THREE.CopyShader);
    effectCopy.renderToScreen = true;


    var composer = new THREE.EffectComposer(renderer);
    composer.addPass(renderPass);
    composer.addPass(customGrayScale);

    composer.addPass(effectCopy);
   var type='add'
    function render() {
        var time =customGrayScale.uniforms.time.value;
        if(time > 2.0){
            type = 'reduce'
        }else if(time < -2.0){
            type = 'add';
        }
        if(type =='add'){
            customGrayScale.uniforms.time.value += 0.01;
        }else{
            customGrayScale.uniforms.time.value -= 0.01;
        }
        // console.log(THREE.SweepingLightShader.uniforms[ 'time' ].value)
        composer.render()
        controls.update(clock.getDelta())
        requestAnimationFrame(render)

    }
    render()
</script>
<!--此腳本與案例無關 可忽略-->
</html>

 

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