TUCaptions

 找回密碼
 立即註冊
搜索
快捷導航
  • TUcaptions 現正社員招募中!! 想參與字幕製作的快來社員招募板報名吧!!
查看: 25673|推文: 10
列印 上一主題 下一主題

TUcaptions - Aegisub特效腳本教學 (最後編輯時間:2014/11/11)

[複製連結]
跳轉到指定樓層
原PO
發表於 2014-10-26 16:45:26 | 只看該作者 推文獎勵 |倒序瀏覽 |閱讀模式
本帖最後由 tgvr531 於 2016-2-3 10:57 編輯

前言
本文尚有小缺失以及邏輯不嚴密的地方,也請各位學習者多指點。

預備知識

mod插件(請放在aegisub安裝資料夾內的Aegisub\csri,直接覆蓋原資料夾內的檔案):


在閱讀本教學文之前,請先閱讀以下5篇教學文,重複的概念將不再重新贅述。

aegisub基本指令教學:
Aegisub基本教學 (by 哈任):http://tucaptions.org/forum.php?mod=viewthread&tid=914
Aegisub進階教學 (by 圓光少女):http://tucaptions.org/forum.php?mod=viewthread&tid=909

aegisub特效指令教學:

(教學)鳥人都能看懂的ASS基礎語法介紹與講解(1) (by 烏骨雞):http://tucaptions.org/forum.php?mod=viewthread&tid=713
(教學)鳥人都能看懂的ASS基礎語法介紹與講解(2) (by 烏骨雞):http://tucaptions.org/forum.php?mod=viewthread&tid=1811

非社員無權限者請參閱這篇(簡體中文):
【原創】字幕軟件Aegisub ASS代碼使用指南(๑>ڡ<)☆http://www.douban.com/note/284573295/

assMOD語法特效指令教學(簡體中文):


K軸說明:
在開始寫自動化特效以前,必須先了解最基本的ass特效名詞用語和一些注意事項,請參照下圖:

拉過k軸的人應該對這個畫面不陌生,如果該行沒有被拉k軸,則內文不會有{\k}的特效。在下文的說明當中,{\k}則佔有相當重要的角色。

自動化指令
在寫特效以前,必須要先了解整個ass自動化的運作流程,如下圖所示:

通常每一組結果不會只有一行。
而要執行整個自動化流程,則是點選這個選項:

在一般OPED的ass結構如下圖:

在寫特效時,需要書寫的的部份是code行template行以及作用行,執行自動化指令之後,會跑出下面很多行的輸出結果,也就是我需要的特效。
上述所產生的輸出結果通常行數會非常多,在這裡我只擷取前5行。
在這個章節裡面主要說明特效欄內的自動化指令,如上圖的template syl noblank等指令。
在以下的說明當中,我將會把自動化指令輸出的結果呈現出現出來,複製代碼後直接貼到aegisub內會顯示和截圖相同的結果。
下文的標題,紅色指令表示特效欄內不可以和其他紅色指令同時存在,如template line syl是不可以的,但是可以和綠色指令同時存在,如template syl noblank notext loop 8 fxgroup KP則可以。

template pre-line
這個指令常用在一般字幕中對每個字幕都做相同的效果,也就是每行字幕前都有類似{\blur5\bord3}這樣的效果。
這個意思就是將template行內文中的文字或效果都加在作用行的前面,結果如下圖:
  1. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,template pre-line,Fuck
  2. Comment: 0,0:05:00.00,0:05:01.00,OP-jp,,0,0,0,karaoke,{\k30}霜淇淋{\k70}炸豬排
  3. Comment: 0,0:05:00.00,0:05:01.00,OP-jp,,0,0,0,karaoke,{\k30}甜甜圈{\k70}滷味捲
  4. Dialogue: 0,0:05:00.00,0:05:01.00,OP-jp,,0,0,0,fx,Fuck霜淇淋炸豬排
  5. Dialogue: 0,0:05:00.00,0:05:01.00,OP-jp,,0,0,0,fx,Fuck甜甜圈滷味捲
複製代碼
我們可以看到template行(行1)的內文Fuck都被加在作用行(行2~行3)內文的前面並在結果行(行4~行5)輸出其結果。

template line
這個指令在寫歌詞特效中相當常用,這個指令和template pre-line不一樣的是template line如果遇到作用行的內文中有{\k}的時候會取代之,結果如下:
  1. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,template line,Fuck
  2. Comment: 0,0:05:00.00,0:05:01.00,OP-jp,,0,0,0,karaoke,{\k30}霜淇淋{\k70}炸豬排
  3. Comment: 0,0:05:00.00,0:05:01.00,OP-jp,,0,0,0,karaoke,{\k30}甜甜圈{\k70}滷味捲
  4. Dialogue: 0,0:05:00.00,0:05:01.00,OP-jp,,0,0,0,fx,Fuck霜淇淋Fuck炸豬排
  5. Dialogue: 0,0:05:00.00,0:05:01.00,OP-jp,,0,0,0,fx,Fuck甜甜圈Fuck滷味捲
複製代碼
從上面可以看到作用行內文的{\k}全部被取代成Fuck並輸出到結果行。
通常template line中,template行的內文會放和時間相關的變數,如{\t},因為這樣可以達到漸變的動態效果,範例如下:
  1. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,template line,!retime("line",0,200)!{\fscx0\t(!$start!,!$end!,\fscx100)\t(!$ldur!,!$ldur+200!,\fscx0)}
  2. Comment: 0,0:05:00.00,0:05:01.00,OP-jp,,0,0,0,karaoke,{\k10}佐{\k10}久{\k10}間{\k20}佐{\k20}馬{\k30}太
  3. Dialogue: 0,0:05:00.00,0:05:02.20,OP-jp,,0,0,0,fx,{\fscx0\t(0,100,\fscx100)\t(1000,1200,\fscx0)}佐{\fscx0\t(100,200,\fscx100)\t(1000,1200,\fscx0)}久{\fscx0\t(200,300,\fscx100)\t(1000,1200,\fscx0)}間{\fscx0\t(300,500,\fscx100)\t(1000,1200,\fscx0)}佐{\fscx0\t(500,700,\fscx100)\t(1000,1200,\fscx0)}馬{\fscx0\t(700,1000,\fscx100)\t(1000,1200,\fscx0)}太
複製代碼
其中在{\t}內的$ldur$start$end皆為表示時間長度的隱變數,在使用變數的同時,必須把變數用兩個驚嘆號括起來,如!$ldur!
$ldur表示整個作用行的時間長度,$start表示該行的開頭到該音節開始的那段時間長度,$end表示該行的開頭到該音節結束的那斷時間長度。
!retime("line",0,200)!表示重設該行的起點和終點時間,這裡我們可以看到結果行的結束時間是作用行結束時間的0.2秒*音節數
詳細的函數和隱變數將在下文中詳細說明。

template syl (noblank)
這個指令和上述兩個不同的是,每一個{\k}都會生成的獨立的一行,輸出結果如下:
  1. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,template syl noblank,深海裡的
  2. Comment: 0,0:05:00.00,0:05:01.00,OP-jp,,0,0,0,karaoke,{\k10}海綿寶寶{\k10}派大星{\k10}蟹老闆{\k20}章魚哥{\k20}海超人{\k30}大洋遊俠
  3. Dialogue: 0,0:05:00.00,0:05:01.00,OP-jp,,0,0,0,fx,深海裡的海綿寶寶
  4. Dialogue: 0,0:05:00.00,0:05:01.00,OP-jp,,0,0,0,fx,深海裡的派大星
  5. Dialogue: 0,0:05:00.00,0:05:01.00,OP-jp,,0,0,0,fx,深海裡的蟹老闆
  6. Dialogue: 0,0:05:00.00,0:05:01.00,OP-jp,,0,0,0,fx,深海裡的章魚哥
  7. Dialogue: 0,0:05:00.00,0:05:01.00,OP-jp,,0,0,0,fx,深海裡的海超人
  8. Dialogue: 0,0:05:00.00,0:05:01.00,OP-jp,,0,0,0,fx,深海裡的大洋遊俠
