Three.js 数学函数着色器 | 三维可视化 / AI 提示词
📋 AI 提示词
prompt
使用 Three.js 实现**数学函数着色器效果**,具体要求:
【核心特效】
- 六种数学函数可视化:正弦波、余弦波、正切波、指数函数、对数函数、高斯函数
- 函数图像的3D曲面展示
- 可调的频率、振幅、相位参数
- 网格线叠加显示
【场景与光照】
- 深蓝色系背景 (#1a1a2e → #16213e 径向渐变)
- OrbitControls 自由视角控制
- 自定义着色器实现函数曲面和颜色渐变
【交互与控制】
- OrbitControls 鼠标拖拽旋转
- 鼠标滚轮缩放
- GUI 面板切换函数类型、调节参数、显示/隐藏网格
【技术要求】
- Three.js 版本 (ES Module)
- 自定义顶点着色器实现函数曲面变形
- 自定义片元着色器实现颜色渐变和网格
- lil-gui 参数控制
🖼️ 效果预览

🎮 案例演示
📖 效果拆解
| 层次 | 视觉效果 | 技术实现 |
|---|---|---|
| 基础 | 3D平面几何体 | PlaneGeometry (10×10, 512×512分段) |
| 核心特效 | 函数曲面变形 | 顶点着色器基于数学函数计算Z轴位移 |
| 增强细节 | 颜色渐变和网格线 | 片元着色器插值颜色 + 网格线绘制 |
| 交互控制 | 函数切换和参数调节 | lil-gui 控制类型/频率/振幅等 |
🔧 核心技术点
1. 六种数学函数定义
为什么需要这个技术:将数学公式转化为可视化的3D曲面,帮助理解函数特性。
glsl
float sineWave(float x) {
return uAmplitude * sin(2.0 * 3.14159 * uFrequency * x + uPhase);
}
float cosineWave(float x) {
return uAmplitude * cos(2.0 * 3.14159 * uFrequency * x + uPhase);
}
float tangentWave(float x) {
return uAmplitude * tan(2.0 * 3.14159 * uFrequency * x + uPhase);
}
float exponentialFunction(float x) {
return uAmplitude * exp(uParam * x);
}
float logarithmicFunction(float x) {
return uAmplitude * log(uParam * x + 1.0);
}
float gaussianFunction(float x) {
float mu = 0.0;
float sigma = 0.2;
return uAmplitude * exp(-pow(x - mu, 2.0) / (2.0 * sigma * sigma));
}
2. 顶点着色器函数选择
为什么需要这个技术:根据用户选择的函数类型,动态切换计算公式。
glsl
uniform int uFunctionType;
void main() {
float functionValue = 0.0;
float x = position.x * 2.0;
if(uFunctionType == 0) {
functionValue = sineWave(x + uTime * 0.5);
} else if(uFunctionType == 1) {
functionValue = cosineWave(x + uTime * 0.5);
} else if(uFunctionType == 2) {
functionValue = tangentWave(x + uTime * 0.5);
} else if(uFunctionType == 3) {
functionValue = exponentialFunction(x + uTime * 0.2);
} else if(uFunctionType == 4) {
functionValue = logarithmicFunction(x + 2.0 + uTime * 0.1);
} else {
functionValue = gaussianFunction(x + uTime * 0.3);
}
vec3 newPosition = position;
newPosition.z += functionValue * 0.5;
gl_Position = projectionMatrix * modelViewMatrix * vec4(newPosition, 1.0);
}
3. 颜色渐变和网格绘制
为什么需要这个技术:增强函数曲面的视觉效果,便于观察函数值变化。
glsl
uniform vec3 uColor1;
uniform vec3 uColor2;
uniform vec3 uColor3;
uniform bool uShowGrid;
uniform float uGridSize;
void main() {
vec3 baseColor = mix(uColor1, uColor2, (vFunctionValue + 1.0) * 0.5);
float highlight = smoothstep(0.5, 0.8, abs(vFunctionValue));
baseColor = mix(baseColor, uColor3, highlight);
if(uShowGrid) {
vec2 gridPos = fract(vUv / uGridSize);
float gridLine = step(0.98, gridPos.x) + step(0.98, gridPos.y);
gridLine = min(gridLine, 1.0);
baseColor = mix(baseColor, vec3(1.0), gridLine * 0.3);
}
gl_FragColor = vec4(baseColor, 1.0);
}
4. GUI 控制面板配置
为什么需要这个技术:提供友好的交互界面,让用户实时调节各种参数。
javascript
const mathParams = {
uFunctionType: 0, // 0=正弦波
uFrequency: 4.0,
uAmplitude: 1.0,
uPhase: 0.0,
uParam: 1.0,
uShowGrid: true,
uGridSize: 0.1
};
const gui = new GUI();
gui.add(mathParams, 'uFunctionType', {
'正弦波': 0, '余弦波': 1, '正切波': 2,
'指数函数': 3, '对数函数': 4, '高斯函数': 5
}).name('函数类型');
gui.add(mathParams, 'uFrequency', 0.1, 10).name('频率');
gui.add(mathParams, 'uAmplitude', 0.1, 2).name('振幅');
gui.add(mathParams, 'uShowGrid').name('显示网格');
💡 调试与优化
| 问题类型 | 表现形式 | 解决方案 |
|---|---|---|
| 正切函数无穷大 | 出现异常高的尖峰 | 添加 tan() 结果的 clamp 限制 |
| 网格闪烁 | 网格线在移动时闪烁 | 减小 uGridSize 或增加分段数 |
| 性能问题 | 512×512分段导致卡顿 | 减少分段数 (256×256) 或简化着色器 |
| 对数函数负值 | log函数输入为负 | 确保 uParam * x + 1.0 > 0 |
🚀 扩展思路
- 二元函数:添加第二个变量,实现 f(x,y) 的3D可视化
- 参数方程:支持极坐标方程如玫瑰线、心形线
- 数据拟合:加载外部数据点并进行曲面拟合
- 动画轨迹:添加点在曲面上移动的动画
- 多函数叠加:同时显示多个函数进行对比
📚 相关学习资源
©️ 版权声明
*本文档由 ThreeLab 编辑整理,专注 Three.js 着色器、Web 3D、GIS 可视化技术分享。如需转载,请注明出处。