Threejs实现3D飞行器交互场景

最近在b站上面看到up主:gamemcu的3D作品,着实让人感到非常震撼,作品中的SU7模型,利用的是Blender进行建模,利用了webGL的技术进行开发。本次编写效果如下:

9145a9aa973549c9a0a0036cc4288f76.gif

初识Three

gamemcu大佬的作品

su7xiaomi su7 made by gamemcuicon-default.png?t=N7T8https://gamemcu.com/su7/

官网学习

利用了一天的时间,到官方网站(Three.js – JavaScript 3D Library)看了documentation、examples和editor。到b站中看了视频,学习了基础的知识。

首页也有推荐一些教学视频,比如resource中提到的Three.js Journery。也是up主:gamemcu推荐去看的,在b站中可以找到免费的教学视频

Three.js Journey(新版-双语字幕)_哔哩哔哩_bilibili
873e82716915448eaab13401f84e090d.png

源码学习

Three.js是开源的,可以把源码下载来看,官网里的所有examples在源码里面都有demo。

984a978b6dc44be9a4f96de67cce3798.png

docs:是官网的文档,网络卡的时候,可以用本地的看。

examples:放的是所有的demo,可以学习到官方的编码方式

editor:是模型编辑器,可视化编辑模型,提高在编写代码时的效率。

402396b5d1fb40a28a6588ccceba6f53.png

初识Blender

大概了解部分Three.js知识后,还需要了解一下建模的软件-Blender,这款软件功能强大,而且是开源的。当需要给模型添加一些动画效果,可能就要对模型进行修改。就可以用Blender对模型进行建模处理了。如果想更加深入,可以在Blender建好模型,添加好动画,然后直接Three.js导入Animation。

982778d3a829433b9921304e7a4cace2.png

开发作品

经过这几天的基础学习和准备,现在可以着手开发了。

搭建场景

8e0669a1fb374eae8f9594c8e1df6647.png

首先是搭建基本场景

function init() {
  // 初始化场景
    const initScene = () =>{
        scene = new THREE.Scene();
        scene.background = new THREE.Color( 0xa0a0a0 );
        scene.fog = new THREE.Fog( 0xa0a0a0, 4, 20 );
    }

    // 初始化相机
    const initCamera = () =>{
        camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 100 );
        camera.position.set( 10, 20, 10 );
    }

    // 初始化半球光
    const hemiLight = () =>{
        const hemiLight = new THREE.HemisphereLight( 0xffffff, 0x444444, 3 );
        hemiLight.position.set( 0, 20, 0 );
        scene.add( hemiLight );
    }

    // 初始化平行光
    const initLight = () =>{
        dLight = new THREE.DirectionalLight( 0xffffff, 3 );
        dLight.position.set( 0, 20, 10 );
        dLight.castShadow = true;
        dLight.shadow.camera.top = 2;
        dLight.shadow.camera.bottom = - 2;
        dLight.shadow.camera.left = - 2;
        dLight.shadow.camera.right = 2;
        scene.add( dLight );

    }

    // 初始化地面
    const initGround = () =>{
        const ground = new THREE.Mesh( new THREE.PlaneGeometry( 40, 40 ), new
        THREE.MeshPhongMaterial( { color: 0xbbbbbb, depthWrite: false } ) );
        ground.rotation.x = - Math.PI / 2;
        ground.receiveShadow = true;
        scene.add( ground );
    }

    // 初始化地面网格
    const initGrid = () =>{
        const grid = new THREE.GridHelper( 40, 20, 0x000000, 0x000000 );
        grid.material.opacity = 0.2;
        grid.material.transparent = true;
        scene.add( grid );
    }

    // 初始化场景辅助标线
    const initAxesHelper = () =>{
        let axesHelper = new THREE.AxesHelper( 3 );
        scene.add( axesHelper );
    }
}

导入模型

这里提前导入了两个模型,同时利用回调,添加了加载模型过程的progress。


// 模型1
function loadStaticScene(){
    return new Promise(resolve => {
        let loader = new GLTFLoader();
        const url = "../models/gltf/WM161_zhankai_1k.glb"
        loader.load(url, (gltf) => {
            gltf.scene.position.set(0,27,0)
            gltf.scene.scale.set(15, 15, 15);
            resolve(gltf);
        },(event) =>{
            const {loaded,total} = event
            handleLoadProgress({url,loaded,total})
        });
    })
}

// 模型2
function loadStaticScene_v11(){
    return new Promise(resolve => {
        let loader = new GLTFLoader();
        const url = "../models/gltf/wm161_v11_zhedie_1k.glb"
        loader.load(url, (gltf) => {
            gltf.scene.position.set(0,-27,0)
            gltf.scene.scale.set(15, 15, 15);
            resolve(gltf);
        },(event) =>{
            const {loaded,total} = event
            handleLoadProgress({url,loaded,total})
        });
    })
}

// 用于加载
function handleLoadProgress({url, loaded, total}){
    const percentage = ((loaded / total) * 100).toFixed(2);
    if (/.*\.(blob|glb)$/i.test(url)) {
        updateLoadingProgress(`加载场景模型:${percentage}%`);
    }

}

function updateLoadingProgress(loading_text){
    progress && (progress.textContent = loading_text);
}

加载模型

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值