
2010-03-11 Advanced SSA (ASS): レイヤーの話
ASSがSSAと大きく違う点の一つとして、レイヤーがある。 レイヤーの概念は簡単なようで少しややこしい。
まずは基本。
Dialogue: 1,0:00:01.00,0:00:05.00,Style1,,0000,0000,0020,,{\3c&Hff0000}Blue
Dialogue: 2,0:00:01.00,0:00:05.00,Style1,,0000,0000,0006,,{\3c&H0000ff}Red
上のように書くと、Blueがレイヤー1、Redがレイヤー2なので、Redの方が「上」に来る。
言い換えると、先にBlueを描画した後で、それを上書きしてRedが描画される。描画順序という意味では「上」とは「順序が後」ということでもある。
レイヤーの番号を入れ替えて、
Dialogue: 2,0:00:01.00,0:00:05.00,Style1,,0000,0000,0020,,{\3c&Hff0000}Blue
Dialogue: 1,0:00:01.00,0:00:05.00,Style1,,0000,0000,0006,,{\3c&H0000ff}Red
とすれば、逆にBlueが上に来る。
ここまでは簡単だった。さて、レイヤーはVSFilterの実装において、32ビット符号付き整数で格納されている。 したがって、単純に考えれば、-2147483648 から 2147483647 の間の任意の数を使うことができるように思える。 その通りなのだが、ここで直観に反することが起きる。例えば、レイヤー21億4700万は数値的にオーバーフローしない。 そして、それはレイヤー -40万(マイナス40万)より上に来る。これは直観に合致する。
Dialogue: 2147000000,0:00:01.00,0:00:05.00,Style1,,0000,0000,0020,,{\3c&Hff0000}Blue
Dialogue: -400000,0:00:01.00,0:00:05.00,Style1,,0000,0000,0006,,{\3c&H0000ff}Red
ところが、下のレイヤーをさらに10万、下げて -50万(マイナス50万)にすると…
Dialogue: 2147000000,0:00:01.00,0:00:05.00,Style1,,0000,0000,0020,,{\3c&Hff0000}Blue
Dialogue: -500000,0:00:01.00,0:00:05.00,Style1,,0000,0000,0006,,{\3c&H0000ff}Red
…マイナスのはずなのに、プラス21億4700万のレイヤーより、上に来てしまった。
つまり、データは32ビット符号付きだが「どちらが上のレイヤーになるか」の比較は、単純な不等号ではなく、 32ビット符号付き整数の引き算で行われる。そのため、大と小の差が2の31乗を越えると、内部的に小の方が大きいと認識される。
一見変なようだが、 メリットもあって、実はVSFilterの実装においては、32ビットを越えてもオーバーフローで無効とはならない。 例えば、22億より23億が上にある…といった比較が正しく行われる。 内部的には、21億台までしか表現できないはずで、プラス22億はマイナスの数、23億はそれより絶対値の小さいマイナスの数、として格納されてしまうが、 差で考えると、23億の方が上にあることは変わりない。 言い換えると、レイヤーを32ビット符号なし整数(0~4294967295)で扱っても、差が2の31乗より下なら、正しく扱われる。 それどころか、実は、レイヤーを64ビットで扱っても、差が2の31乗までなら上下関係が正しく扱われる。 さらに64ビットを越えてもエラーにはならないが、その場合に起きることは少し複雑で、実用上もまず関係ないので、ここでは省略する。
ASSでレイヤーを付けるとき、複雑なエフェクトの場合、1、2、3…100のように単純にレイヤー番号を使うと、後からレイヤー2とレイヤー3の間に別のレイヤーを装入したくなったときに困る(3より上を全部ずらさないと装入できない)。 そうならないように、100、200、300…のように余裕を見てレイヤーを離すのがいい。 複雑なカラオケやロゴなどが同時進行すると、区別のために巨大なレイヤー番号を使ってしまうこともあるが、 上のような問題があるので、プラスの数はなるべく9桁まで、10桁にする場合は一番上の位は1にするのが良い。 一番上の位が2でも、21億までならオーバーフローしないが、紛らわしくなる(うっかりすると、すごく上のはずのレイヤーがレイヤー0より下に来てしまう)。 マイナスのレイヤーはVSFilterでは解釈されるが、パーサーによっては問題が生じるかもしれないので、なるべく避け、 どうしても使う場合は、マイナス5桁程度までにとどめておけば、最大の差が2の31乗で抑えられるので、レイヤー関係が混乱しないだろう。
エフェクトではなく、二人の人が同時にしゃべる場合のような通常の字幕では、1や2といった分かりやすいレイヤー番号を使う方がいい。 もちろん0と1でもいいのだが、それだと同時現象が起きていることがスクリプトを見てパッと分からないので、 レイヤーを使ってコントロールしているところは、1と2など、0以外を使った方がいい。 手動でレイヤーを離して高さを変えなくても、同じレイヤー上で字幕の位置が重なるときは、自動コリジョン処理で後から処理される字幕が前の字幕をよけるように描画される。しかし、この自動処理に頼ると、時間的に前からシークしたとき・後ろからシークしたとき・直接飛び込んだときなどで字幕の位置が違ってしまい、 AVSのキャッシュなどでややこしい問題が生じるので、タイミングが重なる字幕はすべて明示的にレイヤーを離して位置を指定するのが安全だろう。
もう一つ、直観に反することは、ドローイング・コマンド {\p} もコリジョン処理されること。 {\pos} の位置指定はコリジョン処理されないが、同じ感覚で {\p} は使えない。 例えば大小の円を二つ重ねて二重丸を作るとき、二つの円のレイヤーが同じだと、重なってくれない。 混乱を避けるため、時間的にタイミングが重なる字幕はどの二つも、空間的に重なるかどうかと無関係に、レイヤーを離して位置を明示的に指定した方が安全だ。 初めはコリジョンしない、と思っていても、後でmoveのようなエフェクトを追加したりして、予定外のコリジョンが生じる可能性もある。 レイヤーを変えておけばややこしい問題の可能性を最初からなくせるばかりか、 レンダラーも当たり判定(自動コリジョン処理=同一レイヤーのイベントには必要)をしないで済み、レンダラーにも優しい書き方と言えるだろう。
注意: リンクが切れている記事がありますが、そのうち直します。ごめんなさい。
応援団を応援することは正しいか / タンポポの綿毛を吹いて飛ばしていいか
攻殻美味しんぼ — 'Bot for the Chef / 仏説ラーメンライス / 新訳・仏説ラーメンライス
Urban Dictionary というサイトをご存知でしょうか。 ウィキペディアみたいな、でもそれよりずっとくだけた(適当な書き込みも多い)新語辞典という感じのもの。 fred ressler というハンドル名の人の投稿を偶然見て、妙に心引かれた。
JIS第3水準・第4水準漢字と Unicode Plane 2
JavaScriptを使ってブラウザ上で暗号系の動作を実演、 1ステップずつ解説
n=3, 4, …, 7 に対して 10n! の末尾の0の個数は 249, 2499, 24999, 249998, 2499999 だ。なぜ106のときは 249999 にならないか
ミニチュア版・楕円曲線暗号もJavaScriptで実演
「ぬるさ」とは何か なぜそれが自滅を招くのか
人間と神
第3話 マイクロソフト製「彼女」
教会でカップめんは食えるか?
「世の中には10種類の人間がいる。二進法が分かる者と分からない者だ」
この記事だけで、SRT相当の最低限の字幕を自作可能
SSAを編集して字幕の表示スタイルを制御
シーンチェンジと字幕のタイミングの詳細
Windows上のMKV再生で、 ソフトサブ字幕のタイミングが重なっているとき、 後から出る側の字幕の影の透過度が異常になることがある。
t-rカラオケで{\K}を使わないパターン / \t(0,0) は避けるべき / 字幕のリップシンクの閉口側 / EmEditorのSSA/ASS構文強調を素早くオンオフ / t-rカラオケの応用では{\r}を使わない方が良い場合も / きれいなルビ付き縦カラオケ / 縁だけでない縁ワイプ、シャドウのあるt-clip / ほか
FAIREAL.NET Key fingerprint A3 ED EB 91 3A 86 FC AC CD D8 DC 72 EB 36 FB FD