Created
December 3, 2019 14:11
-
-
Save LoadDragon0000000000/b075a6c14f23d6ed4bc31873c9113249 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ------------------------------------------------------------------------ | |
// 金属反射 | |
// ------------------------------------------------------------------------ | |
// ------------------------------------------------------------------------ | |
// グローバル変数 | |
// ------------------------------------------------------------------------ | |
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