Three.js案例从0到1复杂的计算组合生成几何体

Posted pocean2012

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Three.js案例从0到1复杂的计算组合生成几何体相关的知识,希望对你有一定的参考价值。

1. 重构初始化,结构性更好

主程序

function init(event) 
    console.log("main js start. ")
    createScene();
    createLights();
    createSea();
   
    animate();

window.addEventListener('load', init, false);

创建场景和灯光分开

function createScene() 

    HEIGHT = window.innerHeight;
    WIDTH = window.innerWidth;

    scene = new THREE.Scene();
    aspectRatio = WIDTH / HEIGHT;
    fieldOfView = 60;
    nearPlane = 1;
    farPlane = 10000;
    camera = new THREE.PerspectiveCamera(
        fieldOfView,
        aspectRatio,
        nearPlane,
        farPlane
    );
    scene.fog = new THREE.Fog(0xf7d9aa, 100, 950);
    camera.position.x = 0;
    camera.position.z = 200;
    camera.position.y = 100;

    renderer = new THREE.WebGLRenderer( alpha: true, antialias: true );
    renderer.setSize(WIDTH, HEIGHT);
    renderer.shadowMap.enabled = true;
    container = document.getElementById('world');
    container.appendChild(renderer.domElement);

    window.addEventListener('resize', handleWindowResize, false);


// LIGHTS

var ambientLight, hemisphereLight, shadowLight;

function createLights() 

    hemisphereLight = new THREE.HemisphereLight(0xaaaaaa, 0x000000, .9)
    shadowLight = new THREE.DirectionalLight(0xffffff, .9);
    shadowLight.position.set(150, 350, 350);
    shadowLight.castShadow = true;
    shadowLight.shadow.camera.left = -400;
    shadowLight.shadow.camera.right = 400;
    shadowLight.shadow.camera.top = 400;
    shadowLight.shadow.camera.bottom = -400;
    shadowLight.shadow.camera.near = 1;
    shadowLight.shadow.camera.far = 1000;
    shadowLight.shadow.mapSize.width = 2048;
    shadowLight.shadow.mapSize.height = 2048;

    scene.add(hemisphereLight);
    scene.add(shadowLight);

加入了屏幕调整自适应


function handleWindowResize() 
    HEIGHT = window.innerHeight;
    WIDTH = window.innerWidth;
    renderer.setSize(WIDTH, HEIGHT);
    camera.aspect = WIDTH / HEIGHT;
    camera.updateProjectionMatrix();

sea和plane的创建实例

   // 创建实例化sea函数
function createSea() 
    sea = new Sea();
    sea.mesh.position.y = -600;
    scene.add(sea.mesh);

动画效果


function animate() 
    requestAnimationFrame(animate);
    //海浪效果
    sea.mesh.rotation.z += .005;
 
    renderer.render(scene, camera);


;

完成效果

2. 建立复杂模型,用模型组合成飞机,并实例化

// 创建飞机模型
AirPlane = function() 
    this.mesh = new THREE.Object3D();
    // 创建机舱
    var geomCockpit = new THREE.BoxGeometry(60, 50, 50, 1, 1, 1);
    var matCockpit = new THREE.MeshPhongMaterial(
        color: Colors.red,
        shading: THREE.FlatShading
    );
    var cockpit = new THREE.Mesh(geomCockpit, matCockpit);
    cockpit.castShadow = true;
    cockpit.receiveShadow = true;
    this.mesh.add(cockpit);

    // 创建引擎
    var geomEngine = new THREE.BoxGeometry(20, 50, 50, 1, 1, 1);
    var matEngine = new THREE.MeshPhongMaterial(
        color: Colors.white,
        shading: THREE.FlatShading
    );
    var engine = new THREE.Mesh(geomEngine, matEngine);
    engine.position.x = 40;
    engine.castShadow = true;
    engine.receiveShadow = true;
    this.mesh.add(engine);
    // 创建机尾
    var geomTailPlane = new THREE.BoxGeometry(15, 20, 5, 1, 1, 1);
    var matTailPlane = new THREE.MeshPhongMaterial(
        color: Colors.red,
        shading: THREE.FlatShading
    );
    var tailPlane = new THREE.Mesh(geomTailPlane, matTailPlane);
    tailPlane.position.set(-35, 25, 0);
    tailPlane.castShadow = true;
    tailPlane.receiveShadow = true;
    this.mesh.add(tailPlane);
    // 创建机翼
    var geomSideWing = new THREE.BoxGeometry(40, 8, 150, 1, 1, 1);
    var matSideWing = new THREE.MeshPhongMaterial(
        color: Colors.red,
        shading: THREE.FlatShading
    );
    var sideWing = new THREE.Mesh(geomSideWing, matSideWing);
    sideWing.castShadow = true;
    sideWing.receiveShadow = true;
    this.mesh.add(sideWing);

    // 创建螺旋桨
    var geomPropeller = new THREE.BoxGeometry(20, 10, 10, 1, 1, 1);
    var matPropeller = new THREE.MeshPhongMaterial(
        color: Colors.brown,
        shading: THREE.FlatShading
    );
    this.propeller = new THREE.Mesh(geomPropeller, matPropeller);
    this.propeller.castShadow = true;
    this.propeller.receiveShadow = true;

    // 创建螺旋桨的桨叶
    var geomBlade = new THREE.BoxGeometry(1, 100, 20, 1, 1, 1);
    var matBlade = new THREE.MeshPhongMaterial(
        color: Colors.brownDark,
        shading: THREE.FlatShading
    );

    // 创建机翼
    var blade = new THREE.Mesh(geomBlade, matBlade);
    blade.position.set(8, 0, 0);
    blade.castShadow = true;
    blade.receiveShadow = true;
    this.propeller.add(blade);
    this.propeller.position.set(50, 0, 0);
    this.mesh.add(this.propeller);
