【问题标题】:How to load animated 3D model on webpage using THREE.js如何使用 THREE.js 在网页上加载动画 3D 模型
【发布时间】:2021-07-22 12:02:33
【问题描述】:

我想问一下如何使用 THREE.js 在网页上加载动画 3D 模型?目前,我已经设法在网页上使用 THREE.js 加载了我自己的 3D 模型(它名为“aaa.gltf”),具有自动旋转功能,并且能够单击以使用 orbitcontrol.js 在模型中移动。但是,我的模型是静态的。然后,我尝试加载我的另一个 3D 模型,它是动画 3D 模型,它命名为“bbb.glb”,但结果根本无法显示。

这里是html文件:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <link rel="stylesheet" href="./style.css" />
    <title>Document</title>
  </head>
  <body>
    <div class="scene"></div>
    <script src="./three.min.js"></script>
    <script src="./GLTFLoader.js"></script>
    <script src="./OrbitControls.js"></script>
    <script src="./app.js"></script>
  </body>
</html>

这里是js文件:

//Variables for setup

let container;
let camera;
let renderer;
let scene;
let house;
let mixer;

function init() {
  container = document.querySelector(".scene");

  //Create scene
  scene = new THREE.Scene();

  const fov = 35;
  const aspect = container.clientWidth / container.clientHeight;
  const near = 0.1;
  const far = 1000;

  //Camera setup
  camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  camera.position.set(0, 0, 100);

  const ambient = new THREE.AmbientLight(0x404040, 2);
  scene.add(ambient);

  const light = new THREE.DirectionalLight(0xffffff, 2);
  light.position.set(50, 50, 100);
  scene.add(light);
  
  
  // controls.addEventListener('change', renderer);
        
        
  //Renderer
  renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
  renderer.setSize(container.clientWidth, container.clientHeight);
  renderer.setPixelRatio(window.devicePixelRatio);
  
  controls = new THREE.OrbitControls(camera, renderer.domElement);

  container.appendChild(renderer.domElement);

  const clock = new THREE.Clock();

  //Load Model
  let loader = new THREE.GLTFLoader();
  loader.load("./house/bbb.glb", function(gltf) {
    scene.add(gltf.scene);
    house = gltf.scene.children[0];

    mixer = new THREE.AnimationMixer( house );
    mixer.clipAction(gltf.animations[0]).play();

    animate();
  });
}

function animate() {
  requestAnimationFrame(animate);

  const delta = clock.getDelta();
  mixer.update( delta );

  house.rotation.z += 0.005;
  renderer.render(scene, camera);
}

init();

function onWindowResize() {
  camera.aspect = container.clientWidth / container.clientHeight;
  camera.updateProjectionMatrix();

  renderer.setSize(container.clientWidth, container.clientHeight);
}

window.addEventListener("resize", onWindowResize);

这是css文件:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: sans-serif;
  overflow: hidden;
  background: url("https://wallpaperaccess.com/full/1155041.jpg");
}

.scene,
canvas {
  position: absolute;
  width: 100%;
  height: 100%;
}

我只在js文件的第46行将3D模型的来源从'aaa.gltf'改为'bbb.glb':

