ass文件下载地址:http://pan.baidu.com/s/1boG3toj (以后的模板将会在本链接中公开)
应用这部分模板需要Yutils拓展,按这个帖子配置
在上次的帖子中我们分析了该特效的文本部分代码
此次,我们接着对较为复杂的图形部分进行解析
先从code行开始
code行 | |||
行号 | 修饰语 | 功能 | 备注 |
1 | once | 固定用法,利用Lua API获取视频分辨率,计算几何缩放比率 | |
2 | once | set temp函数 | 为6行的辅助函数 |
3 | once | fact(阶乘)函数 | 为7行的辅助函数 |
4 | once | Bernstein函数 | 为8行的辅助函数 |
5 | once | Bezier函数 | 为9行的辅助函数 |
6 | once | Vector Move函数* | 修改过 |
7 | once | 调 切歌 玛利亚 矢量剪影绘图 | |
8 | line all | 绘图转边框 移动矢量位置 |
对黄色部分内容感兴趣可以以英文为关键词在各大搜索引擎搜索相关资料 主要说明Vector Move函数及其参数的含义(若显示不完全请点击展开代码或新窗口查看代码按钮):
Vector Move函数主要用来实现解析矢量图形,将矢量图形边缘路径做像素化,经常用来制作手写效果,本例中使用通过修改该函数及其参数来实现边缘粒子扩散效果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
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,<span style="color: #ff0000;">x_add</span>) 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 |
参数名 | 模板行填写示例 | 含义 | PS |
s_time | (j-1)*$ldur/maxj | 粒子开始时间调整。按照最大循环数平分行持续时间 | 相当于retime函数中presyl模式的两个参数 |
e_time | 0 | 粒子结束时间调整。 | |
afterimage_dur | 1000 | 粒子持续时间 | |
x_blur | math.random(-30,10) | x方向位移范围 | 用于造成粒子随机扩散效果 |
y_blur | math.random(-10,10) | y方向位移范围 | |
accel | 1 | 加速度参数 | |
base_pos_x | $lleft-40 | 计算基点x坐标 | 与第8行中的对应数值保持统一 |
base_pos_y | $middle-40 | 计算基点y坐标 | |
max_space | 2 | 生成的两个相邻粒子间的最大距离 | 距离越大则粒子越少 |
scale_x | 100 | 粒子化前对矢量绘图x轴的缩放处理 | |
scale_y | 100 | 粒子化前对矢量绘图y轴的缩放处理 | |
s | shirabe | shirabe为第7行中定义的矢量绘图(字符串) | |
*x_add | (j-1)/maxj*($lwidth+40) | 按照最大循环数平分图形在$ldur期间的x方向总位移 | 此部分为自行添加的参数 |
1 |
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) |
格式化返回move标签,添加x_add(x轴增量)参数,实现粒子初始坐标随剪影边框移动
至此code行内容说明完毕
template 行就相对简单了
以调的动画为例,因模板只有两行,所以不列表,直接以文本形式进行说明
第9行:
{主体白色,淡入淡出,开启绘图,位移,边框模糊,对齐方式7},shape_outline[1]为第8行中定义的调的剪影边框
对圆点图形应用Vector Move函数,紫色部分已经在Vector Move函数参数表格解释过
其余部分代码均为调节圆点样式
至此,EN3这首歌的全部代码已经基本说明完毕
如果有疑问,可以在评论中回复
战姬绝唱Live 2016中你最喜欢的字幕特效?
投票总人数: 216
请把你的脑子给我。我脑子学不懂
跪大佬,不知以后还会不会有这样的教程
跪domo..看看能看懂多少w
给大神跪,学习学习w
先跪一波~