Gandi 3.0文档
官网 打开编辑器
文档/扩展

粒子

「粒子」是引擎组里的一个扩展,用来做火焰、烟、火花、雨雪、烟花、魔法之类的效果。一团效果叫一个 粒子效果(下文简称效果),存在作品里,在粒子编辑器里决定它长什么样:由几层组成、每层怎么发射、 粒子怎么动、画成什么样。

做好的效果在装配编辑器的光与粒子页放到舞台上:挂在角色身上跟着走,或者摆在场景里某一处,并决定 什么时候发、画在前面还是后面。一个效果可以同时挂在很多角色上,改一次处处都变。

粒子编辑器:左边是层,中间是预览和底部抽屉(这里开着「着色器」页),右边是选中那一层的模块栈

打开方式#

先在扩展库里添加「粒子」。作品里没有粒子扩展时,粒子编辑器只显示「装上粒子扩展」按钮。这台机器上 第一次装上扩展时,屏幕上会出现一张提示卡,带「做一个粒子效果」「看示例」两个按钮,只出现一次。

位置 操作 结果
顶栏「全部功能」 「粒子」(可拖回顶栏) 打开上次编辑的效果;没有时进入新建页
积木栏(粒子分类) 「新建粒子效果」「粒子编辑器」按钮 进入新建页 / 打开上次编辑的效果
粒子积木的右键菜单 「编辑粒子效果「名字」」「新建粒子效果」 前者只出现在带效果下拉框的积木上
资源面板 粒子卡片上的「编辑」、双击卡片、右键「在粒子编辑器中打开」 打开这个效果
资源面板 粒子分组标题上的「新建粒子效果」、空白处右键「新建粒子…」 进入新建页
光与粒子页 选中发射器后的「编辑效果」;「粒子」下拉最后的「新建空白效果…」「复制这个再改…」;发射器工具的「新建空白效果…」 打开 / 新建并挂上
粒子编辑器页头 名字右边的 ▾ 换到作品里另一个效果、某个内置模板,或「新建粒子效果…」

粒子编辑器是编辑器组里的一个页签,和造型、声音并排。同一时间只编辑一个效果,换效果不换页签。

新建#

新建页分两块。上面是「作品里的效果」(作品里已经有效果时才出现),点一下打开。下面是「新建粒子效果」, 右上角在「从模板」和「看示例」之间切换;第一张卡永远是「空白」:一层,只有发射器、持续发射、初始值和外观, 其余模块自己加。卡片显示效果的静帧, 鼠标停在卡片上时播放。点一张卡,就在作品里新建一份并打开,打开后就能改。

模板共 15 个:火焰、烟雾、火花、爆炸、雨、雪、雾、尘埃、散射弹幕、环形弹幕、命中爆点、粒子尾迹、 带状拖尾、法术光球、雨水涟漪(脚本)。

示例共 13 个,每个演示一种做法,卡片上的小字就是它演示的东西:

示例 演示
烟花 事件链:火箭「死亡时」炸开,火花「死亡时」再闪一下
雨和水花 雨丝落地「死亡时」溅起水花
传送门 圆环沿边发射,漩涡把粒子卷进中心
魔法尘 噪声场:粒子顺着气流飘,大小忽大忽小
爱心 路径形状,粒子朝外发射
螺旋 方向写成式子 time * 540
萤火虫 代码模块:飘向鼠标、自己晃动
文字粒子 文字形状,只从边缘发射
泡泡、星星、能量球 外观着色器
热浪 外观着色器 + 扭曲混合
冲击波 扭曲混合,不写代码

效果的名字不和作品里已有的效果、也不和模板重名,重名时自动加序号:从模板「火焰」新建的叫「火焰 2」。 从示例新建的沿用示例的名字;「另存一份」「复制一份」得到的名字后面加「副本」;空白的叫「新粒子」。 一个作品最多 128 个效果。作品里按 id 引用效果,改名不影响用到它的地方。

直接打开内置模板#

从页头的 ▾ →「内置模板」、积木右键、或者一个挂着模板的发射器的「编辑效果」,打开的是模板本身。这时页头写着 「内置模板 · 一改就另存一份」,撤销、重做、另存、删除按钮不显示。第一次改动时,编辑器把模板另存为作品里的 效果,提示「模板不能改,已另存为「名字」」,然后切到这一份接着改。从光与粒子页打开的,那个发射器 同时改挂另存出来的这一份。