从这里

  loader.load("./house/aaa.gltf", function(gltf) {

进入这个

  loader.load("./house/bbb.glb", function(gltf) {

这是“aaa.gltf”的附件: https://drive.google.com/file/d/1RCO8iSvYwTZdcTC55EVzJ0rBLl6aZy9L/view?usp=sharing

这里是“bbb.glb”的附件: https://drive.google.com/file/d/1fzk7AZl2VHwTvZm0Gl0m-oyaIZUmHyeB/view?usp=sharing

有人知道怎么解决吗?提前致谢!

【问题讨论】:

    标签: javascript html css three.js 3d


    【解决方案1】:

    您的 3D 模型动画代码非常不完整,基本上您只是加载它而不播放嵌入的动画。为此,您需要创建一个AnimationMixer,选择要播放的剪辑动作(动画),然后更新动画。

    除此之外,模型是用 DRACO 编码的,所以我也添加了它。更多更改,如THREE.sRGBEncoding 以获得模型的真实颜色,并减少照明,因为它太强烈了......

    编辑:整页代码

     
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>Document</title>
        <style>
            * {
                margin: 0;
                padding: 0;
                box-sizing: border-box;
            }
    
            body {
                font-family: sans-serif;
                overflow: hidden;
            }
    
            .scene,
            canvas {
                position: absolute;
                width: 100%;
                height: 100%;
            }
        </style>
    
    </head>
    <body>
        <div class="scene"></div>
        <script src="https://threejs.org/build/three.min.js"></script>
        <script src="https://threejs.org/examples/js/loaders/GLTFLoader.js"></script>
        <script src="https://threejs.org/examples/js/loaders/DRACOLoader.js"></script>
        <script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
    
        <script>
    
            //Variables for setup
    
            let container;
            let camera;
            let renderer;
            let scene;
            let house;
            let mixer;
            const clock = new THREE.Clock();
    
            function init() {
                container = document.querySelector(".scene");
    
                //Create scene
                scene = new THREE.Scene();
    
                const fov = 35;
                const aspect = container.clientWidth / container.clientHeight;
                const near = 1;
                const far = 10000;
    
                //Camera setup
                camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
                camera.position.set(0, 0, 1000);
    
                const ambient = new THREE.AmbientLight(0x404040, 1);
                scene.add(ambient);
    
                const light = new THREE.DirectionalLight(0xffffff, 1);
                light.position.set(50, 50, 100);
                scene.add(light);
    
                //Renderer
                renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
                renderer.setSize(container.clientWidth, container.clientHeight);
                renderer.setPixelRatio(window.devicePixelRatio);
                renderer.outputEncoding = THREE.sRGBEncoding;
                container.appendChild(renderer.domElement);
    
                const controls = new THREE.OrbitControls(camera, renderer.domElement);
                controls.target.set(0, 0.5, 0);
                controls.update();
                controls.enablePan = false;
                controls.enableDamping = true;
    
                const dracoLoader = new THREE.DRACOLoader();
                dracoLoader.setDecoderPath('https://threejs.org/examples/js/libs/draco/gltf/');
    
                //Load Model
                let loader = new THREE.GLTFLoader();
                loader.setDRACOLoader(dracoLoader);
                loader.load("./house/bbb.glb", function (gltf) {
                    scene.add(gltf.scene);
                    house = gltf.scene.children[0];
    
                    mixer = new THREE.AnimationMixer(house);
                    mixer.clipAction(gltf.animations[0]).play();
    
                    animate();
                });
            }
    
            function animate() {
                requestAnimationFrame(animate);
    
                const delta = clock.getDelta();
                mixer.update(delta);
    
                house.rotation.z += 0.005;
                renderer.render(scene, camera);
            }
    
            init();
    
            function onWindowResize() {
                camera.aspect = container.clientWidth / container.clientHeight;
                camera.updateProjectionMatrix();
    
                renderer.setSize(container.clientWidth, container.clientHeight);
            }
    
            window.addEventListener("resize", onWindowResize);
    
        </script>
    </body>
    </html>
    
    

    如果你这样做,你会看到不同物体、电车、猫等等的动画......

    【讨论】:

    • 嗨,我实际上想添加 'bbb.glb' 而不是添加 'aaa.gltf',我应该将 loader.load("./house/aaa.gltf", function(gltf) { 更改为 loader.load("./house/bbb.glb", function(gltf) { 吗?
    • 我应该把这些行放在哪里let mixer;const clock = new THREE.Clock();
    • 您必须在添加其他脚本变量(例如let renderer)的同一级别添加它。是的,你必须加载 bbb.glb 是我使用的文件。在我的回答中修改
    • 我已经根据你的指导编辑了代码,但还是没有成功。你能帮我看看修改后的 js 文件吗?不知道是哪部分做错了,但是还是不能显示动画模型,如果您能看一下,非常感谢,谢谢!
    • 请下次提供最小可重现示例。用完整的功能代码更新了我的答案。不客气!
    猜你喜欢
    • 2021-02-20
    • 1970-01-01
    • 2017-01-28
    • 2013-05-28
    • 1970-01-01
    • 2020-06-21
    • 2021-12-15
    • 2021-09-25
    • 2017-02-02
    相关资源
    最近更新 更多