6. 动画 (Animation) 与交互 (Interaction)


文档摘要

动画 (Animation) 与交互 (Interaction) Three.js 中的动画与交互:打造沉浸式体验 6.1 动画 (Animation) 动画是指随时间改变对象属性的过程。在 Three.js 中,可以通过多种方式实现动画,包括: 手动更新: 在渲染循环中直接修改对象的属性。 Tween 动画库: 使用 Tween.js 等库来创建平滑过渡的动画。 骨骼动画: 使用 和相关的类来控制骨骼动画。 着色器动画: 在着色器中直接操作顶点和片段数据,实现高级动画效果。 6.1.1 手动更新 这是最基本的动画方法。在渲染循环中,我们修改对象的属性(例如位置、旋转、缩放、颜色等),从而产生动画效果。

6. 动画 (Animation) 与交互 (Interaction)

Three.js 中的动画与交互:打造沉浸式体验

6.1 动画 (Animation)

动画是指随时间改变对象属性的过程。在 Three.js 中,可以通过多种方式实现动画,包括:

  • 手动更新: 在渲染循环中直接修改对象的属性。

  • Tween 动画库: 使用 Tween.js 等库来创建平滑过渡的动画。

  • 骨骼动画: 使用 THREE.AnimationMixer 和相关的类来控制骨骼动画。

  • 着色器动画: 在着色器中直接操作顶点和片段数据,实现高级动画效果。

6.1.1 手动更新

这是最基本的动画方法。在渲染循环中,我们修改对象的属性(例如位置、旋转、缩放、颜色等),从而产生动画效果。

// 创建一个立方体 const geometry = new THREE.BoxGeometry( 1, 1, 1 ); const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); const cube = new THREE.Mesh( geometry, material ); scene.add( cube ); // 渲染循环 function animate() { requestAnimationFrame( animate ); // 手动更新立方体的旋转 cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render( scene, camera ); } animate();

这段代码创建了一个绿色的立方体,并在渲染循环中不断更新其 x 和 y 轴的旋转,使其旋转起来。

6.1.2 Tween 动画库

Tween.js 是一个强大的 JavaScript 动画库,可以轻松创建各种平滑的动画效果。它提供了一系列方法来定义动画的起始值、结束值、持续时间、缓动函数等。

首先,需要引入 Tween.js 库。

<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/18.6.4/tween.umd.js"></script>

然后,可以使用 TWEEN.Tween() 创建一个 Tween 实例,并指定动画的目标对象、属性、起始值、结束值、持续时间和缓动函数。

// 创建一个立方体 const geometry = new THREE.BoxGeometry( 1, 1, 1 ); const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); const cube = new THREE.Mesh( geometry, material ); scene.add( cube ); // 创建一个 Tween 动画 const tween = new TWEEN.Tween(cube.position) .to({ x: 5 }, 2000) // 将立方体的 x 坐标移动到 5,持续 2 秒 .easing(TWEEN.Easing.Elastic.Out) // 使用弹性缓动函数 .repeat(Infinity) // 无限重复动画 .yoyo(true) // 动画来回播放 .start(); // 渲染循环 function animate() { requestAnimationFrame( animate ); TWEEN.update(); // 更新 Tween 动画 renderer.render( scene, camera ); } animate();

这段代码创建了一个立方体,并使用 Tween.js 创建了一个动画,将立方体的 x 坐标移动到 5,持续 2 秒,使用弹性缓动函数,无限重复动画,并且动画来回播放。

6.1.3 骨骼动画

骨骼动画是一种更高级的动画技术,它通过控制模型的骨骼来驱动模型的变形。 Three.js 提供了 THREE.AnimationMixer 类来控制骨骼动画。

要使用骨骼动画,首先需要加载一个包含骨骼动画的模型(例如 glTF 模型)。然后,创建一个 THREE.AnimationMixer 实例,并将模型作为参数传递给它。接下来,从模型的动画剪辑中创建一个 THREE.AnimationAction 实例,并使用 play() 方法开始播放动画。

let mixer; // 加载 glTF 模型 const loader = new THREE.GLTFLoader(); loader.load( 'path/to/your/model.gltf', function ( gltf ) { const model = gltf.scene; scene.add( model ); mixer = new THREE.AnimationMixer( model ); const clips = gltf.animations; // 播放第一个动画剪辑 const clip = clips[ 0 ]; const action = mixer.clipAction( clip ); action.play(); }, undefined, function ( error ) { console.error( error ); } ); // 渲染循环 function animate() { requestAnimationFrame( animate ); const delta = clock.getDelta(); // 获取时间差 if ( mixer ) { mixer.update( delta ); // 更新动画混合器 } renderer.render( scene, camera ); } animate();