界面#

粒子编辑器分五块:页头;左栏「层」;中间的预览;预览下面可以拉出来的底部抽屉;右栏选中那一层的模块栈。

页头从左到右:

控件 作用
名字 点击改名(内置模板不能改)
▾ 换一个效果,或新建
放到舞台上 打开装配编辑器的光与粒子页,拿起发射器工具并选好这个效果,在角色或场景上点一下就放上去
「参数」 打开 / 收起底部抽屉的「参数」页,右边的数字是参数个数
撤销、重做 见「保存、撤销与生效」
另存一份 复制这个效果并打开副本
删除这个效果 确认框里写着有几个角色挂着它,删掉后它们改发火焰

层#

一个效果由一层或几层组成,最多 16 层。每一层是一个发射器,有自己的模块栈。

  • 标着「主」的是主层:放到舞台上时,放置页的位置和方向跟着它,其余几层按各自相对主层的位置摆。
  • 由「变成另一层」或事件生成粒子的那一层,缩进挂在来源层下面,第二行写明来历,比如「火焰 寿命 68% 时变来」 「火箭 死亡时生成」。其他层的第二行是速率(「40 颗/秒」)、「爆发 30」、「只由事件生成」或「不自己发」。
  • 接了物理的层标着「物理」。
  • 点名字改名。行尾的眼睛只在预览里隐藏这一层,不影响作品。
  • 拖动一行改叠放顺序。
  • 右键:设为主层、往前叠(画在上面)、往后叠、复制一层、删除。只剩一层时不能删。
  • 标题栏的 + 打开「加一层」浮层:第一张是「从零开始」(只有发射和外观的一层),下面是模板的主层,按 火与烟、爆裂与弹幕、天气、拖尾与光分组,卡片上是它的样子,鼠标停上去就放起来;最下面可以复制当前层。 「粒子尾迹」「带状拖尾」只在发射器移动时出粒子,卡片上写着这一点。

预览#

预览用和舞台同一套模拟和同一套着色器,看到的就是舞台上的样子。区别有三点:预览里没有光照扩展的照明,辉光按 「光照没开」时的方式画一圈光晕;不跑物理;外观着色器不会因为太慢被停用。预览不经过舞台,不算进作品的粒子 总数,也不需要点绿旗。

  • 左上角是画布工具;接着是放大倍数(相对舞台原大小,不是 100% 时标成蓝色)、「看全效果」「看整个舞台」两个按钮; 右边切换背景:深、浅、棋盘、舞台(选中那一刻舞台的样子)。背景记在这台机器上。
  • 虚线框是舞台。放大倍数是 100% 时,粒子和它的比例就是运行时的比例。
  • 打开一个效果时先框住它:按粒子能飞多远放大,最多 5 倍,满屏的效果看整个舞台。
  • 滚轮缩放,在空白处拖动平移,双击空白处回到装下整个舞台的大小。
  • 打开一个效果时直接从缩略图那一刻(一般是第 0.8 秒)开始放,不会先看到一块空画面。
  • 只放一次的效果(每层都没有持续发射、按距离发射、定时爆发,但至少一层有爆发,比如爆炸):时间轴写着 「放一次 · 放完自动重播」,粒子放完隔 0.6 秒自动再放;缩略图拍它刚炸开的那一刻。
  • 时间轴在控制条上面。主层有持续时长时,时间轴就是这段时长,写着「持续 N s」(循环的加「循环」); 一直发的写「一直发」,长度是最长寿命的两倍。主层有爆发时,起点画一道标记。拖时间轴会暂停,并显示那一刻的样子。
  • 控制条:暂停 / 播放、重播、¼× ½× 1× 2× 变速;右边是当前粒子数和模拟一帧的毫秒数。到了全局粒子上限或 某一层自己的上限,这一段变红并写明原因。有层接了物理时写着「物理在舞台上生效」。

页签看不见、窗口失去焦点、30 秒没有任何操作时,预览停在当前帧;鼠标一动就接着播。手动按了暂停的,要手动按播放。

画布工具#

工具 快捷键 用法
选择 V 拖手柄改位置、方向、散布、形状、重力
放一层 A 在「放一层」浮层里选放什么(和左栏 + 同一个),再在画布上点一下
画路径 — 形状模块选「路径」后点「在画布上画」进入;每点一下加一个点,可以拖点

