スポンサーサイト

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

DXライブラリでハーフランバートにバンプマッピング

こんにちは、未だドライブに夢中のペチコです

TDU2 Jaguar D-Type

車に「ペチコート」ってペインティングしてるのですが、外国の方から見たら日本語で「割烹着」って書いてるようなものなんでしょうか


今回はハーフランバートにバンプマップを付けてみました
正直用途の分からないシェーダです。やってみたかっただけです
レースに優勝したからそのSSを上げたかったとかその辺はナイショです

頂点シェーダ
HLN_VS.fx
// 頂点シェーダーの入力
struct VS_INPUT
{
float4 Pos : POSITION ; // ローカル
float2 Tex : TEXCOORD0 ; // テクスチャUV
float3 Tan : TANGENT0;
float3 Bin : BINORMAL0;
float3 Normal : NORMAL0 ; // ローカル
} ;

// 頂点シェーダーの出力
struct VS_OUTPUT
{
float4 Pos : POSITION ; // 射影
float2 Tex : TEXCOORD0 ; // テクスチャUV
float3 VPos : TEXCOORD1 ; // 座標( ビュー空間 )
float3 VTan : TEXCOORD2 ; // 接線( ビュー空間 )
float3 VBin : TEXCOORD3 ; // 従法線( ビュー空間 )
float3 VNorm : TEXCOORD4 ; // 法線( ビュー空間 )
} ;

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

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

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

// ビューへ
float3 N = mul(VSInput.Normal,(float3x3)g_World);
N = normalize(mul(N,(float3x3)g_View));
float3 T = mul(VSInput.Tan,(float3x3)g_World);
T = normalize(mul(T,(float3x3)g_View));
float3 B = mul(VSInput.Bin,(float3x3)g_World);
B = normalize(mul(B,(float3x3)g_View));

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

VSOutput.VPos=viewPosition.xyz;
VSOutput.VTan=T;
VSOutput.VBin=B;
VSOutput.VNorm=N;

return VSOutput;
}


ビューポジションとビューに変換したNormal,Tangent,Binormalをピクセルシェーダに送ってます

ピクセルシェーダ
HLN_PS.fx
// ピクセルシェーダーの入力
struct PS_INPUT
{
float2 Tex : TEXCOORD0 ; // テクスチャUV
float3 VPos : TEXCOORD1 ; // 座標( ビュー空間 )
float3 VTan : TEXCOORD2 ; // 接線( ビュー空間 )
float3 VBin : TEXCOORD3 ; // 従法線( ビュー空間 )
float3 VNorm : TEXCOORD4 ; // 法線( ビュー空間 )
} ;

// ピクセルシェーダーの出力
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 ) ; // ディフューズマップテクスチャ
sampler NormalMapTexture : register( s1 ) ; // ノーマルマップテクスチャ

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;

float2 Tex=PSInput.Tex.xy;
/*
// 頂点座標から視点へのベクトルを接底空間に投影した後正規化して保存
float3 TempF3;
TempF3.x = dot( PSInput.VTan, -PSInput.VPos.xyz ) ;
TempF3.y = dot( PSInput.VBin, -PSInput.VPos.xyz ) ;
TempF3.z = dot( PSInput.VNorm, -PSInput.VPos.xyz ) ;
float3 V_to_Eye = normalize( TempF3 ) ;
// texをずらして視差を付ける
float H = tex2D( NormalMapTexture, Tex ).a;
Tex = Tex + 0.010 * H * V_to_Eye.xy;
*/
// バンプマッピング
float3 N = 2.0f*tex2D( NormalMapTexture, Tex ).xyz-1.0f;
N = PSInput.VNorm + N.x * PSInput.VTan + N.y * PSInput.VBin;
N = normalize(N);

// ハーフランバート
float P = max(dot(N,-cfLight.Direction),0)*0.5f+0.5f;
P*=P;

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

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

return PSOutput;
}

コメントアウト部分は視差マッピング
法線マップのアルファに高さ(ハイトマップ)が埋め込まれていれば視差マッピングになります

バンプマッピング部分
N = PSInput.VNorm + N.x * PSInput.VTan + N.y * PSInput.VBin;
これでバンプマップになるそうです。海外の掲示板?で見かけました。これ試したかっただけなのです
接線と従法線とか全然理解してないのでビュー空間でやっていいの?ってカンジですが一応表示できるからよしとします

あとはこれでできた法線でハーフランバートやってるだけです
バンプ視差

左がバンプマッピング、右が視差マッピングです

うん、ほんと用途が皆無な気がしますが、
ハーフランバートの柔らかい影でも凹凸を付けたいって日がやってくるかもしれません



でもきっとこない


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

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);
//N,T,Bもそれぞれこんなカンジにしないとダメかも
N = mul(mul(g_View, g_World), VSInput.Normal);


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

コメントの投稿

非公開コメント

プロフィール

ペチコートさん

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

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

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