2017年2月26日日曜日

▼わたり様が公開しているZファイティング対策用シェーダの使い方と注意点_2017年3月版







Zファイティング 及び Zファイティング対策用シェーダとはなんぞやという方はこちら⇒ http://mmd-aero-group.blogspot.jp/2017/02/mmdz20173.html





Zファイティング対策用シェーダ/わたり様の用法と注意点



Zファイティング対策用シェーダの配布ファイルの中身は、
シェーダー (『full_LimitedNearFar.fx』、改変されたExcellentShadow2の『full_ES.fx』等がこれにあたります) と
コントローラーNearFarController.x が、基本のセットになります。

同梱のエフェクトはそれぞれZファイティング対策シェーダ用に改変されたものになっています。


使い方は
Zファイティングを防ぎたいモデル・アクセサリに、シェーダーを適用し、
コントローラーで描画距離を指定する
です。


一旦中間の説明を省きますが、実際にやることは

  0. 『ダミーボーンを読み込む。』※MMD付属のものでも自作のものでも何でもOK。既に読み込み済みならここは省略。

1. エフェクト割り当てでスカイドーム以外のモデル・アクセサリにfull_LimitedNearFar.fx(あるいは改変ExcellentShadow2のfull_ES.fx)を割り当てる。


2. NearFarController.xを読み込み、ダミーボーンに登録。
X軸に0以上・Y軸に50000程度の数値を入力する。

の2つ(+1)で完了です。




 ▼参考動画(エフェクト適用の実演・約40秒) 








説明1・Zファイティング対策用シェーダの描画

仕様として。Zファイティング対策用シェーダを適用したモデル・アクセサリは、Zファイティング対策用シェーダを適用していないモデル・アクセサリより前面に表示されます。

 ▼参考画像 
モデルの位置関係  前方・初音ミクさん、真ん中・鏡音レンさん、後方・鏡音リンさん。

 後方・鏡音リンさんのみにZファイティング対策用シェーダを適用した場合、前2人を無視して描画される状態になる。








モデル・アクセサリの前後関係を無視する形で描画されてしまうので注意が必要です。
基本的に、スカイドーム以外の全てのモデル・アクセサリにシェーダーを適用していく形になります。
(Zファイティング対策用シェーダを適用したい対象が常に最前面にある場合は、他のモデル・アクセサリにシェーダーを適用する必要はありません。 ※この画では、初音ミクさんだけにシェーダを適用できればいい場合です。)





 ▼参考画像(対象が常に最前面にある場合) 

実際の使用例。このシーンでは航空機・人物モデルのみにZファイティング対策用シェーダを適用しています。
 (動画 small wings より)






【個人的なオススメ】
個人的には、使用するシェーダーは改変ExcellentShadow2の『full_ES.fx』がおすすめです。

理由は自分がExcellentShadow2を使うことが多いからなのですが、full_ES.fxはExcellentShadow.xを読み込まなくてもZファイティング対策シェーダーの効果を発揮します

※ full_LimitedNearFar.fx と同等の効果になります。

※ExcellentShadow2はExcellentShadow.xを読み込むと激重になりますが、full_ES.fxを適用しただけではMMDを普通に起動しているだけと変わらないような状態です。 個人的にはfull_ES.fxを適用しただけの状態で作業して最後の仕上げにExcellentShadow.xを読み込み、動画を出力するという手順で作業しています。

ExcellentShadow2をまず使わないという方 full_LimitedNearFar.fx で、何も問題ないですm(__)m





説明2・コントローラーの設定_描画距離・視程と精度

Zファイティング対策用シェーダはコントローラーで描画距離を設定し、描写精度を調節しています。
(指定した範囲外は描画されません。)
(原理的に描画距離の下限と上限の差が小さいほど精度が上がるみたいです。)

 コントローラーはX軸Near近い・下限Y軸Far遠い・上限となります。
 私は基本、X軸値20・Y軸値50000ぐらいで使うことが多いです。
 ( X軸 値は小さな数値でも精度に影響してくる印象で、接写する以外ではなるべく 0 より上の数値を入れています。)


 個人的にNearFarController.xはダミーボーンにくっつけて使うことを推奨します。
撮影に合わせて精度を調節しやすいためです。これは操作上の好みの問題ではなく、アクセサリ登録で数値を操作する場合はキーフレーム間の補間が行われない、デメリットを考慮しています。


 ▼参考画像 
0フレーム(X軸値1000Y軸値20000)70フレーム(X軸値0Y軸値20000)140フレーム(X軸値1000Y軸値20000)3箇所にキーフレームを打った場合の描画の変化。 

・アクセサリで直接キーフレームを打った場合、キーフレーム間の精度の補間ができない。


・ボーン(ダミーボーン登録)でキーフレームを打った場合、キーフレーム間の精度の補間が可能。





【個人的な留意点】
運用上の注意点として。 
Zファイティング対策用シェーダの仕様上、カメラ直前と超遠方の被写体を同時に写すような撮影は厳しいことがあります。状況によっては別撮りで合成なども考えたほうがいいと思われます。







説明3・Zファイティング対策シェーダとその他のエフェクトの共存・改変

説明1で、

"仕様として。Zファイティング対策用シェーダを適用したモデル・アクセサリは、Zファイティング対策用シェーダを適用していないモデル・アクセサリより前面に表示されます。"

と書きましたがこれはエフェクトも例外ではありません
またMMEは一モデルに一シェーダーしか使えないので、そのままでは他のシェーダー・エフェクトが使えません。

エフェクトを使う場合は、Zファイティング対策用シェーダを加味した改変が必要になります。


 ▼参考画像 

1. モデルの位置関係 jetsmoke / 針金P様(煙のエフェクト)が最前列。