选中的层在画布上画出这些手柄:

手柄 拖动的效果
空心圈(发射点) 挪位置;按住 Shift 按 10 对齐
方向箭头 同时改方向和速度,箭头尖大约是一颗粒子飞出去的最远处(半秒,寿命更短时按寿命);按住 Shift 只改方向,吸附 15°。散布 360° 时只剩箭头尖,拖它改速度
扇形两边的点 改散布;散布大于半圈时扇形只画虚线
形状边上的点 线改长度,其余改宽和高
蓝色箭头 改重力的方向和大小;没有重力时是一截虚线,照样可以拖出来
绿色十字 漩涡、吸引到一点、区域阻力这几种力的中心;有范围时外面画一个圈

画布上右键:空白处打开「在这里放一层」浮层,选好的那一层放在右键的位置;层的圆点上是层的右键菜单,最后一项 「在这里放一层…」。

其他键盘操作:Delete 删除选中的层;方向键挪 1,按住 Shift 挪 10;Esc 回到选择工具。

模块栈#

右栏是选中那一层的模块栈,按用途分六组:

组 放什么
发射 发多少、什么节奏
起点 从哪出发、往哪飞、活多久
运动 重力、风、各种力、碰撞
外观 形状、大小、颜色、拖尾、发光
子粒子 在某一刻生出别的粒子:炸开、溅起、变成烟
自定义 设置属性、写代码
模块库:左边按组筛选,中间是模块和一句说明,右边是停在上面那个模块的实时演示

不用的模块不出现在栈里;空的组写着一行这里放什么,点它和点 + 一样。每一组标题上的 + 打开模块库: 左边按组分类(也有「全部」),顶上可以搜索,回车加第一个;每个模块有一句说明,鼠标停在上面时右边用真的粒子 引擎演示效果。只能有一个的模块加过之后变灰,写着「已添加」;力、设置属性、子粒子事件可以加任意多个。

每张模块卡片:

  • 标题点一下展开 / 收起,收起时后面是摘要。展开状态记在这台机器上。
  • 左边的把手可以在同一组里拖动排序。组里靠后的在靠前的基础上算,比如两个设置属性都改大小时,后一个作用在 前一个的结果上。
  • 开关把模块临时关掉,设置保留;关掉的模块完全不起作用。垃圾桶删掉模块。
  • 「发射器」「初始值」「外观」三个是固定的,不能关也不能删,排在各自组的最前面。

底部抽屉#

四页:「参数」「属性」「代码」「着色器」,分别见后面几节。拖顶边改高度,高度和上次打开的页记在这台机器上。 右上角的箭头收起抽屉。

模块#

方向 0° 朝上,顺时针为正,和 Scratch 的方向一样。

发射#

模块 内容
发射器(固定) 持续(0 = 一直发)与循环、预热、上限、坐标(世界 / 局部 / 屏幕)、随机种子、绘制层、发射区域跟着镜头走
持续发射 速率(颗/秒)
爆发 开始时(循环的话每一轮开始时)一次放出多少颗,可以均匀排一圈
定时爆发 在第几秒放多少颗、重复几次(0 = 一直重复)、隔多久、概率、均匀排一圈;最多 16 把
按距离发射 发射器每移动多少像素放一颗,停下就不放
只由事件生成 这一层自己不发,只由别的层的子粒子事件生成

用积木放的效果(「我的发射器 [名字] 立即发射 N 个」)一般关掉持续发射、只留爆发:积木把整个效果放一次, 主层放 N 颗,其余几层各按自己「爆发」的数量一起放。挂着它的角色隐藏或克隆体被删除时,发射器不再发, 已经放出去的粒子照样飞完,所以「立即发射 → 隐藏 → 删除克隆体」看得到整个爆炸。

坐标:「世界」是粒子留在出生的地方,「局部」是跟着发射器一起动,「屏幕」是不随镜头动。绘制层(角色后 / 角色前 / 最前)只管用积木创建的发射器;放到角色、场景上的按放置页选的层。

起点#