複製代碼
上面可以看出深海裡的取代了{\k}並獨立產生一個結果行,noblank則是跳過在作用行中因為有音節空格而輸出無意義的訊息,
因此通常在使用syl的時候都會寫成template syl noblank,下文將詳細解釋這個指令。
同樣地,template行的內文通常也是加入時間的訊息在裡面,而且和template line相比,這個自由度比較高。範例如下:
  1. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,template syl noblank,!retime("syl",0,$ldur-$end)!{\pos(!$center!,!$bottom!)\fad(!$sdur!,0)}
  2. Comment: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,karaoke,{\k80}哈{\k70}哭{\k110}那{\k80}馬{\k80}踏{\k80}塔
  3. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,{\pos(820,1030)\fad(800,0)}哈
  4. Dialogue: 0,0:05:00.80,0:05:05.00,OP-jp,,0,0,0,fx,{\pos(876,1030)\fad(700,0)}哭
  5. Dialogue: 0,0:05:01.50,0:05:05.00,OP-jp,,0,0,0,fx,{\pos(932,1030)\fad(1100,0)}那
  6. Dialogue: 0,0:05:02.60,0:05:05.00,OP-jp,,0,0,0,fx,{\pos(988,1030)\fad(800,0)}馬
  7. Dialogue: 0,0:05:03.40,0:05:05.00,OP-jp,,0,0,0,fx,{\pos(1044,1030)\fad(800,0)}踏
  8. Dialogue: 0,0:05:04.20,0:05:05.00,OP-jp,,0,0,0,fx,{\pos(1100,1030)\fad(800,0)}塔
複製代碼
上面我們可以看到效果都加到了作用行並各自輸出獨立的結果行,而上面用到了$sdur這個時間隱變數和$center$bottom這個位置隱變數。
$sdur表示該音節的長度,$center和$bottom將在下文以圖片詳細說明。
!retime("syl",0,$ldur-$end)!表示重設時間,表示使該行出現的時間為該音節的開頭到該行時間結束,用法則在下文說明。

template char
這個效果和template syl相當類似,不同點是template syl是以{\k}為單位作用,但是template char是以字元為單位作用,不受{\k}的影響,結果如下:
  1. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,template char,Hello
  2. Comment: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,karaoke,笨松鼠Sandy
  3. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,Hello笨
  4. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,Hello松
  5. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,Hello鼠
  6. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,HelloS
  7. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,Helloa
  8. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,Hellon
  9. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,Hellod
  10. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,Helloy
複製代碼
可以看出不論是全形或是半形文字,都是個別作用並輸出獨立的結果行。這裡需要注意的是,template char後面不可加noblank,會導致結果無法輸出。

template notext
這個指令表示在作用的同時,忽略作用行的內文,直接輸出template內文的結果,結果如下:
  1. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,template syl noblank notext,equation
  2. Comment: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,karaoke,{\k80}薛{\k70}丁{\k110}格{\k80}方{\k80}程{\k80}式
  3. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,equation
  4. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,equation
  5. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,equation
  6. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,equation
  7. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,equation
  8. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,equation
複製代碼
可以看到薛丁格方程式完全沒有出現在結果行中。
另外一點值得注意的是,這個自動化指令使可以加在template line/syl/char後面的,表示說notext這個自動化指令是可以和line/syl/char同時存在的。
但是唯獨在template pre-line notext這個時候,notext並不會產生任何的效果,仍然會顯示作用行中的內文,也就是效果等同template pre-line,這點要特別注意。
這個指令通常是搭配圖形的效果而存在的,範例如下:
  1. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,template syl noblank,!retime("syl",0,$ldur-$end)!{\pos(!$center!,!$bottom!)\fad(!$sdur!,0)}
  2. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,template syl noblank notext,!retime("line",0,0)!{\an1\move(!$center!,!$bottom!,!$center!,!$bottom-50!)\p1}m -9 -7 l -9 -7 l -15 6 l 0 16 l 13 17 l 21 3 l 18 -7 l -1 -12 m 0 -5 l 10 -4 l 12 6 l 7 12 l -5 6 l -6 -1
  3. Comment: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,karaoke,{\k80}薛{\k70}丁{\k110}格{\k80}方{\k80}程{\k80}式
  4. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,{\pos(820,1030)\fad(800,0)}薛
  5. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,{\an1\move(820,1030,820,980)\p1}m -9 -7 l -9 -7 l -15 6 l 0 16 l 13 17 l 21 3 l 18 -7 l -1 -12 m 0 -5 l 10 -4 l 12 6 l 7 12 l -5 6 l -6 -1
  6. Dialogue: 0,0:05:00.80,0:05:05.00,OP-jp,,0,0,0,fx,{\pos(876,1030)\fad(700,0)}丁
  7. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,{\an1\move(876,1030,876,980)\p1}m -9 -7 l -9 -7 l -15 6 l 0 16 l 13 17 l 21 3 l 18 -7 l -1 -12 m 0 -5 l 10 -4 l 12 6 l 7 12 l -5 6 l -6 -1
  8. Dialogue: 0,0:05:01.50,0:05:05.00,OP-jp,,0,0,0,fx,{\pos(932,1030)\fad(1100,0)}格
  9. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,{\an1\move(932,1030,932,980)\p1}m -9 -7 l -9 -7 l -15 6 l 0 16 l 13 17 l 21 3 l 18 -7 l -1 -12 m 0 -5 l 10 -4 l 12 6 l 7 12 l -5 6 l -6 -1
  10. Dialogue: 0,0:05:02.60,0:05:05.00,OP-jp,,0,0,0,fx,{\pos(988,1030)\fad(800,0)}方
  11. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,{\an1\move(988,1030,988,980)\p1}m -9 -7 l -9 -7 l -15 6 l 0 16 l 13 17 l 21 3 l 18 -7 l -1 -12 m 0 -5 l 10 -4 l 12 6 l 7 12 l -5 6 l -6 -1
  12. Dialogue: 0,0:05:03.40,0:05:05.00,OP-jp,,0,0,0,fx,{\pos(1044,1030)\fad(800,0)}程
  13. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,{\an1\move(1044,1030,1044,980)\p1}m -9 -7 l -9 -7 l -15 6 l 0 16 l 13 17 l 21 3 l 18 -7 l -1 -12 m 0 -5 l 10 -4 l 12 6 l 7 12 l -5 6 l -6 -1
  14. Dialogue: 0,0:05:04.20,0:05:05.00,OP-jp,,0,0,0,fx,{\pos(1100,1030)\fad(800,0)}式
  15. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,{\an1\move(1100,1030,1100,980)\p1}m -9 -7 l -9 -7 l -15 6 l 0 16 l 13 17 l 21 3 l 18 -7 l -1 -12 m 0 -5 l 10 -4 l 12 6 l 7 12 l -5 6 l -6 -1
複製代碼
可以看到中間輸出的幾行只有圖形,沒有文字。如果不巧在作用行中有英數字,notext則可以避免掉圖形可能會歪掉的麻煩。

template noblank
這個指令通常只會加在template syl的後面,也就是template syl noblank,這個指令是希望中間的空白k軸不要輸出時使用,如下圖所示:
  1. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,template syl noblank,!retime("syl",0,0)!Dirac
  2. Comment: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,karaoke,{\k80}狄{\k70}拉{\k110}克{\k20}{\k60}方{\k80}程{\k80}式
  3. Dialogue: 0,0:05:00.00,0:05:00.80,OP-jp,,0,0,0,fx,Dirac狄
  4. Dialogue: 0,0:05:00.80,0:05:01.50,OP-jp,,0,0,0,fx,Dirac拉
  5. Dialogue: 0,0:05:01.50,0:05:02.60,OP-jp,,0,0,0,fx,Dirac克
  6. Dialogue: 0,0:05:02.80,0:05:03.40,OP-jp,,0,0,0,fx,Dirac一
  7. Dialogue: 0,0:05:03.40,0:05:04.20,OP-jp,,0,0,0,fx,Dirac直
  8. Dialogue: 0,0:05:04.20,0:05:05.00,OP-jp,,0,0,0,fx,Dirac玩
