SHOEISHA iD

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

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

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

MikuMikuEffectで学ぶHLSL入門

「MikuMikuEffect」のエフェクトファイルの内部構成とシェーダコードの編集方法

MikuMikuEffectで学ぶHLSL入門(3)

ダウンロード simple.zip (1.6 KB)

頂点シェーダの編集

 サンプルの頂点シェーダでは、オブジェクトの頂点1つずつに対して、以下の処理を行っています。

  • 頂点座標からスクリーン上の座標に変換する
  • ピクセルシェーダに渡す頂点情報を用意する
simple.fx 頂点シェーダ
VS_OUTPUT Basic_VS( float4 Pos : POSITION, float3 Normal : NORMAL, float2 Tex : TEXCOORD0)
{
    float4 Pos0 = Pos;

    // オブジェクトの座標をスクリーン上の座標へと変換する(ワールドビュー射影変換)
    Pos = mul( Pos, WorldViewMatrix );
    Pos = mul( Pos, ProjMatrix );

    // ピクセルシェーダでのライティング計算用。
    // カメラとの相対位置
    float3 Eye = CameraPosition - mul( Pos0, WorldMatrix );
    // 頂点法線
    Normal = normalize( mul( Normal, WorldMatrix ) );

    VS_OUTPUT Out = { Pos, Tex, Normal, Eye };
    return Out;
}

 コード中の変数Posが頂点シェーダの入力となる、オブジェクトの頂点座標です。

オブジェクト座標の改変

 では、MMD上でモデルを表示した状態で、simple.fxの頂点シェーダを以下のように更新してみましょう。

更新1
VS_OUTPUT Basic_VS( float4 Pos : POSITION, float3 Normal : NORMAL, float2 Tex : TEXCOORD0)
{
    Pos.xyz *= 2;    //この行を追加

    float4 Pos0 = Pos;

 すると以下のように、モデルのサイズが倍になります。これは、入力となるモデルの頂点座標のXYZを、それぞれ2倍する処理がシェーダに追加されたためです。

図7 XYZ座標を2倍
図7 XYZ座標を2倍

 次に以下のように編集してみます。

更新2
VS_OUTPUT Basic_VS( float4 Pos : POSITION, float3 Normal : NORMAL, float2 Tex : TEXCOORD0)
{
    Pos.x *= 0.3;    //この行を追加

    float4 Pos0 = Pos;

 すると、今度は以下のようにモデルの横幅だけが縮まります。これは頂点座標のX成分が0.3倍されるためです。

図8 X座標を0.3倍
図8 X座標を0.3倍

今度は、以下のように編集してみます。

更新3
VS_OUTPUT Basic_VS( float4 Pos : POSITION, float3 Normal : NORMAL, float2 Tex : TEXCOORD0)
{
    if ( Pos.x < 0 ) {    //この行を追加
        Pos.x = 0;        //同上
    }                     //同上

    float4 Pos0 = Pos;

 結果は以下のとおり、モデルの左半分が潰れてしまいます。シェーダの中で、頂点座標のX成分が0未満の場合、つまりその頂点が左半分に位置している場合に、元の値を無視してX成分が0に設定されるためです。

図9 左半分をX=0
図9 左半分をX=0

座標変換の改変

 以下のように編集してみましょう(Y,Zを編集しているのは、そのままではモデルが視界に入らないためです)。

更新4
    // オブジェクトの座標をスクリーン上の座標へと変換する(ワールドビュー射影変換)
    // Pos = mul( Pos, WorldViewMatrix );   //この行をコメントアウト
    Pos.y -= 10;                            //この行を追加
    Pos.z += 30;                            //この行を追加
    Pos = mul( Pos, ProjMatrix );

 すると以下のように、モデルが画面中央に描画され、右ドラッグで視界の向きを変更しても、画面中央に固定されたままになります。

 これは、オブジェクトの座標からスクリーン上の座標を計算する処理のうち、座標をカメラ視点に変換する処理(ビュー変換と呼ばれます)が、コードの編集によって無効になったためです。

図10 カメラ固定
図10 カメラ固定
補足3 データ型

 上記の頂点シェーダのコードで、頂点座標を表す変数Posの型は"float4"で、これは4次元ベクトルを表します。これには、3次元のX,Y,Z成分に加えて、頂点変換に使用するW成分が含まれています。各成分は、"Pos.x"のように記述することで参照できます。また、"Pos.xyz"と記述することで、3次元ベクトルのように扱うこともできます。

 "float4"を、色のデータ型(R,G,B,A)として扱うこともでき、"Color.r"や"Color.rgb"のように記述することで各成分を参照できます。

次のページ
最後に

修正履歴

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

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

もっと読む

この記事の著者

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

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

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

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

この記事をシェア

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

イベント

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

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

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

メールバックナンバー