嗒啦啦研究3D特效的总结(2)
02/2375 浏览开发心得
详细的文档字数太多发不出去,这是简易版的。
3D 技能特效系统 - 通用技术文档
涉及文件:SkillEffects.lua
、ProjectileSystem.lua
、SkillData.lua
1. 架构总览
SkillData.lua → VisualMap (弹体视觉) / EffectMap (释放特效)
SkillEffects.lua → 材质工厂 + 特效创建器 + registerEffect 帧动画
ProjectileSystem.lua → 弹体视觉创建/更新/命中效果
释放技能:SkillSystem
→ SkillData.GetEffectType()
→ SkillEffects.Create()
发射弹体:SkillSystem
→ SkillData.GetVisualType()
→ ProjectileSystem.Fire()
2. 材质创建方法
四种材质工厂函数
| 函数 | Technique | 用途 | 需要贴图 |
|------|-----------|------|---------|
| createGlowMat(r,g,b,alpha,emI)
| PBRNoTexture[Alpha] | 纯色发光(球/粒子/光晕) | 否 |
| createTexturedGlowMat(tex,r,g,b,emI)
| PBRDiff | 有花纹的 PBR 发光(法阵) | 是 |
| createAdditiveMat(tex,r,g,b,bright)
| DiffAdd | 黑底叠加发光(剑身/闪电) | 是(黑底) |
| createUnlitAlphaMat(tex,r,g,b,bright)
| DiffUnlitAlpha | 不受灯光影响(法阵/光幕) | 是(带Alpha) |
createGlowMat 参数经验
alpha < 0.99
自动切换半透明 Technique
emissiveIntensity
:光晕 2~5,主体 5~8,粒子 10~14,核心 14~18
Metallic=0.0, Roughness=0.2
(通用值)
混合模式速查
需要贴图?
├─ 否 → createGlowMat (PBR纯色)
└─ 是 → 底色黑色?
├─ 是 → createAdditiveMat (黑色自然透明,可叠加)
└─ 否 → createUnlitAlphaMat (需Alpha通道)
3. 序列帧动画 & BillboardSet
帧索引→UV:col = idx % COLS; row = floor(idx / COLS); uvRect = Rect(col/COLS, row/ROWS, (col+1)/COLS, (row+1)/ROWS)
BillboardSet 要点:
修改属性后必须 bbSet:Commit()
faceCameraMode
:FC_ROTATE_XYZ
(完全朝相机)/ FC_ROTATE_Y
(仅Y轴)
bb.size
单位是米,bb.uv
范围 0~1
拖尾:多个 Billboard 播放延迟帧;命中:加速帧率 + 膨胀淡出
4. CustomGeometry
基本用法
lua
local geom = node:CreateComponent("CustomGeometry")
geom:BeginGeometry(0, TRIANGLE_LIST)
geom:DefineVertex(pos); geom:DefineNormal(n); geom:DefineTexCoord(uv)
geom:Commit()
geom:SetMaterial(mat)
静态 vs 动态
| | 静态(默认) | 动态 |
|--|------------|------|
| 设置 | 无需额外设置 | geom.dynamic = true
(首次 BeginGeometry 前) |
| 用途 | 创建一次不变的形状 | 每帧重建(拖尾等) |
| 每帧 Commit | 报错 Cannot set data on a static vertex buffer
| 正常 |
常用形状
月牙弧:外弧+内弧之间的弧带,正反面各一套三角形
圆柱管(createTubeGeometry
):仅侧面无盖,配合 CULL_NONE
双面可见
5. 连续拖尾(动态 CustomGeometry)
适用:物体运动时留下平滑连续尾迹(挥剑/飞行轨迹),密度由帧率决定。
核心流程(每帧):
1. 采样:记录物体两端点 {a=Vector3, b=Vector3, time=elapsed}
到缓冲区
2. 清理:移除 age > TRAIL_MAX_AGE
的旧点
3. 重建:相邻两帧 4 个端点 → 1 个四边形(2 三角形),拼接为连续带
4. 衰减:越老的点,端点向中点收缩(变窄)
关键要求:
geom.dynamic = true
(必须)
材质 SetCullMode(CULL_NONE)
(双面可见)
端点必须是世界坐标
无点/1点时仍需 BeginGeometry + Commit
(清空旧网格)
参数:TRAIL_MAX_AGE
0.3~0.8s,材质 alpha 0.5~0.8,emissive 4~8
6. 帧动画驱动(registerEffect)
lua
registerEffect(node, type, duration, function(n, elapsed, dur)
local t = elapsed / dur -- 0→1
-- 操作子节点 position/scale/rotation、光源 brightness、材质参数
end)
由 SkillEffects.Update(dt)
统一驱动
elapsed >= duration
时自动 Remove
节点
典型结构:展开阶段 → 高光阶段 → 消散阶段
7. 视觉设计模式
多层叠加
由内到外:核心(最亮最小)→ 主体 → 光晕(最透最大)→ 粒子点缀 → 点光源
| 层 | alpha | emissive | 尺寸 |
|----|-------|----------|------|
| 核心 | 0.6~0.95 | 10~18 | 最小 |
| 主体 | 0.4~0.8 | 5~8 | 中等 |
| 光晕 | 0.15~0.35 | 2~4 | 最大 |
| 粒子 | 0.7~0.9 | 10~14 | 小球 |
点光源
lua
light.lightType = LIGHT_POINT; light.range = 5.0; light.brightness = 0.0
| 场景 | range | brightness |
|------|-------|-----------|
| 飞行弹体 | 4~5 | 2~4 脉动 |
| 释放闪光 | 5~6 | 6~8 衰减 |
| 持续法阵 | 8~12 | 1~3 呼吸 |
| 命中爆炸 | 5~6 | 6~8 快衰 |
8. SkillData 映射 & 新增流程
映射(唯一数据源,改这里三处消费方自动生效):
SkillData.VisualMap[技能ID] = "视觉类型"
→ 弹体外观
SkillData.EffectMap[技能ID] = 特效编号
→ 释放特效
新增弹体视觉:ProjectileSystem
加创建/更新/命中函数 → SkillData.VisualMap
加映射
新增释放特效:SkillEffects.Type
加枚举 + effectConfigs
加配置 + 写创建函数 + effectCreators
注册 → SkillData.EffectMap
加映射
9. 缓动函数
| 函数 | 效果 | 用途 |
|------|------|------|
| lerp(a,b,t)
| 线性 | 淡出、均匀缩放 |
| easeOutQuad(t)
| 先快后慢 | 展开、亮起 |
| easeOutBack(t)
| 弹性超调 | 弹出、闪光 |
| easeInOutCubic(t)
| 对称S形 | 平滑过渡 |
附录:常见踩坑
P1. 特效过白
原因:emissive 过高 + RGB 通道差异太小 → 饱和为白。
lua
-- ❌ 白色:通道差异小(0.9,0.95,1.0) × 高倍率15 → 全饱和
createGlowMat(0.9, 0.95, 1.0, 0.8, 15.0)
-- ✅ 冰蓝:压低R通道,主次差值>0.3
createGlowMat(0.3, 0.6, 1.0, 0.7, 6.0)
规律:emissive × RGB
决定最终色。主次通道差值至少 0.3 以上才能保持色彩。
P2. 贴图不显示
| 原因 | 解决 |
|------|------|
| 路径多加了 assets/
前缀 | 直接写 "文件名.png"
或 "Textures/xx.png"
|
| 文件不存在/名字拼错 | ls
确认文件存在 |
| DiffAdd 的 brightness = 0 | 设为 1.0~3.0 |
| 加法混合贴图底色不是纯黑 | 确保非发光区为 (0,0,0)
|
P3. CustomGeometry 每帧报错
Cannot set data on a static vertex buffer
→ 加 geom.dynamic = true
P4. shape 配错导致特效不触发
SkillData
中 shape
决定走哪个系统:
"single"/"aoe"
→ SkillEffects.Create
(释放特效)
"projectile"
→ ProjectileSystem.Fire
(弹体)
近战技能配成 "projectile"
→ 释放特效不会出现。
P5. 只有一面可见
mat:SetCullMode(CULL_NONE)
— 拖尾/光幕/薄片特效必备。
P6. 特效方向不对
检查 SkillEffects.Create
是否收到 config.direction
,以及 shape
是否配对。