複製代碼
再比較如果沒有加上noblank時輸出的結果:
  1. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,template syl,!retime("syl",0,0)!Dirac
  2. Comment: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,karaoke,{\k80}狄{\k70}拉{\k110}克{\k20}{\k60}方{\k80}程{\k80}式
  3. Dialogue: 0,0:05:00.00,0:05:00.00,OP-jp,,0,0,0,fx,Dirac
  4. Dialogue: 0,0:05:00.00,0:05:00.80,OP-jp,,0,0,0,fx,Dirac狄
  5. Dialogue: 0,0:05:00.80,0:05:01.50,OP-jp,,0,0,0,fx,Dirac拉
  6. Dialogue: 0,0:05:01.50,0:05:02.60,OP-jp,,0,0,0,fx,Dirac克
  7. Dialogue: 0,0:05:02.60,0:05:02.80,OP-jp,,0,0,0,fx,Dirac
  8. Dialogue: 0,0:05:02.80,0:05:03.40,OP-jp,,0,0,0,fx,Dirac方
  9. Dialogue: 0,0:05:03.40,0:05:04.20,OP-jp,,0,0,0,fx,Dirac程
  10. Dialogue: 0,0:05:04.20,0:05:05.00,OP-jp,,0,0,0,fx,Dirac式
複製代碼
可以看到這裡多出了第3行和第7行在Dirac的後面沒有文字出現,在這裡可以注意到事實上第3行並不會影響字幕出現的結果,因為這段時間的間隔是0,唯一會影響到的就是第7行。
在第2行的作用行可以注意到,中間有一個200ms沒有文字的音節,這個常在拉k軸的時候在同一行中因為中間沒有唱歌,往往這一個音節是空的,
但是有時候希望在這個間隔內仍然有特效圖形出現的話,這個noblank就建議不要加上去。
另外,這個指令也可以和notext同時使用,如template syl noblank notext

template keeptags
這個自動化指令表示保留作用行中的特效指令,這個指令只對template pre-line/line/syl有作用,對template char完全沒有影響,也就是template char keeptags的效果和template char完全一樣。
而template pre-linetemplate line/syl的效果又稍微不同,先比較template pre-line 和template pre-line keeptags的結果,如下圖:
  1. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,template pre-line,Hellen
  2. Comment: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,karaoke,{\k80}煙{\k60}燻{\k30}最{\k70}恩{\k60\fscx50}最{\k40}合{\k80}豆{\k80}腐
  3. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,Hellen煙燻最恩最合豆腐
複製代碼
  1. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,template pre-line keeptags,Hellen
  2. Comment: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,karaoke,{\k80}煙{\k60}燻{\k30}最{\k70}恩{\k60\fscx50}最{\k40}合{\k80}豆{\k80}腐
  3. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,Hellen{\k80}煙{\k60}燻{\k30}最{\k70}恩{\k60\fscx50}最{\k40}合{\k80}豆{\k80}腐
複製代碼
從上面的兩個例子可以看到,template pre-line這個指令完全忽略整個作用行內的所有特效指令,包含{\k}和{\fscx}全部都忽略,直接把template行後面的內文直接和作用行的內文執行後在結果行輸出。
而在template pre-line keeptags這個指令作用的時候,可以發現作用行內的所有特效指令都被保留了。
通常template pre-line keeptags會使用在一般字幕中如果要選定每一行字幕都出現例如像{\blur5\bord3}等特效,又不想改變字幕中可能有使用其他字型時,這個自動化指令就可以達到不改變字型的效果,範例如下:
  1. Comment: 0,0:00:00.00,0:00:05.00,Default,,0,0,0,template pre-line  keeptags,{\blur5\bord2}
  2. Comment: 0,0:00:05.00,0:00:07.00,Default,,0,0,0,karaoke,我無法{\fnDFPPOP1W7-B5\fs80\c&HFFA4A3&}焗烤的{\r}
  3. Dialogue: 0,0:00:05.00,0:00:07.00,Default,,0,0,0,fx,{\blur5\bord2}我無法{\fnDFPPOP1W7-B5\fs80\c&HFFA4A3&}焗烤的{\r}
複製代碼
從這例子可以觀察到,焗烤的的效果{\fnDFPPOP1W7-B5\fs80\c&HFFA4A3&}完全被保留了,如果不加keeptags的時候,則後面的效果會被完全忽略掉。
接下來說明template line和template line keeptags的差別,如下圖所示:
  1. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,template line,D
  2. Comment: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,karaoke,{\k80}煙{\k60}燻{\k30}最{\k70}恩{\k60\fscx50}最{\k40}合{\k80}豆{\k80}腐
  3. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,D煙D燻D最D恩D最D合D豆D腐
複製代碼
  1. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,template line keeptags,D
  2. Comment: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,karaoke,{\k80}煙{\k60}燻{\k30}最{\k70}恩{\k60\fscx50}最{\k40}合{\k80}豆{\k80}腐
  3. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,D煙D燻D最D恩D{\fscx50}最D合D豆D腐
複製代碼
由這兩個例子可以觀察到,template line這個指令本身就是把{\k}取代成template行的內文,並且忽略作用行內所有的特效指令,
template line keeptags則一樣是把{\k}取代成template行的內文,但是這裡保留了{\k}以外的所有特效。
反之亦然,template syl (kepptags)和template line (kepptags)所產生的效果其實類似,如下圖所示:
  1. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,template syl noblank,D
  2. Comment: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,karaoke,{\k80}煙{\k60}燻{\k30}最{\k70}恩{\k60\fscx50}最{\k40}合{\k80}豆{\k80}腐
  3. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,D煙
  4. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,D燻
  5. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,D最
  6. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,D恩
  7. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,D最
  8. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,D合
  9. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,D豆
  10. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,D腐
複製代碼
  1. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,template syl noblank keeptags,D
  2. Comment: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,karaoke,{\k80}煙{\k60}燻{\k30}最{\k70}恩{\k60\fscx50}最{\k40}合{\k80}豆{\k80}腐
  3. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,D煙
  4. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,D燻
  5. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,D最
  6. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,D恩
  7. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,D{\fscx50}最
  8. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,D合
  9. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,D豆
  10. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,D腐
複製代碼
從這個例子也可以看出,template syl則是把{\k}取代掉,忽略其他的特效指令,每個音節個別產生後輸出到結果行,
template syl keeptags則是把{\k}取代掉之後,保留{\k}以外的所有特效指令,並個別輸出到結果行。
另外,這個自動化指令和notextnoblank同時使用並沒有任何意義,而這個指令也就比較常和template pre-line同時使用而已。

template loop N
這個自動化指令的意思就是這一個template行對作用行執行N次的意思,其中N為正整數,如下圖:
  1. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,template pre-line loop 3,哈姆太郎最愛
  2. Comment: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,karaoke,{\k50}向{\k80}日{\k90}葵{\k80}的{\k100}種{\k100}子
  3. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,哈姆太郎最愛向日葵的種子
  4. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,哈姆太郎最愛向日葵的種子
  5. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,fx,哈姆太郎最愛向日葵的種子
複製代碼
可以看到template pre-line執行的果重複了3次,其他的template line/syl/char也會得到重複的效果。
通常這個指令會用在圖形的迴圈,範例如下:


