CodeZine(コードジン)

特集ページ一覧

3DCGツール「MikuMikuDance」のエフェクトを拡張する「MikuMikuEffect」
専用モデルを利用したエフェクト

MikuMikuEffectで学ぶHLSL入門(6)

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2012/11/12 14:00
目次

ピクセルシェーダの処理

 後は表示されているラインにテクスチャを貼り付ければ完成です。

 このエフェクトのピクセルシェーダは、テクスチャの色を取得、出力しているだけの極めてシンプルな構造です。

// ピクセルシェーダ
float4 Line_PS( VS_OUTPUT IN ) : COLOR0
{
    //出力用カラー
    float4 Color;
   
    Color = tex2D(LineTexSampler,IN.Tex); //修正
   
    return Color;
}
使用テクスチャ
使用テクスチャ

 このようなテクスチャをモデルのUV値に合わせて張る処理だけを行っています。

完成!
完成!

エフェクトの改造

 ラインエフェクトは以上で完成です。しかし、若干面白みにかけるのでここからさらに改造を加えていきます。

エルミート曲線の実装

曲がります
曲がります

 エルミート曲線という計算式を用いて、ラインを曲げる処理を付け加えます。

//エルミート補完関数
float3 HermiteLerp(float3 s,float3 e,float3 svec,float3 evec,float t)
{
    return (((t-1)*(t-1))*(2*t+1)*s) + ((t*t)*(3-2*t)*e) +((1-(t*t))*t*svec) + ((t-1)*(t*t)*evec);
}

 このような関数がコード内48行目付近にあるはずです。

 ゲームなどでも利用される比較的高速な計算で、内容としては、始点、終点に"勢い"を与え、それに合わせて曲線を描く計算式です。

 これを利用したコードは以下のようになります。

// 頂点シェーダ
VS_OUTPUT Line_VS(float4 Pos : POSITION, float2 Tex : TEXCOORD0)
{
    VS_OUTPUT Out = (VS_OUTPUT)0;
   
    //ターゲット用座標
    float3 TargetPos = TargetPos2;

    //---追加---//

    //エルミート曲線用始点ベクトル
    float3 StartVec = float3(0,100,0);
    //エルミート曲線用終点ベクトル
    float3 EndVec = float3(0,300,0);
   
    //----------//
   
    //出力用座標
    float4 LastPos = 1;
    //---現在の座標取得---//
    //ワールド行列の4行目からワールド座標を取得
    float3 ZeroPos = WorldMatrix[3].xyz;
   
    //原点と目標点の間を線形補間で座標を取得
    //補間用係数はモデルのZ座標
    //修正
    //float3 NowPos = lerp(ZeroPos,TargetPos,Pos.z);
    float3 NowPos = HermiteLerp(ZeroPos,TargetPos,StartVec,EndVec,Pos.z);
   
    //出力用座標に保存
    LastPos.xyz = NowPos;
   
    //---ビルボード計算---//

    //現在座標から少しだけ先に進めた座標を取得
    //修正
    //float3 NextPos = lerp(ZeroPos,TargetPos,Pos.z+0.01);
    float3 NextPos = HermiteLerp(ZeroPos,TargetPos,StartVec,EndVec,Pos.z+0.01);
   
    //カメラへの視線ベクトルを計算する
    float3 EyeVec = normalize(NowPos - CameraPosition);
   
    //現在の座標と先の座標から正面方向のベクトルを得る
    float3 FrontVec = normalize(NextPos - NowPos);
   
    //正面ベクトルと視線ベクトルの外積からサイドベクトルを得る
    float3 SideVec = normalize(cross(EyeVec,FrontVec))*3;
   
    //現在処理している頂点を左右に割り振る
    //すべての頂点のX座標は0.5もしくは-0.5
    if(Pos.x > 0)
    {
        LastPos.xyz += SideVec;
    }else{
        LastPos.xyz -= SideVec;
    }
   
   
    // カメラ視点ビュー射影変換
    Out.Pos = mul( LastPos, ViewProjMatrix );
   
    // テクスチャ座標
    Out.Tex = Tex;
   
    return Out;
}

 座標を取得する部分を書き換えてあります。

 基本的にlerp関数と同じような使い方で、引数に始点、終点の勢いベクトルが代入されています。

 始点終点ベクトルのパラメータをいろいろ書き換えて挙動を確認してみてください。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

修正履歴

  • 2012/11/13 10:49 Lerp関数の利用 画像のurlを修正

  • 2012/10/18 02:31 記事完成

  • 2012/10/15 23:44 アドバイスに従い間違い修正および文章、画像追加

バックナンバー

連載:MikuMikuEffectで学ぶHLSL入門

著者プロフィール

  • ビームマンP(ビームマンピー)

    ニコニコ動画等でMikuMikuEffect用シェーダプログラム開発者として活動。 開発を始めた理由はカッコいいビームやミサイルが作りたかった為。 エフェクト配布用サイト http://www43.atwiki.jp/beamman/

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5