环形着色器

Three.js 环形着色器 | 三维可视化 / AI 提示词
📋 AI 提示词
prompt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
使用 Three.js 实现**环形着色器**,具体要求:
【核心特效】
- 极坐标变换实现环形图案
- 双层火焰环形叠加
- 鼠标控制内圆大小
- 动态噪声扰动
【场景与光照】
- 深色背景
- OrbitControls 轨道控制器
- 自定义着色器实现火焰环形效果
【交互与控制】
- OrbitControls 鼠标拖拽旋转
- 鼠标滚轮缩放
- 鼠标X轴位置控制内圆半径
【技术要求】
- Three.js 版本 (ES Module)
- 自定义 ShaderMaterial 实现极坐标变换
- GLSL 噪声函数和火焰着色
- 实时鼠标交互
🖼️ 效果预览
🎮 案例演示
📖 效果拆解
| 层次 | 视觉效果 | 技术实现 |
|---|---|---|
| 基础 | 3D平面几何体 | PlaneGeometry (20×20) |
| 核心特效 | 极坐标环形变换 | UV坐标到极坐标的数学变换 |
| 增强细节 | 双层火焰效果 | 噪声函数叠加形成火焰 |
| 交互控制 | 鼠标控制内圆 | iMouse uniform 实时响应 |
🔧 核心技术点
1. 极坐标变换
为什么需要这个技术:将笛卡尔坐标转换为极坐标,实现环形图案的基础。
glsl
1
2
3
4
5
6
vec2 polarMap(vec2 uv, float shift, float inner) {
uv = vec2(0.5) - uv;
float px = 1.0 - fract(atan(uv.y, uv.x) / 6.28 + 0.25) + shift;
float py = (sqrt(uv.x * uv.x + uv.y * uv.y) * (1.0 + inner * 2.0) - inner) * 2.0;
return vec2(px, py);
}
2. 火焰噪声函数
为什么需要 this技术:使用分形噪声模拟火焰的随机跳动效果。
glsl
1
2
3
4
5
6
7
8
9
10
11
float fire(vec2 n) {
return noise(n) + noise(n * 2.1) * .6 + noise(n * 5.4) * .42;
}
float shade(vec2 uv, float t) {
uv.x += uv.y < .5 ? 23.0 + t * .035 : -11.0 + t * .03;
uv.y = abs(uv.y - .5);
uv.x *= 35.0;
float q = fire(uv - t * .013) / 2.0;
vec2 r = vec2(fire(uv + q / 2.0 + t - uv.x - uv.y), fire(uv + q - t));
return pow((r.y + r.y) * max(.0, uv.y) + .1, 4.0);
}
3. 双层颜色叠加
为什么需要这个技术:创建上下对称的双层火焰环,增强视觉效果。
glsl
1
2
3
4
5
6
7
8
9
10
11
12
void main() {
vec2 uv = vUv;
float ff = 1.0 - uv.y;
uv.x -= (iResolution.x / iResolution.y - 1.0) / 2.0;
vec2 uv2 = uv;
uv2.y = 1.0 - uv2.y;
uv = polarMap(uv, 1.3, m1);
uv2 = polarMap(uv2, 1.9, m1);
vec3 c1 = color(shade(uv, t)) * ff;
vec3 c2 = color(shade(uv2, t)) * (1.0 - ff);
gl_FragColor = vec4(c1 + c2, 1.0);
}
4. 鼠标交互控制
为什么需要这个技术:让用户通过鼠标实时控制环形效果参数。
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const { mesh, uniforms } = getShaderMesh();
function getShaderMesh() {
const uniforms = {
iTime: { value: 0 },
iResolution: { value: new THREE.Vector2(1900, 1900) },
iMouse: { value: new THREE.Vector2(0, 0) }
};
renderer.domElement.addEventListener('mousemove', (event) => {
uniforms.iMouse.value.x = event.clientX;
uniforms.iMouse.value.y = event.clientY;
});
// 在着色器中使用 iMouse
float m1 = iMouse.z < 0.0001 ? 3.6 : iMouse.x * 5.0 / iResolution.x;
}
💡 调试与优化
| 问题类型 | 表现形式 | 解决方案 |
|---|---|---|
| 环形不居中 | 图案偏离中心 | 调整 uv.x -= (iResolution.x / iResolution.y - 1.0) / 2.0 |
| 火焰闪烁过快 | 动画过于剧烈 | 减小时间系数 t * .035 |
| 鼠标控制不灵敏 | 内圆变化不明显 | 调整 m1 的计算系数 |
🚀 扩展思路
- 多层环形:添加更多层的环形火焰
- 颜色渐变:实现从火焰红到星空蓝的渐变
- 拖尾效果:添加运动模糊的拖尾
- 音频响应:配合音频实现声音可视化
- 粒子系统:添加从环形飞出的粒子
📚 相关学习资源
©️ 版权声明
*本文档由 ThreeLab 编辑整理,专注 Three.js 着色器、Web 3D、GIS 可视化技术分享。如需转载,请注明出处。








京公网安备 11010502038735号
💬 评论区
评论功能即将上线,敬请期待!