由於這個輸出結果稍微冗長,這裡直接附上ass範本。這個自動化指令我給他迴圈5次,需要注意的是這個template行的內文!retime("presyl",(j-1)/maxj*$sdur,(j-1)/maxj*$sdur+500)!
上面用藍色字寫的jmaxj是一個迴圈變數,這個迴圈總共進行5次,所以這個maxj=5,第1次迴圈時,j=1,第2次迴圈時,j=2,最多跳到j=5時停止迴圈,
簡單來說,可以想成這個template行其實總共是有5行,第1行是!retime("presyl",1/5*$sdur,1/5*$sdur+500)!***,第2行是!retime("presyl",2/5*$sdur,2/5*$sdur+500)!***,以此類推,
!retime("presyl",t1,t2)!所指的是把每一個音節的時間重設為音節開頭往後的t1毫秒到音節開頭往後的t2毫秒的這段時間間隔,詳細也在下文的函數中說明。
在這個template行內文中的math.random(-100,100)是一個LUA函數,LUA函數裡面有包含指數函數、對數函數、三角函數、反三角函數、弧度、π等可以表示任意函數的完備基底,這在數學上是已經被證明的。
有了這些函數就可以用近似的方法去畫出各種多項式函數或是特殊函數,如Gamma函數、Legendre函數、Bessel函數、Laguerre函數、Hermite函數等有名的特殊函數,而這些函數的完備基底都可以查表。
而在這裡使用的math.random(-100,100)就是其中一種,這個是隨機函數,表示任意在[-100,100]之間任意選取一個整數。
事實上除了template loop N以外,還有一個類似的實用函數!maxloop(R)!可以達到一樣的效果,好處是R可以是任意大於0的實數
這個loop N可以和上面任何一個自動化指令同時使用,如template syl noblank notext loop 8

template fxgroup Name
在所有的template行之中,已經知道相同樣式的template行僅執行相同樣式的作用行,但是若只想執行某幾行的作用行的話,其中一個方法是把template行和想執行的作用行都改成另一個樣式名稱,
另一個方法則是在code行和角色欄上面動手腳,使用這個方法的話就會用到這個自動化指令,範例如下:
  1. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,code line all,fxgroup.Hellen01 = (line.actor == "eff001");fxgroup.Hellen02 = (line.actor == "eff002");fxgroup.Hellen03 = (line.actor == "eff003")
  2. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,template pre-line fxgroup Hellen01,Eta
  3. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,template pre-line fxgroup Hellen02,Beta
  4. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,template pre-line fxgroup Hellen03,Zeta
  5. Comment: 0,0:05:00.00,0:05:05.00,OP-jp,eff001,0,0,0,karaoke,座標系
  6. Comment: 0,0:05:00.00,0:05:05.00,OP-jp,eff002,0,0,0,karaoke,射線
  7. Comment: 0,0:05:00.00,0:05:05.00,OP-jp,eff003,0,0,0,karaoke,質量大
  8. Comment: 0,0:05:00.00,0:05:05.00,OP-jp,eff003,0,0,0,karaoke,密度高
  9. Comment: 0,0:05:00.00,0:05:05.00,OP-jp,eff003,0,0,0,karaoke,體積大
  10. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,eff001,0,0,0,fx,Eta座標系
  11. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,eff002,0,0,0,fx,Beta射線
  12. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,eff003,0,0,0,fx,Zeta質量大
  13. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,eff003,0,0,0,fx,Zeta密度高
  14. Dialogue: 0,0:05:00.00,0:05:05.00,OP-jp,eff003,0,0,0,fx,Zeta體積大
複製代碼
從上面的例子可以觀察到第2行作用到第5行,第3行作用到第6行,第4行作用到7~9行,而樣式全部都是OP-jp。要使用這個方法必須要先定義code行,也就是定義執行的規則,
注意第1行,特效欄必須是code line all,表示對每一個作用行執行以前,先讀取第1行的規則後才進行,
內文的fxgroup.Hellen01 = (line.actor == "eff001"); fxgroup.Hellen02 = (line.actor == "eff002"); fxgroup.Hellen03 = (line.actor == "eff003")則是運行規則,綠色字體表示可替換,
這句話翻譯成白話文就是template fxgroup Hellen01僅對角色欄eff001作用; template fxgroup Hellen02僅對角色欄eff002作用; template fxgroup Hellen03僅對角色欄eff003作用
在使用fxgroup Name的時候,這一行code指令是不可或缺的,用法可以死記,同樣地,這個語法也可以和template pre-line/line/syl/char共用,也可以和template notext/noblank/keeptags/loop N共用,
如template syl noblank notext loop 7 fxgroup KP


實用函數

在ass中,做自動化的同時,弱希望該行對某行可以進行某種變化,可以使用函數來重新定義你所期望輸出的結果。
在使用函數時,內文必須用兩個驚嘆號把函數夾進去,如 !retime("line",0,200)! ,其中retime為所使用的函數,()內的東西為函數的變數。
以下將對常使用的函數做一些解說。

retime("mode",t1,t2)
這個函數可以讓該行的時間做重新分配,用綠色字體表示的是變數,mode為時間分配的模式,常用的有8種,t1和t2分別為時間的起點和終點,時間的單位是毫秒(0.001秒)
但是t1和t2的起點和終點根據mode的不同,所定義的起點和終點也會不一樣。
下圖為表示每個模式的初始時間分配(t1=t2=0):

若要改變初始時間分配,示意圖如下:

須注意上圖的時間間隔Δtn≥0,表示該時間差的絕對值,另外藍色字體為隱變數(Inline variables)
這個隱變數為aegisub內建的code,其code功能很多,可以表示位置分配或是時間分配,而在這個函數中所使用的隱變數皆為時間分配的變數,而且是具有特定時間間隔的Δt
在這個函數底下,所用到時間隱變數如下圖:

在這裡要特別說明,常用的時間隱變數共有11種,分別為$ldur、$dur、$sdur、$kdur、$skdur、$start、$sstart、$end、$send、$mid、$smid,且隱變數的時間單位是毫秒,
但是這裡的$sdur=$dur、$kdur=$skdur、$start=$sstart、$end=$send、$mid=$smid,所以這樣扣下來只剩6種,為了方便,我們只需要記得這6種用法。
而又因$kdur=0.1*$sdur,$end=$start+$sdur,$mid=$start+0.5*$sdur,因此嚴格來說,只需要$start$sdur$ldur,3種就可以表示出所有的時間間隔。
上面解釋了retime的定義,這樣就可以再和前面的自動化指令結合寫出重設時間的字幕特效行。

範例一,template pre-line
  1. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,template pre-line,!retime("line",0,0.1*$ldur)!{\fscx0\t(0,!$ldur!,\fsc100)\t(!$ldur!,!1.1*$ldur!,\fscx0)}
  2. Comment: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,karaoke,{\k80}益{\k20}川{\k60}敏{\k70}英{\k50}南{\k60}部{\k70}陽{\k40}一{\k50}郎
  3. Dialogue: 0,0:05:00.00,0:05:05.50,OP-jp,,0,0,0,fx,{\fscx0\t(0,5000,\fsc100)\t(5000,5500,\fscx0)}益川敏英南部陽一郎
複製代碼
從上面的例子來看,!retime("line",0,0.1*$ldur)!表示我讓作用行的時間終點重設成延後原時間長度的0.1倍,並且忽略作用行中的所有特效,
並把template行的內文{\fscx0\t(0,!$ldur!,\fsc100)\t(!$ldur!,!1.1*$ldur!,\fscx0)}加到作用行文字的最前面,輸出到結果行。
需要注意的是,隱變數已經在函數之內了,不用特地再用2個驚嘆號括起來。再次強調,凡是函數(包含實用函數或是LUA函數)或是隱變數,都必須要用2個驚嘆號括起來。
這裡的!$ldur!表示整個作用行的時間長度,在這個case裡面,該作用行的時間長度是5秒,因此$ldur=5000。

範例二,template syl


