【免费下载链接】LinearAbiltyCastingThreeJS
LinearAbilityCastingThreeJS 是一个用 Three.js 加手写 GLSL 打造的技能弹道(skillshot)特效沙盒。除了当前在线的五大技能外,它的src/archive/目录里还静静躺着一套被整体退役的"四元素"系统——其中基于Raymarching(光线步进)的体积火焰与水面特效,是整仓里最值得动手挖掘的宝藏。本文带你找到它、读懂原理,并一步步把火焰 / 水面效果搬回主项目,几乎不用重写一行数学。
先认识项目:为什么会有"归档"这一层 🗂️
一句话概括这个项目:一个角色、五种可瞄准的技能、938 个实时滑块,全部效果都是程序化生成的——没有一张贴图、没有一张精灵图。完整的能力清单与操作说明见 README.md。
上图是当前在线的 Storm Lance(风暴长枪):一道完全由顶点着色器摆出来的闪电,代表了这个项目的特效质量基准。
但很少有人注意到,这个项目的"上一世"是另一套系统:火、水、土、风四元素,沿着你手绘的自由路径喷射,角色还能骑在笔画上飞。当项目把"手绘路径"改成了"MOBA 式地面箭头"(线性技能弹道)后,整套围绕路径输入构建的系统失去了输入来源,于是被整体移进了src/archive/——而不是原地腐烂。
官方对归档的说明很直白:这些文件不参与 Vite 打包(index.html → src/main.js够不到它们),"留着纯粹是为了日后挖宝",原文见 src/archive/README.md。
上图是当前在线的 Frost Lance(冰枪)。归档里的火焰与水面,就是与它同一代工程水准的"老前辈",只是换了输入方式被暂时雪藏。
归档里到底藏了什么:一份文件地图 🧭
想挖宝,先拿地图。归档目录里值得关注的文件如下(完整清单见 src/archive/README.md):
| 目录 | 关键文件 | 里面是什么 |
|---|---|---|
abilities/ | FireAbility.js | 沿路径飞行的体积火球,尾部拖燃烧气体,终点在空中爆炸 |
abilities/ | WaterAbility.js | 沿路径翻涌的水体,终点炸开泡沫水冠与喷射水柱 |
materials/ | VolumetricFireMaterial.js | ⭐ 4 层 Raymarched 火焰 + 普朗克黑体着色 |
materials/ | OceanWaterMaterial.js | ⭐ Raymarched 水面:菲涅尔 + 泡沫 + 折射 |
materials/ | DistortionMaterial.js | 屏幕空间折射偏移:火的热浪、水的折射 |
config/ | legacySettings.js | 火焰 / 水面被退役时调好的全部参数,原样保留 |
⭐ 标记的两个文件是本文主角:一套会烧的火,一汪真的水。
挖掘宝藏一:Raymarched 体积火焰是"烧"出来的 🔥
新手常以为"火焰特效"就是一张贴图在缩放、做加法混合。归档里的火焰完全不是——它是一段真正的光线步进体积。
核心思路:火焰本体只是一块"代理外壳"。贴在飞行路径上的网格并不等于火焰,它只是一条朝向相机的账单式条带(billboard ribbon),负责把真实体积"圈住"。真正的火发生在每个像素:重建路径的局部坐标系 → 从相机发一条射线 → 在密度场里逐步积分发射与吸收。
火焰密度场由 4 层从粗到细堆叠(顺序正是肉眼读一团火球的顺序):
- 轮廓层(silhouette):路径上的一串胶囊,横截面是水滴形(浮力向上拉伸),半径被一阶低频噪声鼓动——火球外形由"米级"鼓包主导。
- 涡旋卷起(vortex roll-up):热气体甩出环形涡,沿尾迹后移并随年龄长大;让噪声域沿(流向、竖直)平面按行波旋转,把场"翻折"起来,形成翻滚、蘑菇状的烟团——普通 fbm 叠再多八度只能做出云,做不出卷。
- 湍流(turbulence):5 个逐级做域扭曲的八度,八度之间旋转去网格化,且每层都比上一层浮升更快,细结构因此跑过粗结构,撕成向上舔的火舌。
- 碎裂(shred):侵蚀在轴心处很弱、在边缘处很烈,火核保持"一整块燃烧体",边缘却溶成缕缕飘散的细丝。
着色不是调色板,而是温度。这是全文件最漂亮的一点:颜色来自 blackbody()——普朗克黑体辐射近似。"火是一团温度,不是一张调色板":红边 → 橙身 → 白核的连续渐变,以及核心区亮过边缘几十倍的巨大动态范围,都从物理里掉出来,而非手调。
三个值得记住的"踩坑教训"(都写在注释里):
- 别用加法混合:真火既发光又遮挡,所以这里用预乘 "over" 混合,火焰才能"挡住"背景。
- 别用温度驱动整条湍流场:辐射功率随温度的高次幂放大,若拿完整湍流场去驱动温度,火焰会渲染成"抛光玛瑙"——一圈圈密集等高线。温度要走更钝的几何轮廓(胶囊衰减),噪声只负责位移。
- 包围盒要用椭球而非球:火焰比宽高得多,用球包会让固定步数被大量空空间摊薄。
火球能力(余烬 / 火星 / 烟、空中爆炸、焦痕、热浪扭曲)在 FireAbility.js,火焰调参集中在 legacySettings.js 的fire块(如volumeSteps、shred、tempCore、colorCore)。
挖掘宝藏二:Raymarched 水面是"真的水" 🌊
如果说火焰是"穿过介质积分",水面就是"找一条表面"——水不发光,它有一张表面,水之所以像水,几乎全发生在那张表面上。
核心思路同样是代理外壳 + 光线步进,但目标不同:射线寻找这个符号场第一次变号的点,再用4 次二分把交点收进一个像素内,然后给该点着色:field(p) = radius(u) * (1 + swell + chop) - distanceToAxis(p),实现见 waterField()。
表面拿到后,五样东西让它"读起来是水":
- 法线:取同一个场的梯度(四面体取样),密度场里的每条涟漪都真实参与光照;更细的波动只加在命中点法线上(3 次噪声 vs 40 次,还不会打穿表面)。
- 反射:Schlick 菲涅尔取场景 HDR 环境,外加一个很紧的太阳高光——这是"湿润"感的来源。
- 深度着色:对解析弦长做 Beer-Lambert 吸收,细边是绿松石色,腹部是深蓝。
- 透光:薄浪尖被从背后照亮(一种 SSS),这是海浪"由内发光"的关键。
- 泡沫:浪峰泡沫、翻卷泡沫、剪影喷雾,全部用Voronoi 切成一格格的,于是读起来是气泡而非刷上去的白漆。
又一个反直觉细节:水的"破碎"(变薄处撕成丝、带孔的片、结成水珠)打在alpha 上而非场上——在场上打孔会在体内制造变号、步进就会撞上内壁,得到黑色斑点。
折射单独由 DistortionMaterial.js 负责:把屏幕空间 UV 偏移写进半分辨率缓冲,后处理阶段整体扭曲。当前在线版保留了这条 pass 但暂无人写入,等于一个"预留钩子",正适合拿来复活水的折射。
水体落地的泡沫 / 涟漪 / 冲击波贴片,和火球的焦痕,都打在 src/world/Ground.js 配置的这层天然岩石地面上。
火焰 vs 水面:两种 Raymarching 的分工 ⚖️
| 维度 | 体积火焰Fire | 水面Water |
|---|---|---|
| 步进在找什么 | 穿过介质的发射 + 吸收积分 | 第一次变号的表面,再二分细化 |
| 着色依据 | 温度(普朗克黑体),发射随 (T/Tcore)^n 放大 | 表面法线:菲涅尔反射 + 深度吸收 + 透光 |
| 混合方式 | 预乘 "over"(发光且遮挡) | 普通 alpha 混合(含不透明泡沫) |
| 细节来源 | 4 层密度场(轮廓→涡旋→湍流→碎裂) | 场内只放粗浪,细波进命中点法线 |
| 遮挡 | 被不透明深度预通道裁掉 | 同左,折射走独立 distortion 缓冲 |
一句话:火在"体内",水在"表面"。两者共享同一套"代理外壳 + 场景深度裁切"基建,所以迁移成本极低。
把火焰 / 水面搬回主项目:5 步迁移指南 🚀
归档不是垃圾场,而是一个即插即用的效果库。官方恢复步骤(src/archive/README.md)很短:
- 搬文件和依赖回
src/:例如把 FireAbility.js 及其 import 的 VolumetricFireMaterial.js 移回src/对应目录(RibbonGeometry已以 src/effects/RibbonGeometry.js 复活,可直接复用)。 - 合并参数块:把 legacySettings.js 里对应的
fire/water块展开进 src/config/settings.js。 - 注册能力:在 src/abilities/AbilityManager.js 的
ABILITY_TYPES登记类,并把 id 加进 settings 的ELEMENTS/ELEMENT_META。 - 处理基类差异:归档能力继承的是旧版(沿样条)
Ability,在线版是线性Ability(spawn(origin, direction, distance))。要么移植到新版基类,要么把旧基类换个名字并排共存——项目其他部分不关心用哪个。 - 输入按需:只有想把"自由手绘路径"找回来时才需要 PathDrawer.js + PathTrail.js;用
AimController递一条两点曲线,就能驱动样条型能力。
💡 最小可行目标:只想看火焰,就搬
FireAbility+VolumetricFireMaterial+fire参数块 + 一条两点曲线,基本就能跑起来。
让效果"活"起来:值得先摸的关键旋钮 🎛️
参数在 legacySettings.js 里保留了退役时的"黄金值",迁移后按下几个,效果立刻不同:
- 火焰:
shred(边缘碎裂烈度)、tempCore/tempEdge(黑体核心 / 边缘温度)、volumeSteps(步进步数,画质与开销的权衡)、paletteBlend(0 = 纯物理辐射,1 = 手绘调色板)。 - 水面:
waveAmplitude/chop(浪与碎浪强度)、fresnel与specular(湿润高光)、translucency(薄浪尖背光)、foam(泡沫密度)、detail(命中点细波)。 - 两者共享:
streamLength(拖尾长度)、headSize(头部放大)、glow(进 bloom 的强度)。
这些值每帧被各系统读取,改滑块会立刻反映在正在飞的火球 / 水柱上——这正是整个项目"暂停中也能编辑"哲学的延续。
收个尾 ⛏️
src/archive/里真正被"雪藏"的,不只是一段旧代码,而是两个完整的 Raymarching 教学样本:一个教你在体内积分出温度与烟,一个教你在表面找回法线、菲涅尔与泡沫。读懂它们,再回头写任何新技能弹道特效,都会顺手得多。
如果只想拿走一块就走的"宝贝",优先从 VolumetricFireMaterial.js 的 blackbody() 和 OceanWaterMaterial.js 的 waterField() 这两个函数开始——一个函数里,就藏着一整团火或一汪水。
【免费下载链接】LinearAbiltyCastingThreeJS
相关推荐
探索技术宝藏:SecretFinder - 深入挖掘隐藏秘密的利器
探索技术宝藏:SecretFinder 深入挖掘隐藏秘密的利器 项目简介 是一个由安全研究者 m4ll0k 开发的强大工具,旨在帮助开发者和安全研究人员发现并提
小米MiMo-7B-MTPs vs 传统语言模型:为什么MTP层是推理能力的黄金钥匙?
小米MiMo 7B MTPs vs 传统语言模型:为什么MTP层是推理能力的黄金钥匙? 小米MiMo 7B MTPs作为新一代开源语言模型,通过创新的MTP(M
LinearAbilityCastingThreeJS陨石技能深度解析:Raymarched火焰尾迹与熔岩裂纹着色器
LinearAbilityCastingThreeJS陨石技能深度解析:Raymarched火焰尾迹与熔岩裂纹着色器 LinearAbilityCastingT
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考