半圆

Three.js 旋转半圆石碑特效 | 三维可视化 / AI 提示词
📋 AI 提示词
prompt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
使用 Three.js 实现旋转半圆石碑特效,具体要求:
【核心特效】
- 平面上的半圆发光区域
- 旋转的指针状光柱
- 角度渐变透明度效果
- 动态旋转动画
【场景与光照】
- 半透明背景 (alpha: true)
- 坐标轴辅助线辅助调试
- OrbitControls 自由观察
【交互与控制】
- TrackballControls 旋转缩放
- Stats 性能监控面板
【技术要求】
- Three.js 版本 (ES Module)
- 自定义 ShaderMaterial
- 极坐标旋转计算
- Raymarching 角度检测算法
🖼️ 效果预览
🎮 案例演示
📖 效果拆解
| 层次 | 视觉效果 | 技术实现 |
|---|---|---|
| 基础 | 绿色半圆发光区域 | Fragment shader 基于距离判断 |
| 核心特效 | 旋转指针光柱 | rotatePoint 函数旋转端点 |
| 动态效果 | 持续旋转动画 | uTime 控制角度变化 |
| 辅助功能 | 坐标轴辅助线 | AxesHelper |
🔧 核心技术点
1. 点旋转算法
将光柱端点绕中心旋转,计算任意时刻光柱的位置。
javascript
1
2
3
4
5
6
7
8
9
10
11
12
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. 角度向量计算
计算像素点到圆心的向量与光柱向量的夹角,用于判断是否在光柱范围内。
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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. 半圆区域判断
结合距离和角度判断,决定像素是否发光。
glsl
1
2
3
4
5
6
7
8
9
10
11
12
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 控制光柱持续旋转。
javascript
1
2
3
4
5
6
7
8
9
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 编辑整理,如需转载,请注明出处。







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