模块 内容
形状 粒子从哪里出生,见下表
初始值(固定) 寿命、速度、方向、散布、大小、旋转、角速度
出画回收 飞出画面就回收重发,适合满屏的雨雪;余量(飞出多远才算出去)、延迟
形状 设置
点 —
线 长度
圆、矩形 宽、高,可以只从边缘发
圆环 宽、高
弧 宽、高、起始角度和转过的角度,可以只从边缘发
造型 选一张造型(也可以填图片网址或作品里的图片文件名),从整块或只从边缘发,可以让粒子取那一点的颜色
文字 文字、字体,其余同造型
路径 在画布上画的点,可以首尾连起来;「清空」删掉所有点

弧、造型、文字、路径还有「朝向」:不跟、朝外(沿法线)、沿边。选了朝外或沿边,「方向」变成在这之上再偏多少。

运动#

模块 内容
重力、风 X、Y 两个分量
阻力 越飞越慢
抖动 每颗各自晃动:幅度、频率
速度随寿命 一条曲线,见「曲线与颜色」
碰撞 碰到碰撞体时消失 / 反弹 / 穿透;弹性、穿透次数、半径、和 16 组碰撞体里的哪几组相撞
物理 交给物理世界,见「物理」
力 七种,见下表;一层最多 16 个
力 作用 设置
噪声场 顺着看不见的气流飘,不聚团 强度、疏密、变化快慢、范围
湍流 更乱更碎的气流 同上
漩涡 绕一个点打转 旋转(正数顺时针)、往里吸、中心、范围、衰减
吸引 / 排斥 拉向一个点、鼠标或某个角色;负数是推开 拉向、强度、中心、范围、衰减
限速 速度不超过多少 最快(像素/秒)
区域阻力 某一圈里越飞越慢 强度、中心、范围、衰减
流场图 按一张造型的颜色走:红色多往右、绿色多往下,灰色不动 造型、铺多宽多高、强度

中心相对发射器,也可以在画布上拖绿色十字。范围为 0 时整个画面都受力;范围大于 0 时可以选衰减(不衰减 / 线性 / 平滑)。

外观#

模块 内容
外观(固定) 形状或贴图、颜色、混合、朝向、宽高比,见下文
大小 / 透明度 / 旋转随寿命 一条曲线,见「曲线与颜色」
颜色随寿命 一条颜色渐变
拖尾 发射器后面一串 / 发射器后面一条带 / 每颗粒子一条
光照 辉光、照亮、照亮半径、被场景光照亮,见「光照」
外观着色器 用代码决定每颗粒子画成什么样,见「外观着色器」

模块库「外观」里还有三张现成的设置属性:越快越大、颜色随机、忽大忽小,见「设置属性」。

「颜色」一行直接选一个颜色(写成两头一样的「颜色随寿命」,没有这个模块时自动加上);已经是一条渐变时这里只 画出来,改渐变去「颜色随寿命」。

外观的「样子」有两种:

  • 内置形状:柔光、圆、方、线条、圆环、星星、十字光、火苗。
  • 贴图:选一张造型,或填图片网址、作品里的图片文件名。「画一张」在当前角色上新建一张造型当贴图,并切到 造型编辑器去画,画完粒子跟着变。「多张随机」让每颗粒子出生时从几张里随机挑一张,最多 16 张。序列帧填 列数和行数(各最多 64),可以按帧率循环或按寿命播完,可以随机起始帧、帧间混合。

混合方式:

混合 适合
普通 一般情况
叠加 越叠越亮:火、光
滤色 提亮但不过曝:雾、光斑
正片叠底 越叠越暗:烟尘、墨迹
扭曲 把粒子后面的画面扭一扭:热浪、冲击波,见「扭曲」

朝向:固定、朝速度(总是指着飞的方向)、拉伸(越快越长,适合雨丝、流星)。

拖尾选「每颗粒子一条」时,长度是每颗粒子记住的点数(2–32);选「一条带」时有寿命、宽度和断开距离,发射器 一帧挪得比断开距离远时拖尾断开重来。

子粒子#

模块 内容
变成另一层 寿命到某一刻变成另一层的粒子(火变成烟):变成哪层、时机(寿命比例或秒)、概率、继承速度、继承大小
死亡时 / 碰撞时 / 出生时 / 每隔一段时间 / 每走一段路 在那一刻于粒子所在处生成别的粒子,或发一条广播

