01.three官方示例+编辑器+AI快速学习webgl_animation_keyframes

实例:examples/webgl_animation_keyframes.html

在这里插入图片描述

重点关注:

  • AnimationMixer:管理模型的所有动画
  • AnimationClip:表示一个完整的动画
  • ClipAction:控制动画的播放状态(播放、暂停、速度等)
  • PMREMGenerator处理环境光照,提升渲染质量

本实例主要讲解内容

本实例主要讲解在Three.js中如何使用WebGL技术实现3D模型的加载、动画播放以及用户交互。通过创建场景、相机、渲染器等基础对象,加载GLTF模型并应用动画,同时使用轨道控制器实现用户对相机视角的控制,以及利用性能统计工具优化渲染性能,展示了一个完整的3D动画交互场景的构建过程,帮助开发者掌握Three.js在动画和交互方面的核心应用。 ### 代码注释与重点解析

以下是对Three.js动画关键帧示例的详细注释,包含了学习重点和核心概念解析:

html 复制代码
<!DOCTYPE html>
<html lang="en">
    <head>
        <!-- 页面标题 -->
        <title>three.js webgl - animation - keyframes</title>
        <!-- 设置字符编码为UTF-8 -->
        <meta charset="utf-8">
        <!-- 视口设置,用于响应式布局,禁止用户缩放,最小和最大缩放比例均为1.0 -->
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <!-- 引入外部样式表main.css -->
        <link type="text/css" rel="stylesheet" href="main.css">
        <!-- 内部样式表,设置页面背景颜色为#bfe3dd,文本颜色为#000,链接颜色为#2983ff -->
        <style>
            body {
                background-color: #bfe3dd;
                color: #000;
            }

            a {
                color: #2983ff;
            }
        </style>
    </head>

    <body>

        <!-- 用于放置Three.js渲染结果的容器 -->
        <div id="container"></div>

        <!-- 包含信息的div,展示three.js链接、模型链接及作者信息 -->
        <div id="info">
            <a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - animation - keyframes<br/>
            Model: <a href="https://artstation.com/artwork/1AGwX" target="_blank" rel="noopener">Littlest Tokyo</a> by
            <a href="https://artstation.com/glenatron" target="_blank" rel="noopener">Glen Fox</a>, CC Attribution.
        </div>

        <!-- 定义模块导入映射,指定three及相关插件的导入路径 -->
        <script type="importmap">
            {
                "imports": {
                    "three": "../build/three.module.js",
                    "three/addons/": "./jsm/"
                }
            }
        </script>

        <!-- 定义JavaScript模块 -->
        <script type="module">

            // 导入Three.js核心库
            import * as THREE from 'three';

            // 导入性能统计工具Stats
            import Stats from 'three/addons/libs/stats.module.js';

            // 导入轨道控制器OrbitControls,用于控制相机视角
            import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
            // 导入房间环境对象RoomEnvironment,用于创建场景环境
            import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';

            // 导入GLTF模型加载器GLTFLoader
            import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
            // 导入Draco压缩模型加载器DRACOLoader
            import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';

            // 声明动画混合器变量
            let mixer;

            // 创建时钟对象,用于计算动画时间间隔
            const clock = new THREE.Clock();
            // 获取放置渲染结果的容器元素
            const container = document.getElementById('container');

            // 创建性能统计对象
            const stats = new Stats();
            // 将性能统计的DOM元素添加到容器中
            container.appendChild(stats.dom);

            // 创建WebGL渲染器,开启抗锯齿
            const renderer = new THREE.WebGLRenderer({ antialias: true });
            // 设置渲染器的像素比为设备像素比
            renderer.setPixelRatio(window.devicePixelRatio);
            // 设置渲染器的尺寸为窗口的内部宽度和高度
            renderer.setSize(window.innerWidth, window.innerHeight);
            // 将渲染器的DOM元素添加到容器中
            container.appendChild(renderer.domElement);

            // 创建PMREM生成器,用于生成预过滤辐射环境贴图
            const pmremGenerator = new THREE.PMREMGenerator(renderer);

            // 创建场景对象
            const scene = new THREE.Scene();
            // 设置场景背景颜色与页面背景一致
            scene.background = new THREE.Color(0xbfe3dd);
            // 设置场景环境,使用房间环境并生成对应的纹理
            scene.environment = pmremGenerator.fromScene(new RoomEnvironment(), 0.04).texture;

            // 创建透视相机
            const camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 100);
            // 设置相机位置
            camera.position.set(5, 2, 8);

            // 创建轨道控制器,关联相机和渲染器的DOM元素
            const controls = new OrbitControls(camera, renderer.domElement);
            // 设置控制器的目标点
            controls.target.set(0, 0.5, 0);
            // 更新控制器状态
            controls.update();
            // 禁用平移功能
            controls.enablePan = false;
            // 启用阻尼效果,使相机移动更平滑
            controls.enableDamping = true;

            // 创建Draco加载器
            const dracoLoader = new DRACOLoader();
            // 设置Draco解码器的路径
            dracoLoader.setDecoderPath('jsm/libs/draco/gltf/');

            // 创建GLTF加载器
            const loader = new GLTFLoader();
            // 为GLTF加载器设置Draco加载器,用于加载压缩的GLTF模型
            loader.setDRACOLoader(dracoLoader);
            // 加载GLTF模型
            loader.load('models/gltf/LittlestTokyo.glb', function (gltf) {

                // 获取加载的模型场景
                const model = gltf.scene;
                // 设置模型位置
                model.position.set(1, 1, 0);
                // 设置模型缩放比例
                model.scale.set(0.01, 0.01, 0.01);
                // 将模型添加到场景中
                scene.add(model);

                // 创建动画混合器,关联模型
                mixer = new THREE.AnimationMixer(model);
                // 播放模型的第一个动画剪辑
                mixer.clipAction(gltf.animations[0]).play();

                // 设置渲染器的动画循环函数
                renderer.setAnimationLoop(animate);

            }, undefined, function (e) {

                // 加载过程中出现错误时,在控制台打印错误信息
                console.error(e);

            });


            // 窗口大小改变时的回调函数
            window.onresize = function () {

                // 更新相机的纵横比
                camera.aspect = window.innerWidth / window.innerHeight;
                // 更新相机的投影矩阵
                camera.updateProjectionMatrix();

                // 更新渲染器的尺寸
                renderer.setSize(window.innerWidth, window.innerHeight);

            };


            // 动画循环函数
            function animate() {

                // 获取时钟的时间间隔
                const delta = clock.getDelta();

                // 更新动画混合器,推进动画
                mixer.update(delta);

                // 更新轨道控制器,处理相机的交互
                controls.update();

                // 更新性能统计信息
                stats.update();

                // 使用渲染器渲染场景和相机
                renderer.render(scene, camera);

            }


        </script>

    </body>