第1行的函數是!retime("start2syl",0,0)!,也就是讓每一個音節出現的時間為從該作用行的開始時間直到該音節開始時間為止
第2行的函數是!retime("syl",0,500)!,也就是讓每一個音節出現的時間為該音節的開始時間直到音節結束時間後500毫秒為止,這裡的函數也可以寫成!retime("presyl",0,$sdur+500)!,完全等價。
而這2個template行的內文中有使用\pos(!$center!,!$middle!),而這裡的$center$middle位置隱變數,可以重設該音節的字出現的位置,而這個位置是相對於作用行的,這裡在後面將會詳細介紹。
由上面的2行,事實上就可以構成一個完整有頭有尾的特效了,而一般歌詞特效的寫法也是類似這樣的結構。

範例三,template char


這裡需要注意的是作用行,跟範例二很像,但是這裡我把連勝文放在同一個音節,而template char又是以每個字元為單位作用,
因此可以看到第12~14行以及第15~17行時間分配的結果是一樣的,但是這裡因為我也放了位置隱變數\pos(!$center!,!$middle!),
而且又是以每個字元為單位作用,因為每個字分配的位置是相對於作用行的每個字,所以這裡輸出的位置也不同。
另外值得注意的是,如果是相同的內文,只是把template行中的特效欄改成template syl的話,結果也會稍微不同,結果如下:


從這個例子可以看到連勝文這3個字相當突兀,因為template syl他是以音節為單位去執行,而這3個字又在同一個音節內,因此連勝文會一起被作用。
而且這個位置隱變數也是相對於作用行內的連勝文這3個字為基準重設的,因此可以看到連勝文會黏在一起旋轉。

範例四,template line
  1. Comment: 0,0:00:00.00,0:00:00.00,OP-jp,,0,0,0,template line,!retime("line",0,500)!{\pos(!$lcenter!,!$lmiddle!)\an10\alpha&HFF&\fs5\t(!$start!,!$end!,\fs60\alpha&H00&)\t(!$ldur!,!$ldur+500!,\fs10\alpha&HFF&)}
  2. Comment: 0,0:05:00.00,0:05:05.00,OP-jp,,0,0,0,karaoke,{\k80}柯{\k20}林{\k60}頓{\k70}小{\k70}布{\k70}希{\k40}歐{\k40}巴{\k50}馬
  3. Dialogue: 0,0:05:00.00,0:05:09.50,OP-jp,,0,0,0,fx,{\pos(960,1000)\an10\alpha&HFF&\fs5\t(0,800,\fs60\alpha&H00&)\t(5000,5500,\fs10\alpha&HFF&)}柯{\pos(960,1000)\an10\alpha&HFF&\fs5\t(800,1000,\fs60\alpha&H00&)\t(5000,5500,\fs10\alpha&HFF&)}林{\pos(960,1000)\an10\alpha&HFF&\fs5\t(1000,1600,\fs60\alpha&H00&)\t(5000,5500,\fs10\alpha&HFF&)}頓{\pos(960,1000)\an10\alpha&HFF&\fs5\t(1600,2300,\fs60\alpha&H00&)\t(5000,5500,\fs10\alpha&HFF&)}小{\pos(960,1000)\an10\alpha&HFF&\fs5\t(2300,3000,\fs60\alpha&H00&)\t(5000,5500,\fs10\alpha&HFF&)}布{\pos(960,1000)\an10\alpha&HFF&\fs5\t(3000,3700,\fs60\alpha&H00&)\t(5000,5500,\fs10\alpha&HFF&)}希{\pos(960,1000)\an10\alpha&HFF&\fs5\t(3700,4100,\fs60\alpha&H00&)\t(5000,5500,\fs10\alpha&HFF&)}歐{\pos(960,1000)\an10\alpha&HFF&\fs5\t(4100,4500,\fs60\alpha&H00&)\t(5000,5500,\fs10\alpha&HFF&)}巴{\pos(960,1000)\an10\alpha&HFF&\fs5\t(4500,5000,\fs60\alpha&H00&)\t(5000,5500,\fs10\alpha&HFF&)}馬
複製代碼
這裡會發現,我明明使用的是!retime("line",0,500)!,字面上的意思是整行的結束時間應該是作用行結束時間加上0.5秒才對,但是這裡卻變成了加4.5秒,而這就是在template line才會出現的特例!!
在template line之中,!retime("line",0,500)!正確的意思是整段輸出後的時間變為該作用行的起始時間到結束時間後0.5秒*音節數,在這個範例當中,因為總共有9個音節,因此這裡的結束時間多了4.5秒。
如果希望結果行出現的時間可以完整地設定在作用行後0.5秒的話,這裡的函數要改寫成!retime("line",0,500/$syln)!,而這裡的$syln也是隱變數,意思是該作用行的音節數

relayer(N)
這個函數相當簡單也容易理解,顧名思義就是讓每個輸出的結果重新定義層數,
這裡的N為不小於0的整數,用法範例如下:

第2行中的!relayer(10-syl.i)!就是重設層數的函數,而這裡的syl.iLUA變數,表示該行中的第i個音節,這個變數相當常用,
在結果行中,可以看到第5行是template行對作用行中的第1個音節作用,因此這裡的syl.i=110-syl.i=9,層數就是9;第7行是template行對作用行中的第2個音節作用,因此這裡的syl.i=2,層數就是8,以此類推,
仔細觀察輸出的效果,在第2行中內文因為有\fs60\t(0,!0.5*$dur!,\fs100)\t(!0.5*$sdur!,!$sdur!,\fs60),因為在中間字放大的同時,如果沒有使用relayer這個函數的話,會導致右邊的文字永遠蓋在左邊的文字上,
明明是放大,卻被比較小的文字壓住,相當不自然,因此在這裡設計成放大的字永遠壓在比較小的文字前面,並且設定愈右邊的字層數愈小,也就是左邊的字永遠在右邊文字之上。


maxloop(R)
這個函數和前面的自動化指令template loop N相當類似,但差別是這裡的R可以放隱變數,N只能是選定好的整數,而R可以是不小於0的實數
在前面的template loop N的範例中,N=5,也就是每一個音節只會噴出5顆星星,但是因為音節有常有短,又希望每顆星星之間噴出的時間間隔相同,這時候maxloop這個函數就派的上用場,以下是範例:


這裡我設定每顆星星噴出的時間間格是50ms,因此每一個音節就可以噴出$sdur/50顆星星,所以這裡我就設定的函數為!maxloop($sdur/50)!,
需要注意的是!maxloop(R)!的R可以是不小於0的實數,如果R不是整數,則迴圈次數會判定成把R後面的小數點無條件進位也就是!maxloop(8.08)!=template loop 9,!maxloop(math.pi)!=template loop 4
上面用到的math.pi也是LUA函數,意思就是圓周率π,所以math.pi=3.1415926535...,因此小數點後面進位之後,就同等於是template loop 4
而時間重設函數!retime("presyl",(j-1)*50,(j-1)*50+500)!則就是設定每顆星星出現的時間長短及順序,每顆星星出現的時間長短是500ms,星星則每隔50ms就出現,出現的示意圖如下:

這裡使用了函數!retime("presyl",ti,tf)!,只須要在這個函數調整星星出現的時間(ti、tf)即可,首先Δtd是每顆星星的間隔時間,Δtl是星星出現的時間長短,
由上面的圖可以輕易看出,ti是星星的開頭時間,tf是星星的結束時間,而ti和tf的關係式如上圖,且j=1,2,3,...,[$sdur/Δtd]
在這個case裡面,Δtd=50Δtl=500,可以任意調整。

隱變數
在前文提到了很多時間隱變數和位置隱變數,但不論是哪一種隱變數,隱變數輸出的結果就是一個數字,也就是在retime裡面也可以放上位置隱變數,如!retime("line",$lcenter,$syln)!之類的
之所以$start、$sdur、$ldur稱為時間隱變數,是因為它們讀取了作用行中的時間訊息而輸出一個數值,同理,$center、$lx、$bottom...等之所以稱為位置隱變數,是因為讀取了作用行中的位置訊息而輸出一個數值,
當然也有一些隱變數既非時間隱變數也非位置隱變數,如$syln$si,我們稱之為特殊隱變數
在前面retime的章節中我們已經詳細討論的時間隱變數的功能,這個章節裡面將詳細描述位置隱變數以及特殊隱變數。