后五种统称事件,设置项:

  • 在哪一层生成:自己(出生时除外)、别的层,或「新建一层…」,后者建一个只由事件生成的新层。
  • 生几颗、概率、继承速度(1 = 带着原来那颗的速度)、继承颜色、继承大小、继承属性。
  • 发广播:作品运行时发一条 Scratch 广播,用「当接收到」接住;同一个名字一帧最多发一次。积木 「粒子事件的 [x / y / 广播名 / 效果]」读最近一次带广播的事件。

事件生成的粒子再触发事件,最多套 3 层;一步里由事件生成的粒子最多 2048 颗。一层最多 16 个事件。

自定义#

模块 内容
设置属性(每帧 / 出生时) 把任何属性设成、加上或乘以一个值,见下文
代码模块 见「代码模块」

「设置属性」有出生时和每帧两种,写成一句话:把 某个属性 设为 / 加上 / 乘以 某个值。每帧的「加上」是 「每秒加」。

  • 属性:大小、透明度、颜色、速度、旋转、角速度、横向速度、竖向速度、寿命(只在出生时)、自定义属性; 菜单最后一项「新建属性…」直接新建一个。
  • 值:常数、随机(最小到最大)、曲线、两条之间(每颗在两条曲线之间随机取一条)、式子。颜色是固定或渐变。
  • 曲线和渐变的横轴可以选:寿命进度、年龄(秒)、速度、发射器时间、每颗的随机数、某个自定义属性。选年龄、 速度、发射器时间或属性时,「到」填横轴的终点。出生时没有寿命进度和年龄。

设置属性出现在加它的那一组里:从「外观」加的「越快越大」在外观组,从「自定义」加的在自定义组;之后改它改的 属性也不挪组。一层最多 32 个设置属性。

数值从哪来#

模块里大多数数值右边有一颗小钮,点开选这个数从哪来:

模式 钮上的字 含义
常数 = 一个数
随机 ⚄ 每颗粒子在最小到最大之间抽一个;只有寿命、速度、大小、旋转、角速度这类范围值有
随时间变化 ∿ 按发射器自己的时间走一条曲线
式子 ƒ 写一行式子,见「式子」
效果参数 ◆ 挂到一个效果参数上,见「效果参数」;菜单里也可以「新建参数…」

「随时间变化」:范围值是整段乘上曲线(纵轴是倍数),普通数值直接取曲线的值。发射器有持续时长时,横轴是 发射器的一轮;一直发的发射器在曲线下面填「一轮」多少秒、要不要循环。点数值旁边的小曲线可以再次编辑。

「随时间变化」和「式子」只对这些字段开放:速率、寿命、速度、大小、方向、散布、旋转、角速度、重力、风、 阻力、抖动幅度、形状的宽和高。颜色随寿命的渐变只有「固定颜色」和效果参数两种。

效果参数#

效果参数是效果对外的旋钮,比如篝火的「强度」「主色」。在抽屉「参数」页里声明,然后在任何数值的模式钮里 挂上去。

  • 每个参数有名字、类型(数 / 颜色 / 开关)、默认值;数还有范围。一个效果最多 16 个参数。
  • 名字后面的「N 处」是有几处字段挂在它上面。删掉参数,挂在它上面的字段回到原来的值。
  • 「试一下」只改编辑器里的预览,不改效果。

挂上去之后:普通数值等于「参数 × 倍数」;范围值整段乘上「参数 × 倍数」,随机幅度保留;颜色渐变换成参数颜色的 色相和饱和度,明暗层次保留。

放到舞台上以后,光与粒子页每个发射器的「只改这里」里可以各调各的参数值。作品运行时用积木改:

  • 「把我的发射器 [名字] 的效果参数 [参数] 设为 [值]」:改这个角色身上的发射器,「我的粒子恢复成物体的设置」 会把它清掉。
  • 「把发射器 [ID] 的效果参数 [参数] 设为 [值]」:改用积木创建的发射器。

自定义属性#

属性是每颗粒子自己带的数,比如「热度」:出生时随机给一个,每帧慢慢降,颜色和大小按它变,炸开生出的火花 还能继承它。在抽屉「属性」页声明,一个效果最多 16 个。

  • 每个属性有名字和出生时的值;「代码里」一行是它在式子和代码里的写法(p. 加 id),式子和代码里也可以用名字。
  • 「设置属性」可以写它,曲线和渐变可以按它走,事件可以「继承属性」。
  • 勾上「给着色器」的属性送进外观着色器,最多 4 个。
  • 名字后面的「N 处」是有几个「设置属性」写它或按它走。