;
// 实例化飞机函数

function createPlane() 
    airplane = new AirPlane();
    airplane.mesh.scale.set(.25, .25, .25);
    airplane.mesh.position.y = 100;
    scene.add(airplane.mesh);

主场景添加飞机模型,动画添加螺旋桨转动效果

function init(event) 
    console.log("main js start. ")
    createScene();
    createLights();
    createSea();
    createPlane();
    animate();

 animate添加

 airplane.propeller.rotation.x += 0.3;

运行效果:

 

 3. 由立方体组合成云朵,云朵变化组成天空效果

用立方体组合创建云朵,用到了随机生成


// 创建云
Cloud = function() 
        // 创建一个空的容器放置不同形状的云
        this.mesh = new THREE.Object3D();
        this.mesh.name = "cloud";
        // 创建一个正方体
        // 这个形状会被复制创建云
        var geom = new THREE.BoxGeometry(20, 20, 20);
        // 创建材质;一个简单的白色材质就可以达到效果
        var mat = new THREE.MeshPhongMaterial(
            color: Colors.white,
        );
        // 随机多次复制几何体
        var nBlocs = 3 + Math.floor(Math.random() * 3);
        for (var i = 0; i < nBlocs; i++) 
            // 通过复制几何体创建网格
            var m = new THREE.Mesh(geom.clone(), mat);
            // 随机设置每个正方体的位置和旋转角度
            m.position.x = i * 15;
            m.position.y = Math.random() * 10;
            m.position.z = Math.random() * 10;
            m.rotation.z = Math.random() * Math.PI * 2;
            m.rotation.y = Math.random() * Math.PI * 2;
            // 随机设置正方体的大小
            var s = .1 + Math.random() * .9;
            m.scale.set(s, s, s);
            // 允许每个正方体生成投影和接收阴影
            m.castShadow = true;
            m.receiveShadow = true;
            // 将正方体添加至开始时我们创建的容器中
            this.mesh.add(m);

        
    
   

创建天空

   // 创建天空


Sky = function() 
    this.mesh = new THREE.Object3D();
    this.nClouds = 20;
    this.clouds = [];
    var stepAngle = Math.PI * 2 / this.nClouds;
    for (var i = 0; i < this.nClouds; i++) 
        var c = new Cloud();
        this.clouds.push(c);
        var a = stepAngle * i;
        var h = 750 + Math.random() * 200;
        c.mesh.position.y = Math.sin(a) * h;
        c.mesh.position.x = Math.cos(a) * h;
        c.mesh.position.z = -400 - Math.random() * 400;
        c.mesh.rotation.z = a + Math.PI / 2;
        var s = 1 + Math.random() * 2;
        c.mesh.scale.set(s, s, s);
        this.mesh.add(c.mesh);
    



// 创建实例
function createSky() 
    sky = new Sky();
    sky.mesh.position.y = -600;
    scene.add(sky.mesh);

形成动画效果

//天空效果
    sky.mesh.rotation.z += .01;

动画效果

 

 完整例子下载

three.js从0到1实操案例,完整目录,直接可用-Javascript文档类资源-CSDN下载

 

以上是关于Three.js案例从0到1复杂的计算组合生成几何体的主要内容,如果未能解决你的问题,请参考以下文章

three.js 几何体-组合网格

Three.js开发指南---创建,加载高级网格和几何体(第八章)

我可以跳过正常语法并使用three.js中的几何缓冲区来提高性能吗?

Three.js案例从0到1对象跟随鼠标动起来

Three.js案例从0到1建立应用架构

Three.js案例从0到1更酷的对象--变形,缩放