About
- パストレーシングで GGX を使いたくなったので, いくつかの資料から GGX について復習
URL
- Optimizing GGX Shaders with dot(L,H) at Filmic Worlds
- Real Shading in Unreal Engine 4
- GGX shader for VRay
Note
- f : The general Cook-Torrance microfacet specular shading model (クックトランスのマイクロファセットのスペキュラシェーディングモデル)
- D : GGX Distribution ( GGX の NDF )
- F : Schlick-Fresnel (フレネルのシュリック近似 )
- V : Schlick approximation of Smith solved with GGX ( スミスのシュリック近似を GGX 向けに解いたもの )
- 以下は http://www.filmicworlds.com/images/ggx-opt/optimized-ggx.hlsl から引用したコードにコメントをつけたもの
// V を計算するための便利関数 float G1V( float dotNV, float k ) { return 1.0f / ( dotNV * ( 1.0f - k ) + k ); } // GGX を使ったスペキュラシェーディングの値を返す関数 float LightingFuncGGX_REF( float3 N, float3 V, float3 L, // ラフネス float roughness, // フレネル反射率 F(0°) float F0 ) { // α = ラフネス^2 float alpha = roughness * roughness; // ハーフベクトル float3 H = normalize(V+L); // ベクトルの内積関連 float dotNL = saturate( dot( N , L ) ); float dotNV = saturate( dot( N , V ) ); float dotNH = saturate( dot( N , H ) ); float dotLH = saturate( dot( L , H ) ); float F, D, vis; // D float alphaSqr = alpha * alpha; float pi = 3.14159f; float denom = dotNH * dotNH * ( alphaSqr - 1.0 ) + 1.0f; D = alphaSqr / ( pi * denom * denom ); // F float dotLH5 = pow( 1.0f - dotLH, 5 ); F = F0 + ( 1.0 - F0 ) * ( dotLH5 ); // V float k = alpha / 2.0f; vis = G1V( dotNL, k ) * G1V( dotNV, k); float specular = dotNL * D * F * vis; return specular; }