式子#

数值和「设置属性」的值都可以写成一行式子,比如 sin(time * 3) * 40 + 60、p.random * 20、强度 * 60。 边写边检查,写错时标红并说明错在哪,写错的不会存进去,粒子照旧用上一版;按 Esc 放弃这次修改。

p 只能用在「每颗粒子」的地方:初始值里的寿命、速度、大小、旋转、角速度(每颗出生时算一次),以及设置属性 的式子。其余字段(速率、方向、重力……)是整个发射器的数,每一步算一次,用 p 会报错。

写法 含义
+ - * / %、^ 或 **、括号 四则运算、取余、乘方
< > <= >= == !=、&& || !、条件 ? 甲 : 乙 比较和逻辑,成立为 1、不成立为 0
p.age p.life p.progress 活了几秒、寿命、寿命进度(0–1)
p.x p.y p.vx p.vy p.speed 位置、速度分量、速度大小
p.size p.rotation p.spin p.opacity 大小、旋转(度)、角速度(度)、透明度
p.random 这颗粒子自己的随机数(0–1)
p.属性 自定义属性,写 id 或名字
time t dt 发射器跑了几秒;这一轮走到哪(0–1,一直发时为 0);这一步多长
pi e 常数
参数名 效果参数;开关为 1 或 0,颜色参数不能用

函数:sin cos tan asin acos atan atan2 abs sqrt pow exp log floor ceil round sign min max clamp(v, a, b) lerp(a, b, t) smoothstep(a, b, x) step(edge, x) fract mod(a, b) rand(a, b) noise(x, y)。

  • rand(a, b) 取 a 到 b 之间的随机数,rand(b) 是 0 到 b,rand() 是 0 到 1。出生时的式子每颗抽一次; 每帧的式子里每颗粒子固定一个值。
  • noise(x, y) 是连续变化的噪声,大约在 -1 到 1 之间。
  • 算出来不是有限的数时按 0 算。

代码模块#

代码模块用 JavaScript 写每颗粒子怎么动。在模块库「自定义」里加「代码模块」,或者在抽屉「代码」页点 「给这一层写代码」,会写好一个模板并打开「代码」页。

函数 什么时候跑
onSpawn(p, ctx) 每颗粒子出生时
onUpdate(p, ctx) 每颗粒子每一步,在这一步的运动和碰撞之后
onCollision(p, ctx) 撞到碰撞体时
onDeath(p, ctx) 消失时;这里只能生成别的粒子
p 的字段 含义
x y vx vy 位置(发射器坐标系)、速度(像素/秒)
size life age opacity 大小、寿命、年龄(秒)、透明度(0–1)
rotation spin 旋转、角速度(度)
progress 寿命进度(0–1),只读
color,red green blue 颜色 #RRGGBB,或分开的分量(0–1)
属性名 自定义属性,按 id 或名字读写,如 p.heat
data 自己记的数,每颗最多 16 个名字
kill() 让这颗粒子消失
ctx 的成员 含义
dt time 这一步多长;发射器跑了几秒
width height 舞台尺寸
mouse 鼠标在舞台上的位置
camera 镜头的 x y zoom rotation
hit onCollision 里撞到了什么:colliderId targetId x y normalX normalY
reason onDeath 里消失的原因:lifetime collision recycle script convert
emit(层名, 数量, 覆盖) 在这颗粒子的位置、同一效果的另一层生成粒子;一次最多 256 颗
target(角色名) 角色现在的舞台坐标,没有这个角色时为 null
worldPosition(p) screenPosition(p) 这颗粒子在舞台上 / 屏幕上的位置
random(min, max) clamp lerp 随机数和常用运算

emit 的第三个参数可以覆盖新粒子的 x y vx vy velocity size life age rotation spin opacity color data。kill、emit 在这一步结束时统一执行。

「代码」页顶栏:

  • 状态:「没有错误」或「第 N 行:说明」,出错的行画红色波浪线。
  • 「插入片段」:左右摆动、追着鼠标跑、离鼠标近就逃、按属性变色、死的时候炸开、碰到就变色。
  • 「运行」:取消勾选时代码不跑。
  • 「去掉」:这一层不再用这段代码,代码留在效果里。