2. Zファイティング対策シェーダ用の改造をしていない通常の状態では、前面に表示することができない。



3. Zファイティング対策シェーダ用の改造をすれば、並び通りに描画可能。






※すでに自分がよく使わせてもらっているエフェクト(ExcellentShadow2等)は改変されたものを同梱してもらっています。
※ポストエフェクトはそのままで使えることが多いと思いますが、場合によっては改変が必要になることも考えられます。(Zファイティング対策用シェーダ: readme参照)



簡単に確認しただけですが、AutoLuminous4、Diffusion7、o_Tonemap、PostMovie、PowerDOF、ikPosterizeは改造無しで使えるようでした。

エフェクトの改造についてはreadmeに改変方法の記述がありますし、既に改変済みの同梱エフェクトなどを参考にチャレンジしてみるといいと思います。

※エフェクトの記述によるとは思いますが、割と簡単だと思います。(プログラム素人の私でも一応改造可能でした)
※どうしても難しかったり、上手く行かない場合はわたり様やエフェクトに詳しい方に相談してみるとよいと思いますm(__)m











おまけ


必要があって、自分が改変(あるいは改変に挑戦)したエフェクトについては改造例として載せていこうかと思っています。
※私はあまりエフェクトを使う人ではないので更新はごく稀になると思いますm(__;)m
※私の環境でたまたま動いているだけで、記述が足りない場合も考えられます。
 参考程度に見ていただいて、動くならそれで良し・エラーが出るようなら自分で改変にチャレンジしてもら えたらと思います。
※また『この記述がおかしい』などありましたら、ご指摘いただけると助かりますm(__)m


以下、エフェクト改変例  : 170408更新
※灰色の部分を改変しています。
更新170224 ・アフターバーナーエフェクト/井桁様
更新170408 ・o_full-AlphaTest.fx/おたもん様



・アフターバーナーエフェクト / 井桁様

配布先⇒ http://seiga.nicovideo.jp/seiga/im6171559

AfterBurner.fx ファイル、51行目あたりの記述を変更します。



・元(オリジナル版)の記述
float4x4 WorldMatrix : World;
float4x4 ViewProjectionMatrix : ViewProjection;

float4x4 WorldViewMatrixInverse        : WORLDVIEWINVERSE;
static float3x3 BillboardMatrix = {
    normalize(WorldViewMatrixInverse[0].xyz),
    normalize(WorldViewMatrixInverse[1].xyz),
    normalize(WorldViewMatrixInverse[2].xyz),
};

float Time : TIME <bool SyncInEditMode=true;>;

float Tr : CONTROLOBJECT < string name = "(self)";string item = "Tr";>;

---------------------------------------------------------

・改変した記述
float4x4 WorldMatrix : World;
float4x4 ViewMatrix        : VIEW;
float4x4 orgProjMatrix            : PROJECTION;

float4x4 ControllerMatrix : CONTROLOBJECT < string name = "NearFarController.x"; >;
static float near = ControllerMatrix[3].x+1.0f;
static float far  = ControllerMatrix[3].y;

static float4x4 ProjMatrix = float4x4(
    orgProjMatrix[0],
    orgProjMatrix[1],
    float4( 0, 0, far / (far-near), 1 ),
    float4( 0, 0, -near * far / (far-near), 0 )
);

static float4x4 ViewProjectionMatrix = mul( ViewMatrix, ProjMatrix );

float4x4 WorldViewMatrixInverse : WORLDVIEWINVERSE;
static float3x3 BillboardMatrix = {
    normalize(WorldViewMatrixInverse[0].xyz),
    normalize(WorldViewMatrixInverse[1].xyz),
    normalize(WorldViewMatrixInverse[2].xyz),
};

float Time : TIME <bool SyncInEditMode=true;>;

float Tr : CONTROLOBJECT < string name = "(self)";string item = "Tr";>;





・o_full-AlphaTest.fx / おたもん様

配布先⇒ http://seiga.nicovideo.jp/seiga/im3131306

o_full-AlphaTest.fx ファイル、最初の// 座法変換行列 の記述を変更します。


・元(オリジナル版)の記述

// 座法変換行列
float4x4 WorldViewProjMatrix      : WORLDVIEWPROJECTION;
float4x4 WorldMatrix              : WORLD;
float4x4 ViewMatrix               : VIEW;
float4x4 LightWorldViewProjMatrix : WORLDVIEWPROJECTION < string Object = "Light"; >;

float3   LightDirection    : DIRECTION < string Object = "Light"; >;
float3   CameraPosition    : POSITION  < string Object = "Camera"; >;

---------------------------------------------------------

・改変した記述
// 座法変換行列
float4x4 ControllerMatrix : CONTROLOBJECT < string name = "NearFarController.x"; >;
static float near = ControllerMatrix[3].x+1.0f;
static float far  = ControllerMatrix[3].y;

float4x4 WorldMatrix              : WORLD;
float4x4 ViewMatrix               : VIEW;
float4x4 orgProjMatrix            : PROJECTION;

static float4x4 ProjMatrix = float4x4(
    orgProjMatrix[0],
    orgProjMatrix[1],
    float4( 0, 0, far / (far-near), 1 ),
    float4( 0, 0, -near * far / (far-near), 0 )
);

static float4x4 WorldViewProjMatrix = mul( mul( WorldMatrix, ViewMatrix), ProjMatrix);

float4x4 LightWorldViewProjMatrix : WORLDVIEWPROJECTION < string Object = "Light"; >;

float3   LightDirection    : DIRECTION < string Object = "Light"; >;
float3   CameraPosition    : POSITION  < string Object = "Camera"; >;


※Zファイティング対策用シェーダ添付の改造ExcellentShadow2・full_ES.fx の記述からそのままコピペしましたm(__)m





以上。




0 件のコメント:

コメントを投稿