スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

DXライブラリでグラスシェーダー

こんにちは、相変わらずHLSLばかりいじってるペチコです。
興味ない方が大半なのに趣味に突っ走ってます。

ブログ分けるのめんどくさいんだもん。


今回はグラスシェーダー作ってみました。
ガラス(glass)ではなく草の(grass)です。ますます海から離れていきます。

一昔前の3Dゲームでは常にこっちを向く一枚の板(ビルボード)で草や木々を表現していましたが
折角シェーダーを使のですから、もう少し良い表現にしてみたいと思います。

地面に生える草をポリゴンで作る場合、板を交差するクロス法が一般的ですが今回は井の字型で成形。

井の字型
一般的な十字型に比べて板がふえますがその分見映えが段違いとの噂です。


草テクスチャ
そこに貼り付ける草テクスチャと透過テクスチャ。メッシュは両面にしてます。
毎度テキトーに描いてアルファ抜きに失敗しています。エッジが残るぅ。

ちなみにアルファ付きテクスチャを使う場合はアルファテストしとかないといけません。
DXライブラリでは下の一文をモデル描画前に付け足します。

SetDrawAlphaTest( DX_CMP_GREATER, 128 ) ;


数字の部分が「アルファ値がそれ以上の場合に描画する」です。
今回のように抜き失敗しても数字を上げることである程度の対処ができますが、通常は128(0.5)で十分だと思います。

あと使わない時は
SetDrawAlphaTest( -1, 0 ) ;


でデフォルト設定にしておかないとその他のところで不具合出るかもしれません。

シーンでアルファを使う時はバックカリングやらZソートやら考えないといけませんが今回は無視です。


この草ポリゴンを頂点シェーダにて左右に揺らしてやればそれらしく見えるかも?と考えたのが本題。




ただのサイン波で揺らしてるだけの最も簡単な実装ですが、視点が遠いなら意外と良いカンジです。
コードもとっても簡単でコストパフォーマンス高いかも。

GrassVS.fx

// 頂点シェーダーの入力
struct VS_INPUT
{
float4 Pos : POSITION ; // ローカル
float2 Tex : TEXCOORD0 ; // テクスチャ座標
} ;

// 頂点シェーダーの出力
struct VS_OUTPUT
{
float4 Pos : POSITION ; // 射影
float2 Tex : TEXCOORD0 ; // テクスチャ座標
} ;

// C++ 側で設定する定数の定義
float4x4 g_World : register( c94 ) ; // ローカル→ワールド
float4x4 g_View : register( c6 ) ; // ワールド→ビュー
float4x4 g_Proj : register( c2 ) ; // ビュー→射影
float4 g_fTime : register( c0 ) ;

// main関数
VS_OUTPUT main( VS_INPUT VSInput )
{
VS_OUTPUT VSOutput;

float g_Time = g_fTime.x ;

float4 Pos = VSInput.Pos;

float shift = sin(g_Time) * Pos.y * 0.3 ;
Pos.x += shift;
Pos.z += shift;

//ローカル→ワールド→ビュー→射影変換
VSOutput.Pos = mul(mul(mul(Pos, g_World), g_View), g_Proj);

// テクスチャ
VSOutput.Tex = VSInput.Tex;

return VSOutput;
}


GrassPS.fx

// ピクセルシェーダーの入力
struct PS_INPUT
{
float2 Tex : TEXCOORD0 ; // テクスチャ
} ;

// ピクセルシェーダーの出力
struct PS_OUTPUT
{
float4 Color0 : COLOR0 ;
} ;


// C++ 側で設定するテクスチャや定数の定義
sampler DiffuseMapTexture : register( s0 ) ; // ディフューズマップテクスチャ

// main関数
PS_OUTPUT main( PS_INPUT PSInput )
{
PS_OUTPUT PSOutput;

float4 TextureDiffuseColor = tex2D( DiffuseMapTexture, PSInput.Tex ) ;

PSOutput.Color0 = TextureDiffuseColor ;

return PSOutput;
}

毎回インデントがずれてますが、面倒なので直しません。
ペチコ座右の銘は「杜撰」です。

ライティングを省いてるのでコードが短いのもありますが、簡単なことしかやってないところにペチコの頭の限界が見えますね。

	float shift = sin(g_Time) * Pos.y * 0.3 ;
Pos.x += shift;
Pos.z += shift;


草を揺らす計算部分はこれだけ。
g_Timeについてはアプリを起動してからの時間(ミリ秒)を定数レジスタで受け取っています。
その辺はオーシャンシェーダで。
地面を支点に揺れるのでメタセコでメッシュ作成時にY軸:0に下面を合わせてます。


横の動きしか考えてないのでびよーんと伸びる感じです。
Y軸も取り入れたり風の向きや強さ速さも適用できるようにするともっと良くなるのかもしれません。



40x40の1600個並べてみました。ついでに前回のティ力(てぃちから)ちゃんも。
規則正しく密集してますが、もうちょっとランダムに並べると表現力がアップしそうです。

しかし目標はコグを海に浮かべることで使い道がないなあ。


ひらめいた。


これを使って海底にワカメ生やせばいいじゃないですか。見えない

コメントの投稿

非公開コメント

プロフィール

ペチコートさん

Author:ペチコートさん
大航海時代オンライン
Zephyros、Eurosサーバーに潜伏中

偽ペチコ1号・2号
ペチコの手下達
Zephyrosサーバーに潜伏中

最新記事
月別アーカイブ
カテゴリ
リンク
最新コメント
検索フォーム
QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。