输入 p.、ctx. 时有补全和说明。停手 0.4 秒检查一次,写得通才存。

代码在沙箱里跑,只支持 JavaScript 的一部分:变量用 let / const,不能用 var;可以用函数、if、 for、while、Math;不支持正则。限制:

项 上限
代码长度 32768 字符
函数个数 32
函数调用层数 24
一次回调执行的指令 4096 步,超出算出错
数组 / 对象 64 项 / 32 个字段
一个效果里的代码 32 段

运行时出错,这一层的代码停止运行。所有代码共用每一步的执行预算,预算用完时剩下的回调这一步不跑,下一步照常。

外观着色器#

外观着色器用 GLSL 写一个函数 vec4 look(Particle p),决定每颗粒子画成什么样:拿到它的位置、颜色、寿命、 随机数,返回颜色(rgb)和不透明度(a)。

在模块库「外观」里加「外观着色器」,或者在抽屉「着色器」页挑一个模板开始。模板 13 个:圆点、贴图、扩散光环、 彩虹、闪烁星、烟、火苗、溶解、等离子、泡泡、细胞、热浪、用效果参数。选「热浪」时混合方式同时换成「扭曲」。

vec4 look(Particle p) {
    float d = length(p.local);
    vec3 c = hsv2rgb(vec3(p.seed + time * 0.3, 0.7, 1.0));
    return vec4(c, (1.0 - smoothstep(0.3, 1.0, d)) * p.color.a);
}
p 的字段 类型 含义
uv vec2 粒子方块里的位置,0–1,左下角是 (0, 0)
local vec2 以中心为原点,-1–1
color vec4 这颗粒子现在的颜色,随寿命的颜色、设置属性、透明度都已算进去
progress float 寿命进度 0–1
age life float 活了几秒、一共能活几秒
seed float 这颗粒子自己的随机数 0–1,一辈子不变
size float 大小(像素)
velocity vec2 速度(像素/秒)
custom vec4 勾了「给着色器」的属性,按声明顺序放进 x、y、z、w
frame float 序列帧的第几帧
可以直接用的 含义
time 发射器跑了几秒
param(i) 第 i 个效果参数(从 0 数,最多 16 个);开关为 1 或 0,颜色参数读到 0
sampleMain(uv) 外观里选的贴图;没选贴图时是白色
behind(偏移) distortion 粒子后面的画面和扭曲强度,只在混合方式为「扭曲」时有,见「扭曲」
noise(v) fbm(v) voronoi(v) 噪声(-1–1)、分形噪声、细胞距离
hsv2rgb(c) rgb2hsv(c) 换色
sdCircle(p, r) sdBox(p, b) sdStar(p, r) 圆、方框、五角星的距离场

「着色器」页顶栏的「能用什么」把这些插到光标处,「换模板」换成另一个模板,「去掉」让这一层不再用着色器 (代码保留,撤销能找回)。输入时有补全。

着色器停手 0.4 秒后在一块小画布上真正编译一次,编得过才存;出错的行标红,最多列 8 条。以下写法一律不允许:

  • # 开头的预处理指令;
  • 声明 uniform、layout、attribute、varying、输入输出;
  • while、do;for 只能写成 for (int i = 0; i < 16; i++) 这种次数写死的形式,最多 64 次;
  • gl_、webgl_ 开头的名字,自己写 main。

源码最长 8KB,必须有 vec4 look(Particle p)。

出问题时的处理:

情况 结果
编译不过 舞台上这一层按默认外观画
太慢 舞台上粒子的显卡耗时连续 90 帧超过 10ms 时,最近用上的那段着色器停用,退回默认外观
显卡出错 着色器第一次用上后 3 秒内显卡上下文丢失,这段着色器在这台机器上被隔离,不再启用

打开「着色器」页时,被停用的写着「太慢,舞台上已停用」,被隔离的写着「上次用它时显卡出了问题,已停用」, 点「再试一次」解除。停用和隔离都只针对那一段代码,改动代码之后,新的代码重新编译和启用。

其他限制:用了外观着色器的层不受场景光照亮,也不画自带的辉光光晕。外观形状选「火苗」且没用贴图时, 着色器不生效。

扭曲#

混合方式选「扭曲」时,粒子读取它后面已经画好的画面并挪动一下再画出来,适合热浪、冲击波。外观里的 「扭曲强度」是后面的画面最多挪几像素(默认 16,最大 200)。