</html>

学习重点解析

  1. Three.js基础架构

    • 场景(Scene)、相机(Camera)、渲染器(Renderer)的创建与配置
    • 轨道控制器(OrbitControls)的使用,实现用户交互
  2. GLTF模型加载与处理

    • 使用GLTFLoader加载3D模型
    • DRACOLoader处理压缩模型,提高加载效率
    • 模型位置、缩放和旋转的调整
  3. 关键帧动画系统

    • AnimationMixer:管理模型的所有动画
    • AnimationClip:表示一个完整的动画
    • ClipAction:控制动画的播放状态(播放、暂停、速度等)
  4. 性能优化与监控

    • 使用Stats监控帧率和性能
    • PMREMGenerator处理环境光照,提升渲染质量
    • 窗口大小自适应处理
  5. 动画循环机制

    • 使用renderer.setAnimationLoop()设置动画循环
    • 利用Clock对象计算帧间隔时间,确保动画速度一致

本实例核心目标

这个示例主要展示了Three.js中关键帧动画系统的使用方法,通过加载包含动画的GLTF模型,并使用AnimationMixer播放动画,演示了以下核心概念:

  1. 如何加载和处理包含动画的3D模型
  2. 如何使用Three.js的动画系统控制模型动画
  3. 如何实现平滑的动画循环和时间管理
  4. 如何通过环境光照提升模型渲染效果

这是Three.js动画系统的基础教程,适合学习3D场景中角色动画、物体运动等动画效果的实现方法。

交流学习: Three.js 场景编辑器 (Vue3 + TypeScript
实现)

https://threelab.cn/threejs-edit/

相关推荐
m4Rk_7 小时前
【论文阅读】Agent 记忆机制(83):Inside Out——用可演化 PersonaTree 构建 Agent 的核心长期记忆
论文阅读·人工智能·学习·开源·github
运行时异常7 小时前
【WMS 仓储系统集成 AI Agent 实战】第 8 讲(终篇):生产部署与并发安全——Semaphore 放进 Flux.defer 的坑,压测抓了一晚上
人工智能·安全
杨杨杨大侠7 小时前
Jev、Kev、Laya:决策模型怎么选,什么时候需要微调?
人工智能·python·agent
一路向北he7 小时前
trae或者vscode定义了文件,但是文件不亮是灰的
ide·vscode·编辑器
代码方舟7 小时前
零信任架构实战:基于天远人企关联构建自动化供应链金融网关
运维·人工智能·架构·自动化
虹科网络安全7 小时前
“顶会”看安全(十八):超越越狱:揭示由能力边界模糊引发的 LLM 应用安全风险
人工智能·安全
Maiko Star8 小时前
* LangChain 提示词模板详解:ChatPromptTemplate 的使用与高级特性
java·人工智能·langchain
鬓戈8 小时前
Rust 语言与 AI 应用生态调研及学习路径
人工智能·学习·rust
天远API8 小时前
零信任架构实战:基于天远人企关联构建自动化图谱网关
网络·人工智能·架构·自动化
爱吃提升8 小时前
文生视频模型发展趋势(2026)
人工智能·音视频