这段代码加载了一个 glTF 模型,并播放了模型的第一个动画剪辑。 clock.getDelta() 用于获取上一帧到当前帧的时间差,并将该时间差传递给 mixer.update() 方法,以确保动画以正确的速度播放。

6.1.4 着色器动画

着色器动画是指在着色器程序中直接修改顶点和片段数据,从而实现动画效果。 这种方法可以创建非常复杂和自定义的动画效果,例如水波、火焰、粒子效果等。

着色器动画通常需要在顶点着色器中修改顶点的位置,并在片段着色器中修改像素的颜色。

// 顶点着色器 varying vec2 vUv; uniform float uTime; void main() { vUv = uv; // 基于时间改变顶点位置 vec3 transformed = position; transformed.x += sin(position.y * 5.0 + uTime) * 0.1; transformed.z += cos(position.x * 5.0 + uTime) * 0.1; gl_Position = projectionMatrix * modelViewMatrix * vec4(transformed, 1.0); } // 片段着色器 varying vec2 vUv; void main() { gl_FragColor = vec4(vUv.x, vUv.y, 1.0, 1.0); }

这段代码在顶点着色器中基于时间 uTime 修改了顶点的位置,从而创建了波浪效果。需要在 Three.js 中将 uTime 传递给着色器。

const material = new THREE.ShaderMaterial({ vertexShader: vertexShader, fragmentShader: fragmentShader, uniforms: { uTime: { value: 0.0 } } }); // 渲染循环 function animate() { requestAnimationFrame( animate ); material.uniforms.uTime.value += 0.01; // 更新时间 renderer.render( scene, camera ); } animate();

6.2 交互 (Interaction)

交互是指用户与 3D 场景进行互动的方式。 Three.js 提供了多种方式来实现交互,包括:

  • 鼠标事件: 监听鼠标点击、移动、滚轮等事件。

  • 键盘事件: 监听键盘按键事件。

  • 触摸事件: 监听触摸屏上的触摸事件。

  • 射线投射 (Raycasting): 使用射线投射来检测鼠标或触摸点与 3D 对象的相交。

6.2.1 鼠标事件

可以使用 JavaScript 的事件监听器来监听鼠标事件。

document.addEventListener( 'mousedown', onMouseDown, false ); document.addEventListener( 'mouseup', onMouseUp, false ); document.addEventListener( 'mousemove', onMouseMove, false ); function onMouseDown( event ) { // 处理鼠标按下事件 console.log("Mouse Down"); } function onMouseUp( event ) { // 处理鼠标抬起事件 console.log("Mouse Up"); } function onMouseMove( event ) { // 处理鼠标移动事件 console.log("Mouse Move"); }

这段代码监听了鼠标按下、抬起和移动事件,并在控制台输出相应的消息。

6.2.2 射线投射 (Raycasting)

射线投射是一种常用的交互技术,用于检测鼠标或触摸点与 3D 对象的相交。 Three.js 提供了 THREE.Raycaster 类来实现射线投射。

const raycaster = new THREE.Raycaster(); const mouse = new THREE.Vector2(); function onMouseMove( event ) { // 将鼠标位置转换为标准化设备坐标 (NDC) mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1; mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1; // 更新射线投射器的射线 raycaster.setFromCamera( mouse, camera ); // 计算物体和射线的焦点 const intersects = raycaster.intersectObjects( scene.children ); if ( intersects.length > 0 ) { // 处理相交的物体 console.log("Intersected object:", intersects[0].object); // 例如,改变相交物体的颜色 intersects[0].object.material.color.set( 0xff0000 ); } else { // 如果没有相交,恢复颜色 scene.children.forEach(child => { if (child.material) { child.material.color.set(0x00ff00); } }); } } window.addEventListener( 'mousemove', onMouseMove, false );

这段代码监听鼠标移动事件,并使用射线投射来检测鼠标与场景中物体的相交。 如果鼠标与物体相交,则将物体的颜色更改为红色。 如果没有相交,恢复颜色。

6.2.3 交互流程图

6.3 总结

动画和交互是 Three.js 中构建交互式 3D 场景的关键。 通过手动更新、Tween 动画库、骨骼动画和着色器动画,可以创建各种动画效果。 通过鼠标事件、键盘事件、触摸事件和射线投射,可以实现用户与 3D 场景的互动。

掌握这些技术,可以创建出令人惊叹的沉浸式 3D 体验。 随着 Three.js 的不断发展,将会出现更多更强大的动画和交互技术,为 3D 应用程序的开发带来更多可能性。 实践是最好的老师,多尝试不同的方法,才能真正掌握 Three.js 的动画和交互技术。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U