没写外观着色器时,每颗粒子把后面的画面从中心往外推,边缘淡掉,本身的颜色不画出来。写了着色器时,用 behind(偏移) 读后面的画面,偏移以像素计,distortion 就是扭曲强度,例如模板「热浪」:

vec4 bg = behind(wave * distortion * edge);

曲线与颜色#

「大小 / 透明度 / 速度 / 旋转随寿命」、「随时间变化」和「设置属性」的曲线用同一个编辑器。横轴从 0 到 1, 点之间按直线连,和运行时的算法一样。

  • 随寿命的四条曲线和范围值的「随时间变化」上面有一排常用形状(恒定、渐大、渐小……),点一下整条换掉。
  • 双击空白处在那一点加一个点,最多 32 个。
  • 拖点改值;首尾两个点只能上下动。中间的点拖出框外松手就删掉,选中后按 Delete 也可以。
  • 选中一个点后方向键微调,按住 Shift 一次走得更多。下面一行写着选中点的位置和值。

颜色渐变用造型编辑器里的同一条色标条:双击加一个色标,拖动改位置,往下拖开就删掉(至少留两个),下面的 取色框改选中色标的颜色,最多 16 个色标。

物理#

「物理」模块要装物理扩展。打开后,这一层在舞台上由物理世界推动,和装了物理的角色、平台互相碰撞;「对物体 产生反作用」开着时还会推动它们。「碰撞」模块的设置这时只在没装物理扩展时使用。

  • 常用项:模式(场景 / 颗粒 / 液体)、碰撞半径、摩擦、弹性、重力倍率、可碰撞图层、对物体产生反作用、点数量 上限;液体还有粘度和表面张力。其余在「更多」里。字段由物理扩展提供。
  • 挂在角色上的每一只(包括克隆体)各自接入物理世界。
  • 一个物理世界总共 1 万个物理点、128 组;点数量上限默认 200。超出时这一只照常发粒子,只是不走物理, 在光与粒子页选中这个发射器时会写出原因。
  • 预览里不跑物理;左栏这一层标着「物理」,控制条写着「物理在舞台上生效」。

光照#

「光照」模块里的辉光不依赖别的扩展;「照亮」和「被场景光照亮」要装光照扩展:

  • 「照亮」大于 0 的层在舞台上是光源,照亮「照亮半径」内的角色和墙。整个作品的粒子默认最多占 32 盏灯。
  • 勾了「被场景光照亮」的层(比如烟)跟着场景的环境光、日月光和灯变亮变暗。
  • 装了光照扩展时,辉光交给光照的泛光,不再额外画一圈光晕;没装时按原来的方式画光晕。

保存、撤销与生效#

改动先落在编辑器里,预览立刻跟上;停手 0.3 秒后写进作品。每写一次,舞台上挂着这个效果的发射器在下一帧按新 参数重建,已经飞出去的粒子不受影响,所以作品运行中也能边改边看。代码和着色器是停手 0.4 秒、检查通过后才写入。

Ctrl + Z 撤销,Ctrl + Y 或 Ctrl + Shift + Z 重做,页头也有这两个按钮。撤销只在粒子编辑器里 有效,每个效果各自一条,最多 100 步;连续拖同一个数字、连按方向键合成一步。页头改效果名字不进撤销。

用积木「创建发射器 … 用 [效果]」建出来的发射器是创建那一刻的副本,之后改效果不会改到它。

在资源库里#

资源面板里粒子是单独一类:筛选条上的「粒子」,网格里单独一组,组标题上有「新建粒子效果」。内置模板和示例 不进资源库。

  • 缩略图是效果某一刻(一般是第 0.8 秒)的静帧,不管深浅主题都是深色底;效果改了缩略图跟着重画。
  • 鼠标停在卡片上时,缩略图上出现「编辑」。
  • 使用数是有几个角色挂着它,为 0 时这一格变暗,和图片、声音的「未使用」一样。
  • 右键:在粒子编辑器中打开、重命名、复制一份、删除。
  • 删除时,如果有角色挂着它,确认框里写出个数;删掉之后那些角色改发火焰。

相关#

  • 引擎:装配编辑器的光与粒子页,把粒子放到舞台上
  • 资源库
  • 光照:粒子照亮周围、被场景光照亮