Three.js 地形高度场动画 | 三维可视化 / AI 提示词

📋 AI 提示词

prompt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
使用 Three.js 实现【地形高度场动画】,具体要求:

【核心特效】
- 使用 BoxGeometry 扁平长方体作为基础几何体
- 通过三个控制点影响顶点高度,产生地形起伏效果
- 控制点高度影响范围使用指数衰减函数
- 动态更新控制点位置,产生平滑的动画效果

【场景与光照】
- 轨道控制器交互
- 网格辅助线辅助观察
- 深色背景突出效果

【交互与控制】
- dat.gui 控制面板
- 影响半径、高度放大系数、衰减指数可调
- 支持自动更新控制点动画
- 线框模式切换
- 颜色自定义(高点和低点颜色)

【技术要求】
- Three.js 版本
- 自定义顶点着色器实现地形变形
- 使用 uniforms 传递控制参数

🖼️ 效果预览

地形高度场动画

🎮 案例演示

立即体验

🤔 前言

这个效果的作者是我认识多年的一位大佬,是一位非常热心的三维技术开发者,经常在群里帮助别人解答问题,人很好。

说实话,第一次看到这个效果的时候,我真的很惊讶!说实话,BoxGeometry 还能这么玩?特别是开启 wireframe 模式后,那些线条随着地形起伏流动的效果,简直太酷了!

这个效果的思路非常巧妙:用一个扁平的 BoxGeometry,通过顶点着色器让控制点"拉动"周围的顶点产生地形起伏。看起来像是一个很复杂的效果,实现起来代码却很少,非常值得学习。

📖 效果拆解

层次 视觉效果 技术实现
基础 200×1 的扁平长方体,旋转成水平面 BoxGeometry + rotateX 旋转
核心特效 控制点周围产生圆形隆起,形成地形 顶点着色器计算高度影响
增强细节 平滑的动画过渡,颜色根据高度渐变 lerp 插值 + mix 颜色混合
交互控制 实时调节参数,切换线框模式 dat.gui 控制面板

🔧 核心技术点

1. BoxGeometry 扁平化

这个效果最妙的地方就是用了一个扁扁的 BoxGeometry (200, 10, 1, 200, 1, 1),然后绕 X 轴旋转 -90 度,让它平躺在 XZ 平面上。

javascript
1
const geometry = new THREE.BoxGeometry(200, 10, 1, 200, 1, 1).rotateX(-Math.PI / 2)

200 个分段意味着有 201 个顶点排成一排,每个顶点都可以被控制点"拉高"。这才是第一步!

2. 顶点着色器地形计算

这是核心逻辑!在顶点着色器中,计算每个顶点被三个控制点影响的高度:

glsl
1
2
3
4
5
6
7
8
9
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;
}

简单说就是:距离越近、衰减越慢、高度越高,影响就越大。控制点就像扔进水面里的石头,激起一圈一圈的涟漪!

3. 动态影响半径

这个实现有一个很巧妙的设计:影响半径会根据控制点的高度动态变化。控制点越高,影响范围越大:

glsl
1
float dynamicRadius = baseInfluenceRadius + point.y * heightToRadiusRatio;

也就是说,高的控制点不仅本身隆起得高,还能影响更远的地方,形成一个平缓的山丘;而矮的控制点只能形成一个小土包。

4. 平滑动画过渡

控制点不会突然跳到目标位置,而是通过 lerp 插值慢慢移动过去:

javascript
1
2
3
for (let i = 0; i < 3; i++) {
    uniforms.points.value[i].lerp(uniforms.targetPoints.value[i], delta * 3)
}

配合自动更新机制,看起来就像地形在"呼吸",不断变化着形状。

5. Wireframe 模式下的惊艳效果

说实话,这个效果在线框模式下真的太惊艳了!那些线条随着地形起伏,仿佛活的神经网络在学习进化。开启方法也很简单:

javascript
1
material.wireframe = true

💡 调试与优化

问题类型 表现形式 解决方案
地形起伏不明显 调整 maxHeight 参数 增大最大高度值,让效果更明显
性能问题 帧率下降 减少 BoxGeometry 的分段数,从 200 降到 100
颜色过渡不自然 高点和低点颜色差异太小 选择对比度更高的颜色组合
控制点跑出视野 控制点随机位置超出范围 限制随机范围在 -50 到 50 之间

🚀 扩展思路

变体效果 核心改动 难度
3D 山脉地形 增加 Z 轴分段,改用 Perlin 噪声驱动 ⭐⭐⭐
水波纹效果 用 sin 函数替代衰减函数 ⭐⭐
多层颜色渐变 增加更多中间颜色,使用 smoothstep 混合 ⭐⭐
地形侵蚀效果 添加时间维度的噪声动画 ⭐⭐⭐

本文档由 ThreeLab 编辑整理,如需转载,请注明出处。