【Aegisub】粒子描边特效、Vector_Move函数的使用

Vector_Move函数:
function Vector_Move(s_time,e_time,afterimage_dur,x_blur,y_blur,accel,base_pos_x,base_pos_y,max_space,scale_x,scale_y,s,x_add)
if (j == 1) then
t = 0
pos_x = {}
pos_y = {}
if (afterimage_dur < 0 ) then
afterimage_dur = 0
end
c_point_x = {}
c_point_y = {}
point = {}
i = 1
s:gsub("(%S+)", function(w) point[i] = w i = i + 1 end)
dur = e_time-s_time
i = 1
m = 0
max_x = -10000
min_x = 10000
max_y = -10000
min_y = 10000
scale_x = scale_x / 100
scale_y = scale_y / 100
while i <= #point do
c_point_x = {}
c_point_y = {}
if point[i] == "m" then
s_point_x = point[i+1]
s_point_y = point[i+2]
i = i + 3
elseif point[i] == "b" then
c_point_x[1] = s_point_x*scale_x
c_point_y[1] = s_point_y*scale_y
for k = 2, 4, 1 do
c_point_x[k] = point[i+1+(k-2)*2]*scale_x
c_point_y[k] = point[i+2+(k-2)*2]*scale_y
end
max_x = math.max(max_x,_G.unpack(c_point_x))
max_y = math.max(max_y,_G.unpack(c_point_y))
min_x = math.min(min_x,_G.unpack(c_point_x))
min_y = math.min(min_y,_G.unpack(c_point_y))
c_point_x[1] = s_point_x*scale_x+base_pos_x
c_point_y[1] = s_point_y*scale_y+base_pos_y
for k = 2, 4, 1 do
c_point_x[k] = point[i+1+(k-2)*2]*scale_x+base_pos_x
c_point_y[k] = point[i+2+(k-2)*2]*scale_y+base_pos_y
end
s_point_x = point[i+5]
s_point_y = point[i+6]
i = i + 7
elseif point[i] == "l" then
c_point_x[1] = s_point_x*scale_x
c_point_y[1] = s_point_y*scale_y
c_point_x[2] = point[i+1]*scale_x
c_point_y[2] = point[i+2]*scale_y
max_x = math.max(max_x,_G.unpack(c_point_x))
max_y = math.max(max_y,_G.unpack(c_point_y))
min_x = math.min(min_x,_G.unpack(c_point_x))
min_y = math.min(min_y,_G.unpack(c_point_y))
c_point_x[1] = s_point_x*scale_x+base_pos_x
c_point_y[1] = s_point_y*scale_y+base_pos_y
c_point_x[2] = point[i+1]*scale_x+base_pos_x
c_point_y[2] = point[i+2]*scale_y+base_pos_y
s_point_x = point[i+1]
s_point_y = point[i+2]
i = i + 3
else _G.aegisub.debug.out("Unknown drawing command. You can use only \"m\" , \"b\" , \"l\"^^;")
i = #point+1
end
c_t = 0 n = #c_point_x
if n ~= 0 then
while c_t <= 1 do
m = m + 1
pos_x[m], pos_y[m] = Bezier(n,c_point_x,c_point_y,c_t) n_x, n_y = Bezier(n,c_point_x,c_point_y,c_t+0.1)
dist = math.sqrt(math.abs(n_x-pos_x[m])^2+math.abs(n_y-pos_y[m])^2)
c_t = c_t + max_space/dist*0.1
end
end
end
maxloop(m)
end
retime("presyl",s_time+dur*(t^accel),s_time+dur*((t+1/m)^accel)+afterimage_dur)
t = t + 1/m
adjust_x = -(max_x - min_x) / 2 - min_x
adjust_y = -(max_y - min_y) / 2 - min_y
return string.format("\\move(%0.1f,%0.1f,%0.1f,%0.1f,%0.1f,%0.1f)",pos_x[j]+x_add,pos_y[j],pos_x[j]+x_blur+x_add,pos_y[j]+y_blur,0,afterimage_dur)
end
矢量移动函数的参数说明:
Vector_Move(s_time,e_time,afterimage_dur,x_blur,y_blur,accel,base_pos_x,base_pos_y,max_space,scale_x,scale_y,s,x_add)
s_time决定第一个粒子的开始时间、结束时间(其它粒子也会相应地变化)
e_time决定最后一个粒子的开始时间、结束时间(其它粒子也会相应地变化)
s_time与e_time不限正负,而且不用保证e_time-s_time>0
举例1:比如s_time填500、e_time填0,那么第一个粒子的开始时间就延后500ms,而最后一个粒子开始时间不变,剩下的其它粒子平分这中间的时间。由于每个粒子的位置不一样,所以此时的移动效果看起来就是“反向”的。
举例2:比如s_time填0、e_time填500,就有第一个粒子的开始时间不变,最后一个粒子开始时间延后500ms,剩下的其它粒子平分这中间的时间,这时粒子的移动效果看起来就是“正向”的,和第一个例子相反
举例3:比如s_time填-500、e_time填-2000,就是第一个粒子的开始时间提前500ms,最后一个粒子开始时间提前2000ms,剩下的其它粒子平分这中间的时间,这时由于最后一个粒子的开始时间比第一个粒子开始时间早,所以移动效果看起来就是“反向”的
举例4:若是s_time填0、e_time填0,就是第一个粒子的开始时间不变,最后一个粒子开始时间不变,即现在每一个粒子的开始时间都一样,此时看起来的效果就是粒子不移动,即没有矢量移动的效果,粒子只静止构成图形而已(当然如果x_blur或y_blur不为0,粒子就会有周边扩散或整体平移效果,但这个不是“描边”移动效果)
afterimage_dur为单个粒子它本身的持续时间
x_blur直接等于x方向位移大小 用于造成粒子随机扩散效果
y_blur直接等于y方向位移大小 用于造成粒子随机扩散效果
accel 加速度参数
关于base_pos_x和base_pos_y这两个参数:
这两个参数将原始绘图的(0,0)点定位在(base_pos_x+x_add,base_pos_y)
所以这两个参数决定了粒子描边移动的起点
max_space生成的两个相邻粒子间的最大距离 max_space越大就是粒子间距离越大即此时粒子越少
scale_x表示对原始矢量绘图x轴的缩放处理
scale_y表示对原始矢量绘图y轴的缩放处理
比如你想做一个心形的描边特效,scale_x和scale_y都设为100,则粒子移动的轨迹就是原本心形的边框。如果你scale_x和scale_y都设为200,那么就相当于矢量绘图放大了4倍,所以粒子移动的轨迹是4倍心形绘图的边框
s你想要描边(粒子移动)的矢量绘图(字符串)
s这一项说明:这里要填的是绘图代码。比如不能填m -3 0 b -3 4 3 4 3 0 b 3 -4 -3 -4 -3 0,而是要填"m -3 0 b -3 4 3 4 3 0 b 3 -4 -3 -4 -3 0"才行,当然你也可以先在code行定义xxx="m -3 0 b -3 4 3 4 3 0 b 3 -4 -3 -4 -3 0"然后在这项参数这里直接填xxx这种也是可以的
x_add表示在base_pos_x设定的粒子x坐标上,再在x坐标上加x_add,即在base_pos_x基础上,粒子在x方向上平移x_add
一般来说,x_add这一项填0,但是如果你想要描一个移动图形的边,就会用x_add了,因为它能做出一边描边一边移动的效果,当然这样的话x_add也不能填一个定值,而是一个会变化的值,比如(j-1)/maxj*$lwidth等等
另外,返回的move标签中,%0.1f那一部分表示保留小数点后一位
使用该函数必须的辅助函数:
Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code,function set_temp(ref,val) temp[ref] = val; return val; end temp = {} Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code,function factk(n) k = 1 if (n > 1) then for i = 2, n, 1 do k = k * i end end return k end Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code,function bernstein(i,n,t) return (factk(n) / (factk(i)*factk(n-i))) * (t^i) * ((1-t)^(n-i)) end Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,code,function Bezier(n,x,y,t) p_x = 0 p_y = 0 for i = 1, n, 1 do p_y = p_y + y[i] * set_temp("bern",bernstein(i-1,n-1,t)) p_x = p_x + x[i] * temp.bern end return p_x, p_y end 这些直接复制行
更详细的说明参考视频AV74819601