位置隱變數
首先介紹跟作用行整行相關的位置隱變數,有$lleft、$lcenter、$lright、$ltop、$lmiddle、$lbottom、$lx、$ly、$lheight、$lwidth,共10種,其位置示意圖如下:

($lleft,$ltop)表示說這2個隱變數讀取該點的座標,也就是$lleft=作用行文字左邊邊緣的x座標$ltop=作用行文字上面邊緣的y座標
($lcenter,$lbottom)同理,也就是$lcenter=作用行文字中心的x座標$lbottom=作用行文字下面邊緣的y座標,以此類推。
而這裡的($lx,$ly)則是隨著作用行的預設樣式改變,如果該作用行的樣式編輯器內,對齊如果選擇7,則($lx,$ly)=($lleft.$ltop);若選擇2,則($lx,$ly)=($lcenter,$lbottom),以此類推。
$lheight則是該作用行文字的高度,也就是$lheight=$lbottom-$ltop$lwidth則是該作用行文字的寬度,但是關係式稍微不同,關係式為$lwidth=$lright-$lleft+1,但實際上沒有差很多,可以直接使用。
通常這個隱變數是拿來做重新定位使用,範例如下:
  1. Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,template line notext,!retime("line",0,0)!{\an2\pos(!$lleft!,!$ltop!)\fs30}●
  2. Comment: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,karaoke,微分方程
  3. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an2\pos(820,935)\fs30}●
複製代碼
這裡可以看到結果行位置中心被重新定位,請注意是位置中心,也就是的位置,如果template內的{\an2}改成{\an5},則template內文的則和位置中心重疊。
在這個範例當中,輸出結果後,暫時先將作用行的註解欄的勾取消,可以看到輸出後的位置中心和原先的內文的關係,如下圖:

可以看到(!$lleft!,!$ltop!)對齊的位置剛好就是微分方程的左上角,如果使用別的位置隱變數,輸出的結果也會跟著改變,可以自己操作看看。
介紹完和作用行整行相關的隱變數之後,接著介紹和音節相關的隱變數,$left、$center、$right、$top、$middle、$bottom、$x、$y、$height、$width,共10種,其位置示意圖如下:

可以看到音節的位置隱變數的位置分配和整行的分配是相當類似的,只是這個隱變數是以音節為單位執行,
($left,$top)表示說這2個隱變數讀取該點的座標,也就是$left=作用行中該音節文字左邊邊緣的x座標$top=作用行中該音節文字上面邊緣的y座標
($center,$bottom)同理,也就是$lcenter=作用行文字中該音節中心的x座標$bottom=作用行中該音節文字下面邊緣的y座標,以此類推。
同樣地,($x,$y)也是隨著預設樣式的改變而改變。
且這裡的$width=$left-$right$height=$bottom-$top,不會有+1的關係式出現。
音節定位的範例如下:
  1. Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,template syl noblank notext,!retime("line",0,0)!{\an5\pos(!$center!,!$middle!)\fs30}●
  2. Comment: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,karaoke,{\k125}微{\k125}分{\k125}方{\k125}程
  3. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an5\pos(855,973)\fs30}●
  4. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an5\pos(925,973)\fs30}●
  5. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an5\pos(995,973)\fs30}●
  6. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an5\pos(1065,973)\fs30}●
複製代碼
因為(!$center!,!$middle!)是設定在每個音節文字的正中央,因此可以觀察到template行的全部被定位在每個文字的正中央。
另外這個音節位置隱變數中,每一個隱變數前加s的效果是相同的,也就是$center=$scenter$left=$sleft,以此類推。

特殊隱變數
特殊隱變數在這裡只介紹經常使用的,只有$si$slyn,而$si=$i
$syln的意思就是整行的音節數,$si就是該行的第i個音節。通常這個隱變數是用在有隨音節漸變效果的情況,範例如下:
  1. Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,template syl noblank,!retime("line",0,0)!{\an2\pos(!$center!,!$bottom!)\fs!$syln*4+$si*5!}
  2. Comment: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,karaoke,{\k50}飛{\k50}行{\k50}荷{\k50}蘭{\k50}人 {\k50}住{\k50}在{\k50}比{\k50}奇{\k50}堡
  3. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an2\pos(628,1040)\fs45}飛
  4. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an2\pos(698,1040)\fs50}行
  5. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an2\pos(768,1040)\fs55}荷
  6. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an2\pos(838,1040)\fs60}蘭
  7. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an2\pos(908,1040)\fs65}人
  8. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an2\pos(1013,1040)\fs70}住
  9. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an2\pos(1083,1040)\fs75}在
  10. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an2\pos(1153,1040)\fs80}比
  11. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an2\pos(1223,1040)\fs85}奇
  12. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an2\pos(1293,1040)\fs90}堡
複製代碼
從這個例子可以看到,作用行中總共有10個音節,因此這裡$syln=10是第1個音節,所以$si=1是第2個音節,所以$si=2,以此類推。
可以看到我的隱變數放在{\fs!$syln*4+$si*5!}裡面,也就是每執行1個音節,字型大小從{\fs45}~{\fs90}漸漸變化,所以畫面就會看到字體由左而右愈來愈大。

LUA函數
在前文中有介紹到math.random(Z1,Z2)和math.pi這個LUA函數,在使用LUA函數的時候也是必須要用2個驚嘆號把函數括起來,用法如下:
  1. Comment: 0,0:00:00.00,0:00:00.00,Default,,0,0,0,template syl noblank,!retime("line",0,0)!{\an2\pos(!$center!,!$bottom!)\fs!50+30*math.sin($si)!}
  2. Comment: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,karaoke,{\k50}飛{\k50}行{\k50}荷{\k50}蘭{\k50}人 {\k50}住{\k50}在{\k50}比{\k50}奇{\k50}堡
  3. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an2\pos(628,1040)\fs75.244129544237}飛
  4. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an2\pos(698,1040)\fs77.27892280477}行
  5. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an2\pos(768,1040)\fs54.233600241796}荷
  6. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an2\pos(838,1040)\fs27.295925140762}蘭
  7. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an2\pos(908,1040)\fs21.232271760106}人
  8. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an2\pos(1013,1040)\fs41.617535054032}住
  9. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an2\pos(1083,1040)\fs69.709597961564}在
  10. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an2\pos(1153,1040)\fs79.680747398701}比
  11. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an2\pos(1223,1040)\fs62.363554557253}奇
  12. Dialogue: 0,0:05:00.00,0:05:05.00,Default,,0,0,0,fx,{\an2\pos(1293,1040)\fs33.679366673319}堡
複製代碼
在template行中,{\fs}這個特效語法裡面我用了math.sin(R)這個函數,這個就是sin函數,也是其中一個LUA函數。
在這個章節中,將介紹常使用的LUA函數。

math.abs(R) 取絕對值
基本上就是數學的|x|,這裡的R任意實數以下的S代表輸出結果(solution)。

定義域/值域 範例
input
-∞<R<∞
math.abs(-18.52)
output
0≦S<∞
18.52


math.deg(R1) / math.rad(R2) 角度/弧度轉換
math.deg為弧度轉角度,math.rad為角度轉弧度,而R1、R2皆為任意實數

定義域/值域 範例1範例2
input
-∞<R1<∞
-∞<R2<∞
math.deg(math.pi)math.rad(180)
output
-∞<S2<∞
-∞<S2<∞
1803.1415926535898


math.pi 圓周率
就是數學上的圓周率π。

定義域/值域 範例
input
null
math.pi
output
S=π
3.1415926535898


math.random(Z1,Z2) 隨機函數
隨機選取Z1到Z2之間的整數,而Z1和Z2皆為任意整數

