美文网首页
通过高级几何体创建粒子

通过高级几何体创建粒子

作者: Codifier | 来源:发表于2019-11-15 16:50 被阅读0次
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Particle</title>
    <script src="../../three-part/threejs/three.js"></script>
    <script src="../../three-part/utils/stats.min.js"></script>
    <script src="../../three-part/utils/dat.gui.min.js"></script>
    <script src="../controls/TrackballControls.js"></script>
    <script src="../util/util.js"></script>
    <style>
        body {
            margin: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>
<div id="container"></div>
<script type="text/javascript">
    init();
    function init() {
        // show FPS
        let stats = initStats();
        // resize
        window.addEventListener('resize', onResize, false);

        let scene = new THREE.Scene();
        let camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.x = -30;
        camera.position.y = 40;
        camera.position.z = 50;
        camera.lookAt(scene.position);

        let renderer = new THREE.WebGLRenderer();
        renderer.setClearColor(new THREE.Color(0x000000));
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.shadowMap.enabled = true;
        document.getElementById("container").appendChild(renderer.domElement);

        // init trackball control
        let trackballControls = initTrackballControls(camera, renderer);
        let clock = new THREE.Clock();

        let knot;

        // attributes which can be modified in GUI
        const controls = {
            "radius" : 13,
            "tube" : 1.7,
            "radialSegments" : 156,
            "tubularSegments" : 12,
            "p" : 5,
            "q" : 4,
            "asParticles" : false,
            "rotate" : false,
            "redraw" : function(){
                if(knot){
                    scene.remove(knot);
                }
                let geometry = new THREE.TorusKnotGeometry(controls.radius, controls.tube, Math.round(controls.radialSegments), Math.round(controls.tubularSegments), Math.round(controls.p), Math.round(controls.q));

                knot = createPoints(geometry);
                if (controls.asParticles) {
                    knot = createPoints(geometry);
                } else {
                    knot = new THREE.Mesh(geometry, new THREE.MeshNormalMaterial());
                }
                scene.add(knot);
            }
        };
        // init GUI
        initGUI();

        controls.redraw();

        renderScene();

        function initGUI(){
            let gui = new dat.GUI();
            gui.add(controls, 'radius', 0, 40).onChange(controls.redraw);
            gui.add(controls, 'tube', 0, 40).onChange(controls.redraw);
            gui.add(controls, 'radialSegments', 0, 400).step(1).onChange(controls.redraw);
            gui.add(controls, 'tubularSegments', 1, 20).step(1).onChange(controls.redraw);
            gui.add(controls, 'p', 1, 10).step(1).onChange(controls.redraw);
            gui.add(controls, 'q', 1, 15).step(1).onChange(controls.redraw);
            gui.add(controls, 'asParticles').onChange(controls.redraw);
            gui.add(controls, 'rotate').onChange(controls.redraw);
        }

        function generateSprite() {
            let canvas = document.createElement('canvas');
            canvas.width = 16;
            canvas.height = 16;

            let context = canvas.getContext('2d');
            let gradient = context.createRadialGradient(canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2);
            gradient.addColorStop(0, 'rgba(255,255,255,1)');
            gradient.addColorStop(0.2, 'rgba(0,255,255,1)');
            gradient.addColorStop(0.4, 'rgba(0,0,64,1)');
            gradient.addColorStop(1, 'rgba(0,0,0,1)');

            context.fillStyle = gradient;
            context.fillRect(0, 0, canvas.width, canvas.height);
            let texture = new THREE.Texture(canvas);
            texture.needsUpdate = true;
            return texture;
        }

        function createPoints(geom) {
            let material = new THREE.PointsMaterial({
                color: 0xffffff,
                size: 3,
                transparent: true,
                blending: THREE.AdditiveBlending,
                map: generateSprite(),
                depthWrite: false
            });
            return new THREE.Points(geom, material);
        }

        function onResize() {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        }

        function renderScene(){
            trackballControls.update(clock.getDelta());
            stats.update();
            if (controls.rotate) {
                knot.rotation.y += 0.01;
            }
            requestAnimationFrame(renderScene);
            renderer.render(scene, camera);
        }
    }
</script>
</body>
</html>

运行结果:


相关文章

网友评论

      本文标题:通过高级几何体创建粒子

      本文链接:https://www.haomeiwen.com/subject/adusictx.html