three.js和五彩纸屑

时间:2013-04-07 01:41:51

标签: vector three.js

我正在尝试制作五彩纸屑爆炸,我在预测五彩纸屑方面存在问题。我的想法是向各个方向向外快速爆炸(1秒),然后五彩纸屑漂浮在地面上。我确信我的数学是错的,因为我没有让它扩展。

我已经使用了三个.js代码并制作了一些mod:

http://givememypatientinfo.com/ParticleBlocksConfetti.html

欢迎任何建议。我是three.js的菜鸟......但是喜欢图书馆!

代码:     

        var container, stats;
        var camera, controls, scene, projector, renderer;
        var objects = [], plane;
        var vel = 1;
        var vel2 = 0.01;
        var accel = .3;
        var accel2 = -.9;
        var force = 1;

        var frame = 0;

        var mouse = new THREE.Vector2(),
        offset = new THREE.Vector3(),
        INTERSECTED, SELECTED;

        init();
        animate();

        function init() {

            container = document.createElement( 'div' );
            document.body.appendChild( container );

            camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
            camera.position.z = 1000;

            /*//controls = new THREE.TrackballControls( camera );
            controls.rotateSpeed = 1.0;
            controls.zoomSpeed = 1.2;
            controls.panSpeed = 0.8;
            controls.noZoom = false;
            controls.noPan = false;
            controls.staticMoving = true;
            controls.dynamicDampingFactor = 0.3;*/

            scene = new THREE.Scene();

            scene.add( new THREE.AmbientLight( 0x505050 ) );

            var light = new THREE.SpotLight( 0xffffff, 1.5 );
            light.position.set( 0, 500, 2000 );
            light.castShadow = true;

            light.shadowCameraNear = 200;
            light.shadowCameraFar = camera.far;
            light.shadowCameraFov = 50;

            light.shadowBias = -0.00022;
            light.shadowDarkness = 0.5;

            light.shadowMapWidth = 2048;
            light.shadowMapHeight = 2048;

            scene.add( light );

            var geometry = new THREE.CubeGeometry( 40, 40, 40 );

            //make confetti for particle system 
            for ( var i = 0; i < 100; i ++ ) {

                var object = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: Math.random() * 0xffffff } ) );

                //object.material.ambient = object.material.color;


                /*object.position.x = Math.random() * 500 - 100;
                object.position.y = Math.random() * 500 - 100;
                object.position.z = 300;*/

                object.position.x = Math.random() * 100 - 100;
                object.position.y = Math.random() * 100 - 100;
                object.position.z = 300;

                object.rotation.x = Math.random() * 2 * Math.PI;
                object.rotation.y = Math.random() * 2 * Math.PI;
                object.rotation.z = Math.random() * 2 * Math.PI;

                object.scale.x = .1;
                object.scale.y = Math.random() * .8 + .1;
                object.scale.z = Math.random() * .5 + .1;

                object.castShadow = false;
                object.receiveShadow = true;

                scene.add( object );

                objects.push( object );
            }

            plane = new THREE.Mesh( new THREE.PlaneGeometry( 2000, 2000, 8, 8 ), new THREE.MeshBasicMaterial( { color: 0x000000, opacity: 0.25, transparent: true, wireframe: true } ) );
            plane.visible = false;
            scene.add( plane );

            projector = new THREE.Projector();

            renderer = new THREE.WebGLRenderer( { antialias: true } );
            renderer.sortObjects = false;
            renderer.setSize( window.innerWidth, window.innerHeight );

            renderer.shadowMapEnabled = true;
            renderer.shadowMapType = THREE.PCFShadowMap;

            container.appendChild( renderer.domElement );

            var info = document.createElement( 'div' );
            info.style.position = 'absolute';
            info.style.top = '10px';
            info.style.width = '100%';
            info.style.textAlign = 'center';
            info.innerHTML = '<a href="http://threejs.org" target="_blank">three.js</a> webgl - draggable cubes';
            container.appendChild( info );


        }

    function animate_particles(frame) {
    //will update each particle     
  if (frame < 50){
      var pCount = objects.length-1;    

    if (frame < 40){
         vel += accel*2;
    }else {
         vel = vel + accel2;
    }

    while(pCount > -1) {
        if (frame < 30){
            objects[pCount].position.y += vel;
        }else{
             objects[pCount].position.y -= vel;
        }


        //objects[pCount].rotation.x += Math.random()*.7;
        //objects[pCount].rotation.z += Math.random()*.01;
        //objects[pCount].rotation.y += Math.random()*.01;

        pCount--;

        }
    }
}


        function animate() {

            requestAnimationFrame( animate );
            animate_particles(frame);
            render();
            //stats.update();

        }

        function render() {


            renderer.render( scene, camera );
            frame++;
        }


    </script>

2 个答案:

答案 0 :(得分:0)