定義域/值域 範例
input
-∞<Z1<∞
-∞<Z2<∞
math.random(-32,168)
output
-∞<Z1≦S≦Z2<∞
147


math.sin(R1) / math.cos(R1) / math.tan(R2) 三角函數
這就是很一般的三角函數,需要注意的是這裡的R1和R2都是以弧度為單位,所以通常R會放角度轉弧度的LUA函數,如!math.sin(math.rad(180))!。R為任意實數

定義域/值域 範例1範例2範例3
input
-∞<R1<∞
-∞<R2<∞
math.sin(math.rad(90))math.cos(math.rad(90))math.tan(math.rad(45))
output
-1≦S1≦1
-∞<S2<∞
101


math.asin(R1) / math.acos(R2) / math.atan(R3) 反三角函數
三角函數的反函數,值域也不太一樣,且輸出的結果單位為弧度,且R1、R2、R3皆為實數,表格如下:

定義域/值域 範例1範例2範例3
input
-1≦R1≦1
-1≦R2≦1
-∞<R3<∞
math.asin(1)math.acos(1)math.tan(math.rad(45))
output
-π/2≦S1≦π/2
0≦S2≦π
-π/2≦S3≦π/2
1.570796326794900.78539816339745


math.exp(R) 自然指數函數
這是一個以e為底的指數函數,也就是ex,且e=2.7182818284...。這裡的R為任意實數

定義域/值域 範例
input
-∞<R<∞
math.exp(2.3)
output
0<S<∞
9.9741824548147


math.log(R) 自然對數函數
這是一個以e為底的對數函數,也就是ln(x),這裡的R為大於0的實數

定義域/值域 範例
input
0<R<∞
math.exp(0.3)
output
-∞<S<∞
-1.2039728043259


math.log10(R) 對數函數
這是一個以10為底的對數函數,也就是log10(x),這裡的R為大於0的實數

定義域/值域 範例
input
0<R<∞
math.log10(2)
output
-∞<S<∞
0.30102999566398


math.sinh(R1) / math.cosh(R2) / math.tanh(R3) 雙曲函數
這一類的函數可能大家會比較少碰到,也就是sinh(x)、cosh(x)、tanh(x),而sinh(x)=(ex-e-x)/2、cosh(x)=(ex+e-x)/2、tanh(x)=sinh(x)/cosh(x)。這裡的R1、R2、R3皆為任意實數

定義域/值域 範例1範例2範例3
input
-∞<R1<∞
-∞<R2<∞
-∞<R3<∞
math.sinh(0)math.cosh(0)math.tanh(0)
output
-∞<S1<∞
1≦S2<∞
-1<S3<1
010


math.sqrt(R) 根號
開根號,也就是x0.5,這裡的R為大於0的實數

定義域/值域 範例1範例2
input
0≦R<∞
math.sqrt(25)2^0.5
output
0≦S<∞
51.4142135623731


範例一 螺旋曲線
有了這些函數以後,其實就可以做出很多有特殊軌跡的特效。在一般特效指令當中,我們用到的移動指令有{\move}、{\moves}、{\mover3}、{\mover4}等,也就是說用了那4種移動指令的話,ass只需要1行就可以達成移動的效果,但是如果說沒有內建指令又想達成任意軌跡的話,那上面的自動化指令、實用函數、隱變數、LUA函數就可以派的上用場,和內建特效語法的不同點就是這個結果會輸出非常多行。
先假設我想要畫出一個螺旋軌跡,軌跡如下圖:

上圖使用的是標準的笛卡爾座標系,而這張圖是畫在xy平面的第4象限內,而ass座標系則是和原點映射的笛卡爾座標系。如果要把2維的笛卡爾座標系轉成ass座標系的話,就是在原座標前乘上一個庖立矩陣σz(Pauli Matrix)
庖立矩陣在量子力學當中是一個相當重要的矩陣。轉換結果如下列所示:

簡單來講就是把原先笛卡爾座標系的y前面加一個負號即可,這樣就可以成功轉換到ass座標系當中。
而運動軌跡方程式如上圖所示,在這裡我先把初始點設定在(x0,y0)=(960,540),旋轉半徑r(t)為隨時間改變的函數,且我設定a=5,角速度ω=5,最後t是變數,且單位是,不是毫秒。
如果用ass呈現的話,結果如下:


