SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

MikuMikuEffectで学ぶHLSL入門

3DCGツール「MikuMikuDance」のエフェクトを拡張する「MikuMikuEffect」
ポストエフェクトの作成方法

MikuMikuEffectで学ぶHLSL入門(5)

ダウンロード sample.zip (10.5 KB)

スクリーン全体を描画するシェーダを記述

 ポストエフェクト本体の処理は、スクリーンに一致するサイズの長方形のポリゴンを描画するシェーダを作成して、その中で行います。これには、まずテクニック内のパス定義で以下のようにスクリプトを記述します。

パスのスクリプト
    pass DrawBuffer < string Script= "Draw=Buffer;"; > {
        AlphaBlendEnable = FALSE;
        VertexShader = compile vs_2_0 VS_DrawBuffer();
        PixelShader  = compile ps_2_0 PS_DrawBuffer();
    }

 この"Draw=Buffer;"というコマンドにより、シェーダが描画するオブジェクトが、スクリーンに一致するサイズの長方形のポリゴンになります。

 頂点シェーダは以下のように実装します。カメラ等の座標変換が必要ないため、基本的に入力されたポリゴンの頂点情報をそのまま出力する形になります(TexにViewportOffsetを加えている点については補足1を参照)。

頂点シェーダ
VS_OUTPUT VS_DrawBuffer( float4 Pos : POSITION, float4 Tex : TEXCOORD0 ){
    VS_OUTPUT Out; 
    
    Out.Pos = Pos;
    Out.Tex = Tex + ViewportOffset;
    
    return Out;
}

 そして、ピクセルシェーダでポストエフェクト本体の処理を実装します。以下の例では、入力したピクセル色をそのままスクリーンに出力しているので、無編集のポストエフェクトになります。

ピクセルシェーダ
float4 PS_DrawBuffer(float2 Tex: TEXCOORD0) : COLOR
{   
    float4 Color = tex2D( ScnSamp, Tex );
    
    // 何か処理
    
    return Color;
}
補足1 テクスチャ座標のオフセットずらし

 典型的なポストエフェクトの頂点シェーダは以下のようなものになります。

頂点シェーダ
// スクリーンサイズ
float2 ViewportSize : VIEWPORTPIXELSIZE;
// スクリーンサイズを1としたときの、0.5ピクセル分
static float2 ViewportOffset = (float2(0.5,0.5)/ViewportSize);

VS_OUTPUT VS_DrawBuffer( float4 Pos : POSITION, float4 Tex : TEXCOORD0 ){
    VS_OUTPUT Out; 
    
    Out.Pos = Pos;
    Out.Tex = Tex + ViewportOffset;
    
    return Out;
}

 ここで、テクスチャ座標Texは、(0,0)でスクリーン左上の点を指し、(1,1)でスクリーン右下の点を指します。この頂点シェーダではTexにViewportOffsetを加えていますが、もしも、入力されたTexの値を変更せずにそのままピクセルシェーダに渡して、入力テクスチャの座標として使用した場合、次のような問題が発生します。
 

 ラスタライザによって頂点情報がピクセル単位へと展開されるとき、あるピクセルの頂点情報は、そのピクセルの左上の点における情報になります。例えばスクリーン上の最も左上のピクセルについて考えると、ViewportOffsetを加えていなければTexの値は(0,0)になります。これはこのピクセルを表す1x1の四角形の左上の点を指し、ピクセルの中心は指しません。テクスチャの各ピクセルの色を正確に取得するためには、tex2D()関数には、ピクセルの四角形の中心を指す座標を与える必要があります。サンプラの設定にもよりますが、テクスチャ座標が1つのピクセルの中心を指しておらず、ピクセル同士の境界の座標を指している場合、得られるピクセル色は双方のピクセルの色の平均になります。
 

 これを避けるために、頂点シェーダでTexにViewportOffsetを加えるという操作を行っています。これにより、テクスチャ座標が縦横ともに0.5ピクセル分ずれ、ピクセルシェーダにおけるTexの値がピクセルの中心座標を指すようになります。

次のページ
ぼかしフィルタ

この記事は参考になりましたか?

MikuMikuEffectで学ぶHLSL入門連載記事一覧

もっと読む

この記事の著者

舞力介入P(ブリョクカイニュウピー)

ニコニコ動画でMMD関連のツール開発者として活動中。代表作は「MikuMikuEffect」。我流のAPI Hookを常套手段とする、邪道プログラマです。ニコニコ動画マイリスト

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/6298 2011/12/09 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー