アンチフリッカ - [[AEexpression]]
目次
アンチフリッカ
サンプル付きのダウンロードはこちら http://www.nekomataya.info/cgi-bin/control.cgi?PAGE=85&ITEM=070901
特定の原因で起きるPANショットのフリッカを解消するアニメーションプリセットです。
どのようなケースで使用するかというと。
↑こんなケース
作画が大判(背景に対して固定)で2k以上のコマ撮りかつ結構早めのcameraワークつきで 「カメラワーク速度と被写体セルの移動速度が近接している」状態で発生する「ガコガコ」です。
被写体をカメラで追いかけているショットでは、よくある状況です。 このアニメーションプリセットを使って以下の様に滑らかに中間値を生成することが 「出来ないこともない」です。
もう少しキレイなサンプルはこちらをどうぞ
http://www.nekomataya.info/teck_info/traceExpressions/index.html
このテンプレートと同様の目的のエクスプレッションはこちらのサイトにも解説があります。
http://homepage3.nifty.com/higematsu/
また、作画T.U.(または T.B.)で1k撮りになっていない(出来ない)ケースの動画補間にも使用できるように このアニメーションプリセットではトレーサレイヤのサイズを参照する仕様になっています。
このアニメーションプリセットは、タイムリマップされたレイヤに対して適用します。
使い方
- まず、セル組したレイヤから効果をかける適用部分を抽出します。 対象が別セルになってる場合はそのセルを、書き込みの場合はそれなりに分離しておいてください。
- 次に「トレーサレイヤ」を設定します。種類はなんでも良いですがヌルや平面(ソリッド)が一般的です。 精密なトレースを行う場合は基準になるセル画像を静止画で抜き出してトレーサに使うと作業がラクです。 ヌル以外を選択した場合は、トレーサをガイドレイヤーにして本番レンダリングで表示されない様注意してくださいね。
トレーサレイヤは効果をかけるレイヤのすぐ上に置いてください。 (レイヤインデックスが対象レイヤの(index-1)となる重ね位置です)
このレイヤを参照して画像の調整を行います。
- この「トレーサレイヤ」で、動画の動きをトレースします。・ 細かい手順はサンプルデータをご覧ください。
手間をいとわなければ、動画一枚一枚にあわせてキーを作ると良いでしょう。
動きが単純ならば最初と最後の位置にキーをつけて中間のキーを省いてもかまいません。
- 処理対象のレイヤにアニメーションプリセットを適用します。
このアニメーションプリセットは以下の様に働きます。
本体レイヤのタイムリマップのキーをみて、
1. 現在のtimeにタイムリマップキーがあれば、現行の値を保持
2. キーがなければ,直前のキー時間のトレースレイヤの状態と 現在のトレースレイヤの状態の差を本体プロパティに加える
トレースレイヤ(直上のレイヤ)の位置(や角度・スケールなどの)プロパティを「真似する」わけです。 これで、3k撮りの動画を1kづつ中割り移動させることが出来ます。
トレースレイヤの動きを調整して、きれいな動きになる様にがんばってください。
位置を1コマごとにずらすので、背景とクミ合わせ(位置あわせ)が発生する動画には適用できないか または困難な場合があります。たとえば、足元が画面に入っている追従(フォロー)ショット等では、 この処理を行うと「足の位置ずれ」の方がフリッカよりも気になる場合があるので、 それはそれ、ケースごとに使い分ける様にしてください。
このアニメーションプリセットには簡易版とフルスペック版があります。
簡易版は、二次元で「位置」プロパティだけを計算します。 被写体のサイズがあまり変わらないショットにはこちらが処理が軽くて良いでしょう。
フルスペック版は、サイズと角度も追従するので「回転しながらT.U.」など 一コマごとのサイズの差が大きい場合はこちらをご利用ください。 ちょぴり動作が重いのと、キーをたくさん打って手間をかけてやらないと 「ガタガタ」しやすいのでご注意ください。
作画による拡大縮小を2k撮り以上のコマ撮りで行っている場合は、このテンプレートを利用して 中間のサイズと位置を補間することが可能です。
フルスペック版では、トレーサレイヤに三次元モードも使用可能です。
このアニメーションプリセットはタイムリマップのキーを参照しますので、 適用するレイヤはタイムリマップが有効になっている必要があります。 1枚の静止画を拡大縮小してアニメーションするケースなどでは、事前にプリコンポして タイムリマップを有効にしておいてください。
じゃ、いつものおまじない
- おことわり このプログラムの著作権は「ねこまたや」にあります。
あなたは、このプログラムのこの著作権表示を改変しないかぎり 自由にプログラムの使用・複製・再配布などを行うことができます。
あなたは、このプログラムを自己の目的にしたがって改造することができます。 その場合、このプログラムを改造したものであることを明記して、この著作権表示を 添付するように努めてください。
このプログラムを使うも使わないもあなたの自由なのです。
作者はこのプログラムを使用したことによって起きたいかなる 不利益に対しても責任を負いません。 あなたは、あなたの判断と責任においてこのプログラムを使用するのです。
なんか、困ったことがあったら以下で連絡してもらえると何とかなるかもしれません。 http://www.nekomataya.info/ nekomataya@gmail.com
以下、ソース
簡易版ソース
位置のオフセットのみを処理するので動作は軽快です。 セルごとのサイズや角度の差が大きい時はフルスペック版を推奨
/* 即席版コマ割りエクスプレッション タイムリマップされたレイヤの位置の中割をします。 このエクスプレッションは、ポジションまたはオフセットに適用してください。 トランスフォームエフェクトのポジションもOK トレーサー用のレイヤを設定してそのレイヤでセルの動きをトレースします。 このエクスプレッションはトレーサの動きを追跡します。 タイムリマップにキーのある位置は保持されます。 2007/09/01 nekomataya kiyo */ var myTracer=thisComp.layer(index-1); var baseTime=0; //直前のタイムリマップキーの時間を取得 if(this.timeRemap.numKeys>1){ if(this.timeRemap.nearestKey(time).time>time) { baseTime=this.timeRemap.key(this.timeRemap.nearestKey(time).index-1).time; }else{ baseTime=this.timeRemap.nearestKey(time).time; } }else{ if(this.timeRemap.numKeys==1 && this.timeRemap.key(1).time<time){ baseTime=this.timeRemap.key(1).time; } } //直前キーの時間と現在のフレーム差を取得 var mySliceOffset=(time-baseTime)/thisComp.frameDuration; //トレースレイヤのbaseTime位置と現在位置の差分を本体レイヤの位置に反映する。 add(this.value,sub(myTracer.position.valueAtTime(time),myTracer.position.valueAtTime(baseTime)));
フルスペック版ソース
トランスポートエフェクトのanchorPoint,Position,scale,rotation に対して適用してください。
/****** for anchorPoint *******/ //各プロパティ共通部分 var myTracer=(index>2)?thisComp.layer(index-1):thisComp.layer(1);//ひとつ上のレイヤを設定 var baseTime=0; //直前のタイムリマップキーの時間を取得 if(this.timeRemap.numKeys>1){ if(this.timeRemap.nearestKey(time).time>time) { baseTime=(this.timeRemap.nearestKey(time).index>2)?this.timeRemap.key(this.timeRemap.nearestKey(time).index-1).time:0; //ケースによって直前キーが存在しない場合例外処理として0を設定 }else{ baseTime=this.timeRemap.nearestKey(time).time; } }else{ if(this.timeRemap.numKeys==1 && this.timeRemap.key(1).time<time) { baseTime=this.timeRemap.key(1).time; } } //各プロパティ共通部分オワリ //アンカーポイントをトレーサの位置をレイヤローカル座標に変換して置き替え if(myTracer.position.value.length==2){ myTracer.position.valueAtTime(baseTime); }else{ //スケール //トレースレイヤの表示比率取得 AE6.5以降版 //デフォルトカメラの値を設定(推測ナノデはずれてたら御免) var myZoom=Math.tan(degreesToRadians((180-39.5980)/2))*(thisComp.width/2); var cameraPosition=[thisComp.width/2,thisComp.height/2,-myZoom]; //レイヤにカメラがあるかチェックする var hasCamera=false; for(idx=1;idx<=thisComp.numLayers;idx++){ if((thisComp.layer(idx) instanceof Camera)&&(thisComp.layer(idx).active)){hasCamera=true;break;}else{continue;} } //カメラレイヤがあればアクティブカメラを使う(アクティブカメラがない場合はエラー) if(hasCamera){ myZoom=thisComp.activeCamera.zoom; cameraPosition=thisComp.activeCamera.position; } //視点からレイヤまでの距離を出して比の逆数で計算 //var myBaseDistance=length(cameraPosition,myTracer.position.valueAtTime(baseTime));//カメラ位置からキー位置のトレーサまで距離 var myBaseDistance=Math.abs(cameraPosition[2]-myTracer.position.valueAtTime(baseTime)[2]); var myDistance=Math.abs(cameraPosition[2]);//カメラ位置から投影面中央まで距離 //zoom動作とanchorオフセットを考慮した計算 //var myScale=(myZoom/myBaseDistance)*myBaseDistance/length(sub(myDistance,cameraPosition)); var myScale=(myDistance/myBaseDistance); toComp( add(mul( sub(fromComp( myTracer.position.valueAtTime(baseTime) ),[width/2,height/2]),myScale ),[width/2,height/2]) );// 3D処理 }
/****** for position *******/ //各プロパティ共通部分 var myTracer=(index>2)?thisComp.layer(index-1):thisComp.leyer(1);//ひとつ上のレイヤを設定 var baseTime=0; //直前のタイムリマップキーの時間を取得 if(this.timeRemap.numKeys>1){ if(this.timeRemap.nearestKey(time).time>time) { baseTime=(this.timeRemap.nearestKey(time).index>2)?this.timeRemap.key(this.timeRemap.nearestKey(time).index-1).time:0; //ケースによって直前キーが存在しない場合例外処理として0を設定 }else{ baseTime=this.timeRemap.nearestKey(time).time; } }else{ if(this.timeRemap.numKeys==1 && this.timeRemap.key(1).time<time) { baseTime=this.timeRemap.key(1).time; } } //各プロパティ共通部分オワリ //トレーサの位置をコンポ内の座標に変換して置き替え if(myTracer.position.value.length==2){ myTracer.position.valueAtTime(time);// 2D処理 }else{ //スケール //トレースレイヤの表示比率取得 AE6.5以降版 //デフォルトカメラの値を設定(推測ナノデはずれてたら御免) var myZoom=Math.tan(degreesToRadians((180-39.5980)/2))*(thisComp.width/2); var cameraPosition=[thisComp.width/2,thisComp.height/2,-myZoom]; //レイヤにカメラがあるかチェックする var hasCamera=false; for(idx=1;idx<=thisComp.numLayers;idx++){ if((thisComp.layer(idx) instanceof Camera)&&(thisComp.layer(idx).active)){hasCamera=true;break;}else{continue;} } //カメラレイヤがあればアクティブカメラを使う(アクティブカメラがない場合はエラー) if(hasCamera){ myZoom=thisComp.activeCamera.zoom; cameraPosition=thisComp.activeCamera.position; } //視点からレイヤまでの距離を出して比の逆数で計算 //var myBaseDistance=length(cameraPosition,myTracer.position.valueAtTime(baseTime));//カメラ位置からキー位置のトレーサまで距離 var myBaseDistance=Math.abs(cameraPosition[2]-myTracer.position.valueAtTime(time)[2]); var myDistance=Math.abs(cameraPosition[2]);//カメラ位置から投影面中央まで距離 //zoom動作とanchorオフセットを考慮した計算 //var myScale=(myZoom/myBaseDistance)*myBaseDistance/length(sub(myDistance,cameraPosition)); var myScale=(myDistance/myBaseDistance); toComp( add(mul( sub(fromComp( myTracer.position.valueAtTime(time) ),[width/2,height/2]),myScale ),[width/2,height/2]) );// 3D処理 }
/****** for scale *******/ //各プロパティ共通部分 var myTracer=(index>2)?thisComp.layer(index-1):thisComp.leyer(1);//ひとつ上のレイヤを設定 var baseTime=0; //直前のタイムリマップキーの時間を取得 if(this.timeRemap.numKeys>1){ if(this.timeRemap.nearestKey(time).time>time) { baseTime=(this.timeRemap.nearestKey(time).index>2)?this.timeRemap.key(this.timeRemap.nearestKey(time).index-1).time:0; //ケースによって直前キーが存在しない場合例外処理として0を設定 }else{ baseTime=this.timeRemap.nearestKey(time).time; } }else{ if(this.timeRemap.numKeys==1 && this.timeRemap.key(1).time<time) { baseTime=this.timeRemap.key(1).time; } } //各プロパティ共通部分オワリ if(myTracer.position.value.length==2){ // 2D処理 //スケール 100*myTracer.scale.valueAtTime(time)[0]/myTracer.scale.valueAtTime(baseTime)[0]; }else{ // 3D処理 //スケール //トレースレイヤの表示比率取得 AE6.5以降版 //デフォルトカメラの値を設定(推測ナノデはずれてたら御免) var myZoom=Math.tan(degreesToRadians((180-39.5980)/2))*(thisComp.width/2); var cameraPosition=[thisComp.width/2,thisComp.height/2,-myZoom]; //レイヤにカメラがあるかチェックする var hasCamera=false; for(idx=1;idx<=thisComp.numLayers;idx++){ if((thisComp.layer(idx) instanceof Camera)&&(thisComp.layer(idx).active)){hasCamera=true;break;}else{continue;} } //カメラレイヤがあればアクティブカメラを使う(アクティブカメラがない場合はエラー) if(hasCamera){ myZoom=thisComp.activeCamera.zoom; cameraPosition=thisComp.activeCamera.position; } //視点からレイヤまでの距離を出して比の逆数で計算 var myBaseDistance=length(cameraPosition,myTracer.position.valueAtTime(baseTime));//カメラ位置からキー位置のトレーサまで距離 var myDistance=length(cameraPosition,myTracer.position.valueAtTime(time));//カメラ位置から現在のトレーサまで距離 //zoom動作とanchorオフセットを考慮した計算 //var myScale=(myZoom/myBaseDistance)*myBaseDistance/length(sub(myDistance,cameraPosition)); var myScale=(myBaseDistance/myDistance); 100*myScale*(myTracer.scale.valueAtTime(time)[0]/myTracer.scale.valueAtTime(baseTime)[0]); //この値はスケールの比が1:1でロックされていることが前提です。 //トレーサ・適用セルともにスケールの連動プロパティを固定してください。 }
/****** for rotation *******/ //各プロパティ共通部分 var myTracer=(index>2)?thisComp.layer(index-1):thisComp.leyer(1);//ひとつ上のレイヤを設定 var baseTime=0; //直前のタイムリマップキーの時間を取得 if(this.timeRemap.numKeys>1){ if(this.timeRemap.nearestKey(time).time>time) { baseTime=(this.timeRemap.nearestKey(time).index>2)?this.timeRemap.key(this.timeRemap.nearestKey(time).index-1).time:0; //ケースによって直前キーが存在しない場合例外処理として0を設定 }else{ baseTime=this.timeRemap.nearestKey(time).time; } }else{ if(this.timeRemap.numKeys==1 && this.timeRemap.key(1).time<time) { baseTime=this.timeRemap.key(1).time; } } //各プロパティ共通部分オワリ //Z軸の回転のみ処理 if(myTracer.position.value.length==2){ myTracer.rotation.valueAtTime(time)-myTracer.rotation.valueAtTime(baseTime);//2D }else{ myTracer.rotation.valueAtTime(time)-myTracer.rotation.valueAtTime(baseTime)+myTracer.orientation.valueAtTime(time)[2]-myTracer.orientation.valueAtTime(baseTime)[2];//3D };
なにか、間違ってたり「ヘボい」動作があったら教えてね。 では
Nekomataya/kiyo 2007/09/10
Powered by YukiWiki 2.1.2a / Modified by Nekomataya.