從這個ass可以看到輸出的結果總共有500行,雖然這個看起來有在移動,但實際上是在這短短的5秒之間就有500張不同位置的
也就是說這500張靜畫構成了一個5秒鐘的動畫,每一張動畫停留的時間為10ms,
在ass的第1行中,var = {"960","540","70","5","10"}表示定義一個自建函數var,而這個函數又是一個矩陣,總共有5個矩陣元。
如果要在下面的template行使用這個矩陣中的數值,那就是用var[N]來拿出某個矩陣元的值。在這個範例中,var總共有5個矩陣元,var[N]就是第選擇第N個矩陣元,也就是var[1]=960var[2]=540,以此類推。
在這裡我設定var函數的內容是x0=960、y0=540、a=70、ω=5、Δt=10。也就是如果下面我想要改變這些參數的話,只需要改變第1行矩陣元內的數字即可。
再來因為這個函數只需要讀取一次就會被儲存在記憶體當中,因此這個code只需要執行一次即可,因此在這個特效欄內寫上code once,這個code的用法可以死記,相當實用。
第2行中的!retime("preline",(j-1)*var[5],j*var[5])!,紅色字體表示出現時間的起點和終點,從j=1開始起跳,直到j=$ldur/var[5]為止,而這裡的var[5]=Δt=10,單位是ms
所以這裡的話,在第j個畫面時,出現時間點為ti=(j-1)*Δt=tj×103,消失時間點為tf=j*Δt=tj×103+Δt,這裡注意Δt的單位是毫秒,而tj的單位是,因此tj後面要乘上一個103
!maxloop($ldur/var[5])!則是迴圈次數,次數又等於是的數量,也就是當間隔為Δt,可以把畫面切成$ldur/Δt個
再來是後面定義位置的特效指令{\fs10\an5\pos(!var[1]+var[3]*(j-1)*var[5]/1000*math.cos(var[4]*(j-1)*var[5]/1000)!,!var[2]+var[3]*(j-1)*var[5]/1000*math.sin(var[4]*(j-1)*var[5]/1000)!)},
注意{\pos(x(tj),y(tj))}這個結構,這裡的x(tj)=var[1]+var[3]*(j-1)*var[5]/1000*math.cos(var[4]*(j-1)*var[5]/1000)=x0+a*tj*cos(ω*tj)=x0+r(tj)*cos(ω*tj)
y(tj)=var[2]+var[3]*(j-1)*var[5]/1000*math.sin(var[4]*(j-1)*var[5]/1000=y0+a*tj*sin(ω*tj)=y0+r(tj)*sin(ω*tj)
上面所表示的是第tj秒時的座標,又因為(j-1)*Δt=tj×103,所以{\pos}內文的tj通通要寫成(j-1)*Δt/1000。
在這個三角函數裡面,因為ωtj單位本身就是弧度了,所以不需要再用math.rad(R)做轉換。
由上面這些指令和語法,就可以完美地畫出運動軌跡。若Δt愈小,所畫出來的圖也會更精緻,缺點是產生的行數和ass的檔案大小也會上升。
如果這個範例當中,時間重設函數改寫成!retime("preline",(j-1)*var[5],$ldur+500)!的話,就可以顯示所有移動的軌跡,如下圖:

可以看到輸出後的畫面和上面完全一致,也就是證明這個ass語法並沒有寫錯。

範例二 任意二維平面曲線
從範例一當中,解釋了移動的原理之後,我們就可以開始考慮最廣義的任意函數,重新再用更嚴謹的方式討論移動軌跡。

上圖是任意向量函數R(s)的軌跡,其中s是該向量函數的參數,並假設從R(s1)移動到R(s2)需要Δt的時間,且需要經由參考點R0將R(s)從第一象限移動到第四象限,也就是移動函數為:

其中Rd(s)表示在笛卡爾座標系中的向量函數。
若移動過程的時間耗時Δt,並將這段過程切成N個靜畫,則時間分配函數和迴圈函數可寫成:
!retime("preline",Δt/N*(j-1),Δt/N*j)! !maxloop(N)!
=!retime("preline",$ldur/maxj*(j-1),$ldur/maxj*j)! !maxloop(N)!
而函數軌跡要從連續函數改成隨著迴圈次數j改變的不連續函數:



範例三 4階貝茲曲線
在內建的特效指令當中,{\moves3}是2階貝茲曲線,{\moves4}是3階貝茲曲線,但是內建的指令當中只有這2種,沒有更高階的指令。
因此若要使用更高階的貝茲曲線,就要另外寫特效語法。貝茲曲線的標準式和曲線示意圖如下:

由這張圖可以看到(x,y)隨參數t改變的軌跡方程式,而貝茲曲線的參數t的範圍是0≦t≦1。所以同樣地,要畫出4階貝茲曲線的方法和範例一相當類似:


在這個ass的第1行,同樣地先定義矩陣函數P0~P4td這6個矩陣函數,其中P0~P4的第1和第2個矩陣元分別是(x0,y0)~(x4,y4),而td則是Δt,表示每個出現的時間間隔。
在同一個code行裡面,可以定義多個函數,中間只需要用;隔開即可,如temp0={"5","8","6"}; temp1={"1","3"}
第2行中的{\pos(x,y)}的結構看起來相當複雜,但這其實就單純是上面算出來的4階方程式而已,唯獨需要注意的是這個貝茲曲線函數Bn(t)的變數t是有範圍限制的,這個時間需要仔細調整。
首先看作用行的時間長度,因為長度是5秒,因此這裡$ldur=5000,之後把這段時間切成N=$ldur/Δt等份。因此每一個出現的時間起點為ti=(j-1)*$ldur/Δt,終點時間tf=j*$ldur/Δt
因此這裡的時間重設函數同樣是寫成!retime("preline",(j-1)*td[1],j*td[1])!,而因為總共有$ldur/Δt個,因此迴圈函數要寫成!maxloop($ldur/td[1])!,
比較麻煩的是參數t,他不像時間要多長就有多長,它有限制範圍0≦t≦1,要把t也切成$ldur/Δt等份,且要設定當j=1時,t=0;當j=$ldur/Δt時,t=1。
先令每個迴圈j之間t的間隔為Δs,也就是tj=(j-1)Δs,分成N段,N=$ldur/Δt,且N*Δs=1,因此可以得到Δs=1/N=Δt/$ldur,所以tj=(j-1)*Δs=(j-1)*Δt/$ldur,
所以在作用行中的{\pos(Bx(t),By(t))}的貝茲曲線位置方程式為
Bx(t)=(1-t)4x0+4(1-t)3tx1+6(1-t)2t2x2+4(1-t)t3x3+t4x4
=(1-(j-1)*td[1]/$ldur)^4*P0[1]+4*(1-(j-1)*td[1]/$ldur)^3*(j-1)*td[1]/$ldur*P1[1]+6*(1-(j-1)*td[1]/$ldur)^2*((j-1)*td[1]/$ldur)^2*P2[1]+4*(1-(j-1)*td[1]/$ldur)*((j-1)*td[1]/$ldur)^3*P3[1]+((j-1)*td[1]/$ldur)^4*P4[1]
By(t)=(1-t)4y0+4(1-t)3ty1+6(1-t)2t2y2+4(1-t)t3y3+t4y4
=(1-(j-1)*td[1]/$ldur)^4*P0[2]+4*(1-(j-1)*td[1]/$ldur)^3*(j-1)*td[1]/$ldur*P1[2]+6*(1-(j-1)*td[1]/$ldur)^2*((j-1)*td[1]/$ldur)^2*P2[2]+4*(1-(j-1)*td[1]/$ldur)*((j-1)*td[1]/$ldur)^3*P3[2]+((j-1)*td[1]/$ldur)^4*P4[2]
若將時間重設函數改寫成!retime("preline",(j-1)*td[1],$ldur+500)!的話,則會變成一個4階貝茲曲線的軌跡,如下圖:

可以看到和上面模擬的結果吻合,所以這個語法沒有寫錯。
如果可以看懂上面2個範例,那相信你特效已經有一定的水準了,可以試著寫寫看不同的軌跡方程式。

習題 黑體輻射曲線
這個曲線是普朗克在1900年所提出的,目的是用來解釋在一個黑體中所放射出來的電磁波其溫度和波長之間的關係,可以修正Rayleigh-Jeans法則在高頻率時產生紫外災變以及Wien法則在低頻率時不符合實驗結果的情形。
在提出這個理論時,普朗克優先使用了能量不連續的概念,也就是E=nhν,並結合波茲曼統計,使得普朗克的黑體輻射曲線可以吻合實驗結果,導致在量子力學這個領域被快速發展。
黑體輻射曲線如下圖所示:

經過y(x)=-y0+a*I(x/b)適當地平移和伸縮後,並轉換至ass座標系,畫出最適當的軌跡。其中a、b為任意實數。

本帖子中包含更多資源

您需要 登錄 才可以下載或查看,沒有帳號?立即註冊

x
頭香
發表於 2014-11-2 18:29:46 | 只看該作者
本帖最後由 wayne85814 於 2014-11-2 18:30 編輯

呃...薛丁格和狄拉克都跑出來了。 讓我想起我的普化其中考試叫我們用薛丁格Equation導出particle in a box(one dimension) 的 wave function & Energy ,老師根本整人。

P.S. 寫的真詳盡,真是太神了。

點評

嗯,有理。我會盡量去理解特效的世界(想試著畫玫瑰線)。  發表於 2014-11-9 08:48
重點不是詳不詳細,而是你看了這個教學是否真的看得懂而且真的學會。  發表於 2014-11-9 02:38
3#
發表於 2015-4-14 00:48:30 | 只看該作者

應4E要求將本文公開 但是放在社員專區會有權限問題 所以先轉到公告區囉~

本帖子中包含更多資源

您需要 登錄 才可以下載或查看,沒有帳號?立即註冊

x
4#
發表於 2015-10-8 22:55:16 | 只看該作者
如果完全是針對新手且不會lua
樓主的教學文我覺得寫得非常好且詳細
5#
發表於 2015-10-11 04:08:48 | 只看該作者
這裡只是個外來人士
在之前是有學一些東西
正想要往特效方面作探究
剛好看到這篇教學很有內容
好奇前面的基礎教學又是如何
可是好像要入社才能看到的樣子
 
 
 
只是無聊的排版
打完這串文時發現
覺得可以這樣玩而已

點評

純粹只是aegisub最基本的特效指令,如\N \fscx \move(x1,y1,x2,y2,t1,t2)...等等,google都找的到,因為太基本,所以不在這篇文章贅述。  發表於 2015-10-11 17:21
6#
發表於 2016-2-1 18:02:23 | 只看該作者
前幾篇教學帖要積分多少呢...有大大推薦我來這學習...
7#
 原PO| 發表於 2016-2-3 10:32:57 | 只看該作者
本帖最後由 tgvr531 於 2016-2-3 10:34 編輯
夜魅殘月 發表於 2016-2-1 18:02
前幾篇教學帖要積分多少呢...有大大推薦我來這學習...

沒有權限推薦看這篇: http://www.douban.com/note/284573295/
內容大同小異
8#
發表於 2016-4-11 00:53:05 | 只看該作者
卧槽,深度好文
您需要登入後才可以推文 登錄 | 立即註冊

本版積分規則

小黑屋|手機版|論壇導覽|TUCaptions

GMT+8, 2024-4-20 03:00 , Processed in 0.055221 second(s), 15 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc. 技術支持 by 巔峰設計.

快速回復 返回頂部 返回列表