Three.js 旋转半圆石碑特效
🎯 提示词
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
使用 Three.js 实现旋转半圆石碑特效,具体要求:
**核心特效**
- 平面上的半圆发光区域
- 旋转的指针状光柱
- 角度渐变透明度效果
- 动态旋转动画
**场景与光照**
- 半透明背景 (alpha: true)
- 坐标轴辅助线辅助调试
- OrbitControls 自由观察
**交互与控制**
- TrackballControls 旋转缩放
- Stats 性能监控面板
**技术要求**
- Three.js 版本 (ES Module)
- 自定义 ShaderMaterial
- 极坐标旋转计算
- Raymarching 角度检测算法
📖 效果拆解
| 层次 |
视觉效果 |
技术实现 |
| 基础 |
绿色半圆发光区域 |
Fragment shader 基于距离判断 |
| 核心特效 |
旋转指针光柱 |
rotatePoint 函数旋转端点 |
| 动态效果 |
持续旋转动画 |
uTime 控制角度变化 |
| 辅助功能 |
坐标轴辅助线 |
AxesHelper |
🔧 核心技术点
1. 点旋转算法
为什么需要这个技术:将光柱端点绕中心旋转,计算任意时刻光柱的位置。
vec2 rotatePoint(vec2 center, float angle, vec2 p) {
float s = sin(angle);
float c = cos(angle);
p.x -= center.x;
p.y -= center.y;
float xNew = p.x * c - p.y * s;
float yNew = p.x * s + p.y * c;
return vec2(xNew + center.x, yNew + center.y);
}
2. 角度向量计算
为什么需要这个技术:计算像素点到圆心的向量与光柱向量的夹角,用于判断是否在光柱范围内。
float angleVec(vec2 a_, vec2 b_) {
vec3 a = vec3(a_, 0);
vec3 b = vec3(b_, 0);
float dotProd = dot(a, b);
vec3 crossprod = cross(a, b);
float crossprod_l = length(crossprod);
float lenProd = length(a) * length(b);
float cosa = dotProd / lenProd;
float sina = crossprod_l / lenProd;
float angle = atan(sina, cosa);
if (dot(vec3(0,0,1), crossprod) < 0.0)
angle = 90.0;
return angle * (180.0 / PI);
}
3. 半圆区域判断
为什么需要这个技术:结合距离和角度判断,决定像素是否发光。
void main(){
vec2 center = vec2(0.5, 0.5);
float radius = 0.5;
float angleStela = 180.0;
float distanceToCenter = distance(center, vUv.xy);
float angleStelaToApply = angleVec(normalize(lineEnd - center), normalize(vUv - center));
if (angleStelaToApply < angleStela && distanceToCenter < radius) {
float factorAngle = 1.0 - angleStelaToApply / angleStela;
alpha = factorAngle * endAlpha;
}
}
4. 旋转动画控制
为什么需要这个技术:通过时间 uniform 控制光柱持续旋转。
function animate() {
requestAnimationFrame(animate);
if (rayMarchingFireMaterial) {
rayMarchingFireMaterial.uniforms.uTime.value += 0.01;
}
controller.update(clock.getDelta());
renderer.render(scene, camera);
stats.update();
}
💡 调试与优化
| 问题类型 |
表现形式 |
解决方案 |
| 半圆变整圆 |
光柱两侧都发光 |
检查 angleStela 值是否为 180 |
| 光柱闪烁 |
帧率不稳定 |
减少 shader 中的 cross 计算 |
| 旋转方向错误 |
光柱向反方向旋转 |
检查 sin/cos 顺序或时间符号 |
🚀 扩展思路
| 变体效果 |
核心改动 |
难度 |
| 多指针时钟 |
增加多个不同角度的光柱 |
⭐ |
| 雷达扫描 |
渐变透明度模拟扫描效果 |
⭐ |
| 霓虹灯管 |
添加颜色渐变和发光效果 |
⭐⭐ |
| 动态半径 |
radius 随时间变化 |
⭐⭐ |
| 3D 半球星体 |
使用 SphereGeometry 替代 PlaneGeometry |
⭐⭐⭐ |
本文档由 ThreeLab 编辑整理,如需转载,请注明出处。
💬 评论区
评论功能即将上线,敬请期待!