这可能是你想要的结果。我稍微修改了你的代码并评论了这些变化。基本上我只是添加了一个随机方向向量,对其进行归一化并向粒子添加随机速度。在animate_particles函数中,我以随机速度沿着随机方向向量移动五彩纸屑。

    var container, stats;
    var camera, controls, scene, projector, renderer;
    var objects = [], plane;
    var vel = 1;
    var vel2 = 0.01;
    var accel = .3;
    var accel2 = -.9;
    var force = 1;

    var frame = 0;

    var mouse = new THREE.Vector2(),
    offset = new THREE.Vector3(),
    INTERSECTED, SELECTED;

    init();
    animate();

    function init() {

        container = document.createElement( 'div' );
        document.body.appendChild( container );

        camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
        camera.position.z = 1000;

        /*//controls = new THREE.TrackballControls( camera );
        controls.rotateSpeed = 1.0;
        controls.zoomSpeed = 1.2;
        controls.panSpeed = 0.8;
        controls.noZoom = false;
        controls.noPan = false;
        controls.staticMoving = true;
        controls.dynamicDampingFactor = 0.3;*/

        scene = new THREE.Scene();

        scene.add( new THREE.AmbientLight( 0x505050 ) );

        var light = new THREE.SpotLight( 0xffffff, 1.5 );
        light.position.set( 0, 500, 2000 );
        light.castShadow = true;

        light.shadowCameraNear = 200;
        light.shadowCameraFar = camera.far;
        light.shadowCameraFov = 50;

        light.shadowBias = -0.00022;
        light.shadowDarkness = 0.5;

        light.shadowMapWidth = 2048;
        light.shadowMapHeight = 2048;

        scene.add( light );

        var geometry = new THREE.CubeGeometry( 40, 40, 40 );

        //make confetti for particle system 
        for ( var i = 0; i < 100; i ++ ) {

            var object = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: Math.random() * 0xffffff } ) );

            //object.material.ambient = object.material.color;


            /*object.position.x = Math.random() * 500 - 100;
            object.position.y = Math.random() * 500 - 100;
            object.position.z = 300;*/

            object.position.x = Math.random() * 100 - 100;
            object.position.y = Math.random() * 100 - 100;
            object.position.z = 300;

            object.rotation.x = Math.random() * 2 * Math.PI;
            object.rotation.y = Math.random() * 2 * Math.PI;
            object.rotation.z = Math.random() * 2 * Math.PI;

            object.scale.x = .1;
            object.scale.y = Math.random() * .8 + .1;
            object.scale.z = Math.random() * .5 + .1;

            // give every "particle" a random expanding direction vector and normalize it to receive a length of 1.
            object.directionVector = new THREE.Vector3( Math.random() - .5, Math.random() - .5, Math.random() - .5 )
            object.directionVector.normalize();

            // and a random expanding Speed
            object.expandingSpeed = Math.random() * 100;

            object.castShadow = false;
            object.receiveShadow = true;

            scene.add( object );

            objects.push( object );
        }

        plane = new THREE.Mesh( new THREE.PlaneGeometry( 2000, 2000, 8, 8 ), new THREE.MeshBasicMaterial( { color: 0x000000, opacity: 0.25, transparent: true, wireframe: true } ) );
        plane.visible = false;
        scene.add( plane );

        projector = new THREE.Projector();

        renderer = new THREE.WebGLRenderer( { antialias: true } );
        renderer.sortObjects = false;
        renderer.setSize( window.innerWidth, window.innerHeight );

        renderer.shadowMapEnabled = true;
        renderer.shadowMapType = THREE.PCFShadowMap;

        container.appendChild( renderer.domElement );

        var info = document.createElement( 'div' );
        info.style.position = 'absolute';
        info.style.top = '10px';
        info.style.width = '100%';
        info.style.textAlign = 'center';
        info.innerHTML = '<a href="http://threejs.org" target="_blank">three.js</a> webgl - draggable cubes';
        container.appendChild( info );


    }

    function animate_particles(frame) {
    //will update each particle     
    if (frame < 50){
      var pCount = objects.length-1;    

    if (frame < 40){
         vel += accel*2;
    }else {
         vel = vel + accel2;
    }

    while(pCount > -1) {
        if (frame < 30){
            // commented that out. not sure why you put it there.
            //objects[pCount].position.y += vel;

            // move objects along random direction vector at the individual random speed. 
            objects[pCount].position.x += objects[pCount].directionVector.x * objects[pCount].expandingSpeed;
            objects[pCount].position.y += objects[pCount].directionVector.y * objects[pCount].expandingSpeed;
            objects[pCount].position.z += objects[pCount].directionVector.z * objects[pCount].expandingSpeed;
        }else{
             objects[pCount].position.y -= vel;
        }


        //objects[pCount].rotation.x += Math.random()*.7;
        //objects[pCount].rotation.z += Math.random()*.01;
        //objects[pCount].rotation.y += Math.random()*.01;

        pCount--;

        }
    }
}


    function animate() {

        requestAnimationFrame( animate );
        animate_particles(frame);
        render();
        //stats.update();

    }

    function render() {


        renderer.render( scene, camera );
        frame++;
    }

答案 1 :(得分:-1)

我刚刚制作了一个用于使用THREE.js创建五彩纸屑效果的插件:https://github.com/mrgoonie/three.confetti.explosion.js

使用以下工具,事情会更容易

var confetti = new ExplosionConfetti({
    rate: 1, // percent of explosion in every tick - smaller is fewer - be careful, larger than 10 may crash your browser!
    amount: 200, // max amount particle of an explosion
    radius: 800, // max radius of an explosion
    areaWidth: 500, // width of the area 
    areaHeight: 500, // height of the area 
    fallingHeight: 500, // start exploding from Y position
    fallingSpeed: 1, // max falling speed
    colors: [0xffffff, 0xff0000, 0xffff00] // random colors
});
scene.add( confetti.object );

干杯