スポンサーサイト

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

DXライブラリでハーフランバートシェーダ

こんにちは
そろそろ何ヶ月も放置体勢に入りそうなペチコです

重度の飽き性でめんどくさがりなのです
人間失格ですね。太宰です


頭の具合がよろしくないので今回も基本で遊びます
ハーフライフってゲームを作った会社が開発したハーフランバート反射というものです
ペチコはBF派なのでよく知りませんが有名だそうですファイアインザホー

通常のランバートで法線とライトのベクトルの内積を取っていた所を
2で割って0.5を足して二乗するだけの簡単なお仕事らしいです

頂点シェーダは前回のランバートと一緒なので省略

HalfLambert_PS.fx
// ピクセルシェーダーの入力
struct PS_INPUT
{
float2 Tex : TEXCOORD0 ; // テクスチャUV
float3 Norm : TEXCOORD1 ; // 法線(ビュー)
} ;

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

// マテリアルパラメータ
struct MATERIAL
{
float4 Diffuse ; // ディフューズカラー
float4 Specular ; // スペキュラカラー
float4 Power ; // スペキュラの強さ
} ;

// ライトパラメータ
struct LIGHT
{
float4 Position ; // 座標( ビュー空間 )
float3 Direction ; // 方向( ビュー空間 )
float4 Diffuse ; // ディフューズカラー
float4 Specular ; // スペキュラカラー
float4 Ambient ; // アンビエントカラーとマテリアルのアンビエントカラーを乗算したもの
float4 Range_FallOff_AT0_AT1 ; // x:有効距離 y:スポットライト用FallOff z:距離による減衰処理用パラメータ0 w:距離による減衰処理用パラメータ1
float4 AT2_SpotP0_SpotP1 ; // x:距離による減衰処理用パラメータ2 y:スポットライト用パラメータ0( cos( Phi / 2.0f ) ) z:スポットライト用パラメータ1( 1.0f / ( cos( Theta / 2.0f ) - cos( Phi / 2.0f ) ) )
} ;

// C++ 側で設定するテクスチャや定数の定義
sampler DiffuseMapTexture : register( s0 ) ; // ディフューズマップテクスチャ
float4 cfAmbient_Emissive : register( c1 ) ; // エミッシブカラー + マテリアルアンビエントカラー * グローバルアンビエントカラー
MATERIAL cfMaterial : register( c2 ) ; // マテリアルパラメータ
float4 cfFactorColor : register( c5 ) ; // 不透明度等
LIGHT cfLight : register( c32 ) ; // ライトパラメータ

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

//法線とライト方向の正規化
float3 N = normalize( PSInput.Norm );
float3 L = normalize( cfLight.Direction );

//ライトの強さ
float P = max(dot(N,-L),0)*0.5f+0.5f;
P*=P;

//色
float4 C = P * cfLight.Diffuse * cfMaterial.Diffuse + cfLight.Ambient + cfAmbient_Emissive;
//テクスチャ
float4 D = tex2D( DiffuseMapTexture, PSInput.Tex );

PSOutput.Color0.rgb = D * C.rgb;
PSOutput.Color0.a = cfMaterial.Diffuse.a * D.a * cfFactorColor.a ;

return PSOutput;
}

ピクセルシェーダも前回と9割方一緒で、//ライトの強さってトコだけ変わってます
dot(N,-L)内積を2で割って(*0.5)、0.5足したものを二乗(P*=P)しました

ハーフランバートハーフランバート

わかりやすいようにマテリアルの環境光を0にしてます
ランバートでは完全に陰になる部分(明るさ0)が真っ黒(環境光0)になりますが、ハーフだと明るい部分はそのままで陰だけやさしくなりました
これだとわかりにくいですが、ランバートではベタ塗りになる陰部分にもグラデーションがつきます


実際に使うかどうかはさておき、ちょっとした工夫で色々できるのでHLSLはおもしろいですね

ちなみにさっきから内積だの偉そうに解説していますが、ペチコは文系のため学校で習ってません
つまり、何のことだかさっぱりわかってないのです

あたまよくなりたい(手遅れ)



追記:
テキトー過ぎて行列の順序とか考えてなかったせいでモデルによっては描画が変になっちゃいますね

cppでモデル描画前に
MATRIX MatWorld = MV1GetLocalWorldMatrix(描画するモデルのハンドル);
MATRIX Camera_ViewMatrix = GetCameraViewMatrix() ;
MATRIX Camera_ProjectionMatrix = GetCameraProjectionMatrix() ;
SetVSConstFMtx(94,MatWorld);
SetVSConstFMtx(6,Camera_ViewMatrix);
SetVSConstFMtx(2,Camera_ProjectionMatrix);


頂点シェーダの行列変換部分を
VSOutput.Pos = mul(mul(mul(g_Proj, g_View), g_World), VSInput.Pos);
//法線
VSOutput.Norm = mul(mul(g_View, g_World), VSInput.Normal);

に追記および変更で正常になる、はずです。。行列とか全然分かってないです!(きっぱり)
大人しくライブラリ様の通りにしろってカンジですね

コメントの投稿

非公開コメント

プロフィール

ペチコートさん

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

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

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