three打造一个三维污染动画效果代码

three打造一个三维污染动画效果代码
<html lang="en">
<head>

    <meta charset="UTF-8">





    <style>
        canvas {
            display: block;
            width: 100%;
            height: 100vh;
            cursor: -webkit-grab;
            cursor: grab;
        }
    </style>



</head>

<body>
    <canvas width="917" height="668" style="display: block;"></canvas>




    <script type="module">
        import * as $ from '//cdn.skypack.dev/three@0.125.0/build/three.module.js?min';
        import {
            OrbitControls
        } from '//cdn.skypack.dev/three@0.125.0/examples/jsm/controls/OrbitControls.js?min';
        import {
            EffectComposer
        } from '//cdn.skypack.dev/three@0.125.0/examples/jsm/postprocessing/EffectComposer.js?min';
        import {
            RenderPass
        } from '//cdn.skypack.dev/three@0.125.0/examples/jsm/postprocessing/RenderPass.js?min';
        import {
            UnrealBloomPass
        } from '//cdn.skypack.dev/three@0.125.0/examples/jsm/postprocessing/UnrealBloomPass.js?min';

        //// Boot

        const renderer = new $.WebGLRenderer({});
        const scene = new $.Scene();
        const camera = new $.PerspectiveCamera(75, 2, 20, 12000);
        const controls = new OrbitControls(camera, renderer.domElement);
        window.addEventListener('resize', () => {
            const {
                clientWidth, clientHeight
            } = renderer.domElement;
            renderer.setSize(clientWidth, clientHeight, false);
            renderer.setPixelRatio(window.devicePixelRatio);
            camera.aspect = clientWidth / clientHeight;
            camera.updateProjectionMatrix();
        });
        document.body.prepend(renderer.domElement);
        window.dispatchEvent(new Event('resize'));

        //// Inputs

        const size = 5000;
        const segs = 500;
        const disp = 500;

        //// Setup

        camera.position.set(1000, 1200, 1200);
        controls.autoRotate = true;
        controls.enableDamping = true;
        controls.maxPolarAngle = Math.PI / 2.9;

        const light0 = new $.DirectionalLight('white', 1);
        light0.position.set(0, 1, 0);
        scene.add(light0);

        const tex0 = new $.TextureLoader().load('//repo.bfw.wiki/bfwrepo/image/6032e33d4f494.png');

        const mesh0 = new $.Mesh(
            new $.PlaneBufferGeometry(size, size, segs, segs).rotateX(-0.5 * Math.PI),
            f());

        scene.add(mesh0);
        const mesh1 = new $.Mesh(
            new $.PlaneBufferGeometry(size, size, segs >> 1, segs >> 1).rotateX(-0.5 * Math.PI),
            f({
                wireframe: true, color: new $.Color('#333')
            }));

        scene.add(mesh1);

        //// Make Material

        function f( {
            wireframe, color
        } = {}) {
            const mat = new $.ShaderMaterial({
                extensions: {
                    derivatives: true // wgl 1
                },
                lights: true,
                wireframe: Boolean(wireframe),
                uniforms: $.UniformsUtils.merge([
                    $.ShaderLib.standard.uniforms, {
                        time: {
                            value: 0
                        },
                        displacementScale: {
                            value: disp
                        },
                        wireframe: {
                            value: wireframe || false
                        },
                        color: {
                            value: color || new $.Color()
                        },
                        roughness: {
                            value: 1
                        },
                        metalness: {
                            value: 0
                        }
                    }]),


                vertexShader: `
                varying vec3 vWorldPos;
                ` + $.ShaderLib.standard.vertexShader.replace("#include <worldpos_vertex>", `
                    // #if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )
                    vec4 worldPosition = vec4( transformed, 1.0 );
                    #ifdef USE_INSTANCING
                    worldPosition = instanceMatrix * worldPosition;
                    #endif
                    worldPosition = modelMatrix * worldPosition;
                    vWorldPos = worldPosition.xyz;
                    // #endif
                    `).replace("#include <displacementmap_vertex>", `
                    #ifdef USE_DISPLACEMENTMAP
                    transformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );
                    // form a bowl
                    float yOffset = length( position.xz ) / ${size.toFixed(1)};
                    yOffset = pow(sin(yOffset * 2.0), 2.0);
                    transformed.y += yOffset * ${size.toFixed(1)} / 3.0;
                    #endif
                    `),
                fragmentShader: `
                varying vec3 vWorldPos;
                uniform float time;
                uniform bool wireframe;
                uniform vec3 color;
                ` + $.ShaderLib.standard.fragmentShader.replace(
                    "gl_FragColor = vec4( outgoingLight, diffuseColor.a );", `
                    gl_FragColor = vec4( outgoingLight, diffuseColor.a );
                    float ths = ${size.toFixed(1)} * pow(sin(time * 0.00015), 2.0);
                    if ( !wireframe ) {
                    if ( length( vWorldPos ) > ths ) {
                    discard;
                    }
                    } else {
                    gl_FragColor = vec4( color, 1.0 );
                    if ( length( vWorldPos ) < ths ) {
                    discard;
                    }
                    }
                    `)
            });

            mat.map = mat.uniforms.map.value = tex0;
            mat.displacementMap = mat.uniforms.displacementMap.value = tex0;
            return mat;
        }

        //// Render

        const res = new $.Vector2();
        window.addEventListener('resize', () => {
            renderer.getDrawingBufferSize(res);
            fx.setSize(res.width, res.height);
        });
        const fx = new EffectComposer(renderer);
        fx.addPass(new RenderPass(scene, camera));
        fx.addPass(new UnrealBloomPass(res, 0.5, 0.5, 0.3));

        renderer.setAnimationLoop(t => {
            fx.render();
            mesh0.material.uniforms.time.value = t;
            mesh1.material.uniforms.time.value = t;
            controls.update();
        });

    </script>







</body>
</html>

网友评论0