Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save LoadDragon0000000000/b075a6c14f23d6ed4bc31873c9113249 to your computer and use it in GitHub Desktop.
Save LoadDragon0000000000/b075a6c14f23d6ed4bc31873c9113249 to your computer and use it in GitHub Desktop.
// ------------------------------------------------------------------------
// 金属反射
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// グローバル変数
// ------------------------------------------------------------------------
float4x4 mWVP; // ローカル→射影まで変換する
float4 vLightDir; // ライトの方向
float4 vColor; // ライト*メッシュの色
float3 vEyePos; // カメラの位置(ローカル座標系)
// ------------------------------------------------------------------------
// 出力構造体
// ------------------------------------------------------------------------
struct VS_OUTPUT {
float4 Pos : POSITION;
float4 Color : COLOR0;
float3 N : TEXCOORD0;
float3 X : TEXCOORD1;
};
// ------------------------------------------------------------------------
// 頂点シェーダ
// ------------------------------------------------------------------------
VS_OUTPUT VS(float4 Pos : POSITION, float4 Normal : NORMAL) {
VS_OUTPUT Out = (VS_OUTPUT)0; // 出力データのクリア
Out.Pos = mul(Pos, mWVP); // ローカル→射影へ変換
// 拡散光 + 環境光
float4 L = -vLightDir; // ライトベクトル(ローカル)
float amb = -L.w; // 環境光の強さ
Out.Color = vColor * max(amb, dot(Normal, L));
// 鏡面反射用のベクトルをピクセルシェーダへ渡す
Out.N = Normal.xyz; // ローカルでの法線
Out.X = Pos.xyz; // ローカルでの座標
return Out;
}
// ------------------------------------------------------------------------
// ピクセルシェーダ
// ------------------------------------------------------------------------
float4 PS(VS_OUTPUT In) : COLOR{
// ベクトル達(ローカル)
float3 L = -vLightDir.xyz; // ライトベクトル
float3 N = normalize(In.N); // 法線ベクトル(PSへ渡す際に線形補間されるので再度正規化)
float3 V = normalize(vEyePos - In.X); // 視線ベクトル
float3 H = normalize(L + V); // ライトベクトルと視線ベクトルのハーフベクトル
// 計算に使うそれぞれの内積
float NV = dot(N, V);
float NH = dot(N, H);
float VH = dot(V, H);
float NL = dot(N, L);
float LH = dot(L, H);
// Beckmann分布関数D
const float m = 0.350f; // 粗さ(小さいほど鏡に近づく)
float NH2 = NH * NH;
float DB = 4 * m * m * NH2 * NH2; // 基底部
float DE = exp(-(1 - NH2) / (NH2 * m * m)); // 指数部 exp() = pow(e, n)
float D = (DE / DB); // (1 / DB) * DE
// 幾何減衰率G
float G = min(1, min(2 * NH * NV / VH, 2 * NH * NL / VH));
// フレネル項F
float n = 20.0f; // 複素屈折率の実部(遊び)
float g = sqrt(n * n + LH * LH - 1);
float gpc = g + LH;
float gnc = g - LH;
float cgpc = LH * gpc - 1;
float cgnc = LH * gnc + 1;
float F = 0.50f * pow(gnc / gpc, 2) * (1 + pow(cgpc / cgnc, 2));
// 金属の色
float4 ks = { 2.0f * 0.4860f, 2.0f * 0.4330f, 2.0f * 0.1850f, 1.0f };
// 拡散+環境 鏡面反射光
return In.Color + ks * max(0, F * D * G / NV);
}
// -------------------------------------------------------------
// テクニック
// -------------------------------------------------------------
technique TShader
{
pass P0
{
VertexShader = compile vs_2_0 VS();
PixelShader = compile ps_2_0 PS();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment