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 实现逼真的乌云密布特效,具体要求:
**核心特效**
- 体积云 raymarching
- 内光源闪烁
- 多层噪声叠加
- 消散效果
- 抗锯齿渲染
**场景与光照**
- 全屏 PlaneGeometry
- 自定义 raymarching
- 球体内渲染
**交互与控制**
- 无控制器,纯动画展示
**技术要求**
- Three.js 版本 (ES Module)
- 自定义 ShaderMaterial
- PlaneGeometry 全屏
- 复杂 raymarching 算法
📖 效果拆解
| 层次 |
视觉效果 |
技术实现 |
| 基础 |
全屏 shader |
PlaneGeometry |
| 云层 |
密度函数 |
octavedNoise 叠加 |
| 光源 |
随机闪烁 |
hash11 概率 |
| 渲染 |
Raymarching |
累积透明度 |
| 阴影 |
光线步进 |
多步阴影检测 |
🔧 核心技术点
1. 多层噪声
为什么需要这个技术:多层不同频率的噪声叠加创造自然的云层纹理。
float octavedNoise(vec3 position) {
vec3 samplePosition = position * 2.;
float noiseAmount = noise(samplePosition + iTime * vec3(0.0,0.2,0.0));
samplePosition *= 1.99;
noiseAmount += noise(samplePosition + iTime * vec3(0.05,-0.37,0.02)) * 0.51;
noiseAmount /= 1.51;
return noiseAmount;
}
2. 密度计算
为什么需要这个技术:结合基础形状和噪声确定云的密度分布。
float density(vec3 position) {
float baseValue = 1.0 - pow(max(0.0, length(position)), 2.0);
float noiseAmount = octavedNoise(position);
return max(0., min(1., baseValue - max(0., noiseAmount * 1.5)));
}
3. 内光源闪烁
为什么需要这个技术:模拟云层内部的闪电或能量闪烁。
vec4 innerLightPositionAndIntensity() {
float scaledTime = iTime * 6.1;
float hashInput = floor(scaledTime) * 0.1;
if (hash11(hashInput) < 0.8) return vec4(0.);
float intensity = sin(fract(scaledTime) * 3.142);
return vec4(position, intensity);
}
4. Raymarching 渲染
为什么需要这个技术:在视线方向上步进,累积颜色和透明度。
for(int i = 0; i < mainSteps; i++) {
float localDensity = min(1.0, density(samplePosition) * mainDensityScale);
if (localDensity > 0.001) {
transmittance *= (1. - stepDensity);
if (transmittance < 0.01) break;
}
samplePosition += mainStepAmount;
}
💡 调试与优化
| 问题类型 |
表现形式 |
解决方案 |
| 性能极差 |
帧率极低 |
减少 mainSteps 或 shadowSteps |
| 云层空洞 |
过多透明区域 |
增加噪声叠加次数 |
| 闪烁过频 |
眼花缭乱 |
增加 hash11 阈值 |
🚀 扩展思路
| 变体效果 |
核心改动 |
难度 |
| 云海 |
改背景为地面 |
⭐ |
| 日落云 |
改变光源颜色 |
⭐ |
| 风暴云 |
增加内闪烁频率 |
⭐ |
| 云朵形状 |
改变噪声参数 |
⭐⭐ |
| 体积光 |
添加体积光散射 |
⭐⭐⭐ |
本文档由 ThreeLab 编辑整理,如需转载,请注明出处。
💬 评论区
评论功能即将上线,敬请期待!