☰
LinearAbilityCastingThreeJS隐藏宝藏:归档中Raymarched火焰与水面特效的挖掘指南
2026/10/17 0:06:51 网站建设 项目流程

【免费下载链接】LinearAbiltyCastingThreeJS

项目地址:https://gitcode.com/gh_mirrors/li/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 层从粗到细堆叠(顺序正是肉眼读一团火球的顺序):

  1. 轮廓层(silhouette):路径上的一串胶囊,横截面是水滴形(浮力向上拉伸),半径被一阶低频噪声鼓动——火球外形由"米级"鼓包主导。
  2. 涡旋卷起(vortex roll-up):热气体甩出环形涡,沿尾迹后移并随年龄长大;让噪声域沿(流向、竖直)平面按行波旋转,把场"翻折"起来,形成翻滚、蘑菇状的烟团——普通 fbm 叠再多八度只能做出云,做不出卷。
  3. 湍流(turbulence):5 个逐级做域扭曲的八度,八度之间旋转去网格化,且每层都比上一层浮升更快,细结构因此跑过粗结构,撕成向上舔的火舌。
  4. 碎裂(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)很短:

  1. 搬文件和依赖回src/:例如把 FireAbility.js 及其 import 的 VolumetricFireMaterial.js 移回src/对应目录(RibbonGeometry已以 src/effects/RibbonGeometry.js 复活,可直接复用)。
  2. 合并参数块:把 legacySettings.js 里对应的fire/water块展开进 src/config/settings.js。
  3. 注册能力:在 src/abilities/AbilityManager.js 的ABILITY_TYPES登记类,并把 id 加进 settings 的ELEMENTS/ELEMENT_META。
  4. 处理基类差异:归档能力继承的是旧版(沿样条)Ability,在线版是线性Ability(spawn(origin, direction, distance))。要么移植到新版基类,要么把旧基类换个名字并排共存——项目其他部分不关心用哪个。
  5. 输入按需:只有想把"自由手绘路径"找回来时才需要 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

项目地址:https://gitcode.com/gh_mirrors/li/LinearAbiltyCastingThreeJS
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询