Three.js 跳跃动画教程

发布时间:2026/9/13 20:18:00

Three.js 跳跃动画教程 跳跃动画 ·Jump Animate· ▶ 在线运行案例案例合集三维可视化功能案例threehub.cn开源仓库github地址https://github.com/z2586300277/three-cesium-examples400个案例代码:网盘链接你将学到什么ShaderMaterial 自定义着色器实现核心视觉效果OrbitControls 相机轨道交互requestAnimationFrame渲染循环与resize自适应效果说明本案例演示跳跃动画效果基于 WebGL 实现「跳跃动画」可视化效果附完整可运行源码核心用到 ShaderMaterial、OrbitControls。建议先打开文首在线案例查看动态画面再对照下方源码逐步理解。核心概念Scene / Camera / WebGLRenderer构成最小渲染闭环大场景可开logarithmicDepthBuffer缓解 Z-fighting。ShaderMaterial通过uniforms 自定义 GLSL 控制逐像素/逐点效果透明粒子常配合depthTest: false。OrbitControls提供轨道旋转/缩放开启enableDamping后需在 animate 中controls.update()。实现步骤搭建 Scene、PerspectiveCamera、WebGLRenderer挂载 canvas 并处理resize定义 uniforms / onBeforeCompile 或 ShaderMaterial编写 GLSL 与材质参数创建 OrbitControls及 Raycaster 等交互控件若源码包含在requestAnimationFrame循环中更新状态并 renderCesium 为viewer.render或自动渲染代码要点import * as THREE from threeimport { OrbitControls } from three/examples/jsm/controls/OrbitControls.js import { GUI } from dat.guiconst box document.getElementById(box)const scene new THREE.Scene()const camera new THREE.PerspectiveCamera(50, box.clientWidth / box.clientHeight, 0.1, 2000)camera.position.set(10, 10, 10)const renderer new THREE.WebGLRenderer({ antialias: true, alpha: true, logarithmicDepthBuffer: true })renderer.setSize(box.clientWidth, box.clientHeight)box.appendChild(renderer.domElement)new OrbitControls(camera, renderer.domElement)scene.add(new THREE.GridHelper(10, 10))// uniforms const uniforms { points: { value: [ new THREE.Vector3(-30, 2.0, 0), new THREE.Vector3(0, 5.0, 0), new THREE.Vector3(30, 10.0, 0) ] }, // 目标点用于插值过渡 targetPoints: { value: [ new THREE.Vector3(-30, 2.0, 0), new THREE.Vector3(0, 5.0, 0), new THREE.Vector3(30, 10.0, 0) ] }, baseInfluenceRadius: { value: 5.0 }, heightToRadiusRatio: { value: 2.0 }, falloffPower: { value: 2.0 }, baseHeight: { value: 0.0 }, maxHeight: { value: 10.0 }, color1: { value: new THREE.Color(0x0066ff) }, color2: { value: new THREE.Color(0xff3300) }, }// 顶点着色器 const vertexShader uniform vec3 points[3]; uniform float baseInfluenceRadius; uniform float heightToRadiusRatio; uniform float falloffPower; uniform float baseHeight; uniform float maxHeight;varying float vHeightRatio;float calculateInfluence(vec3 point, vec3 vertex) { float distance2D length(point.xz - vertex.xz); float dynamicRadius baseInfluenceRadius point.y * heightToRadiusRatio; dynamicRadius max(dynamicRadius, baseInfluenceRadius); if (distance2D dynamicRadius) return 0.0; float normalizedDistance distance2D / dynamicRadius; float attenuation pow(1.0 - normalizedDistance, falloffPower); return attenuation * point.y; }void main() { vec4 worldPosition modelMatrix * vec4(position, 1.0); float heightOffset 0.0; heightOffset calculateInfluence(points[0], worldPosition.xyz); heightOffset calculateInfluence(points[1], worldPosition.xyz); heightOffset calculateInfluence(points[2], worldPosition.xyz); vHeightRatio clamp(heightOffset / maxHeight, 0.0, 1.0); vec3 newPosition position; newPosition.y heightOffset baseHeight; gl_Position projectionMatrixmodelViewMatrixvec4(newPosition, 1.0); }// 片段着色器 const fragmentShader uniform vec3 color1; uniform vec3 color2; varying float vHeightRatio;void main() { vec3 color mix(color1, color2, vHeightRatio); gl_FragColor vec4(color, 1.0); }// 创建网格 const geometry new THREE.BoxGeometry(200, 10, 1, 200, 1, 1).rotateX(-Math.PI / 2) const material new THREE.ShaderMaterial({ uniforms, vertexShader, fragmentShader, side: THREE.DoubleSide, wireframe: true }) scene.add(new THREE.Mesh(geometry, material))// GUI 参数 const params { baseInfluenceRadius: 5.0, heightToRadiusRatio: 2.0, falloffPower: 2.0, baseHeight: 0.0, maxHeight: 10.0, autoUpdate: true, interval: 1.0, wireframe: true, color1: #0066ff, color2: #ff3300, }// GUI 控制 const gui new GUI() gui.add(params, baseInfluenceRadius, 1, 50).name(影响半径).onChange(v uniforms.baseInfluenceRadius.value v) gui.add(params, heightToRadiusRatio, 0, 10).name(高度放大系数).onChange(v uniforms.heightToRadiusRatio.value v) gui.add(params, falloffPower, 0.1, 10).name(衰减指数).onChange(v uniforms.falloffPower.value v) gui.add(params, baseHeight, -5, 5).name(基础高度).onChange(v uniforms.baseHeight.value v) gui.add(params, maxHeight, 1, 30).name(最大高度).onChange(v uniforms.maxHeight.value v) gui.add(params, autoUpdate).name(自动更新) gui.add(params, interval, 0.3, 5).name(更新间隔(秒)) gui.add(params, wireframe).name(线框模式).onChange(v material.wireframe v) gui.addColor(params, color1).name(低点颜色).onChange(v uniforms.color1.value.set(v)) gui.addColor(params, color2).name(高点颜色).onChange(v uniforms.color2.value.set(v))// 随机生成目标点 function randomizeTargets() { for (let i 0; i 3; i) { uniforms.targetPoints.value[i].set( Math.random() * 200 - 100, Math.random() * params.maxHeight, 0 ) } }// 定时更新目标 let timer 0 const clock new THREE.Clock()function animate() { requestAnimationFrame(animate) const delta clock.getDelta()// 定时更新目标点 if (params.autoUpdate) { timer delta if (timer params.interval) { timer 0 randomizeTargets() } }// 平滑插值到目标点 for (let i 0; i 3; i) { uniforms.points.value[i].lerp(uniforms.targetPoints.value[i], delta * 3) }renderer.render(scene, camera) } animate()window.onresize () { renderer.setSize(box.clientWidth, box.clientHeight) camera.aspect box.clientWidth / box.clientHeight camera.updateProjectionMatrix() }完整源码GitHub小结本文提供跳跃动画完整 Three.js 源码与在线 Demo建议先运行案例再改 uniform/参数做二次实验更多 Three.js 实战案例见 three-cesium-examples 合集 与 GitHub 开源仓库
延伸阅读

更多相关文章

2026/9/13 0:56:22

【C/C++】手写内存池(四):内存池的重置、销毁与完整生命周期

前面已经介绍了小块内存的顺序分配、内存对齐、节点扩容以及大块内存的单独管理。一个完整的内存池还需要解决两个问题: 一批数据使用结束后,如何快速重新使用内存池? 程序结束时,如何完整释放内存池中的所有资源? 对…

2026/9/13 20:13:05

AI SDK 如何校验 Provider 响应中的 URL 以防止 SSRF 攻击

AI SDK 如何校验 Provider 响应中的 URL 以防止 SSRF 攻击 【免费下载链接】ai The AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and agents 项目地址: https://gitcode.com…

2026/9/13 20:13:05

bd template 命令详解:用 Beads 模板系统统一 issue 创建规范

bd template 命令详解:用 Beads 模板系统统一 issue 创建规范 【免费下载链接】beads Beads - A memory upgrade for your coding agent 项目地址: https://gitcode.com/GitHub_Trending/beads1/beads Beads 的 bd template 命令体系用于管理 issue 模板&…

2026/9/13 0:01:16

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/13 0:01:16

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/12 6:29:36

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/12 14:32:17

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/13 11:18:28

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码