Gregory Igehy

Dancing at hemisphere coordinate

Notes of Spherical Harmonics ( 球面調和関数のメモ)

注意点

  • SH 係数自体が, ラディアンスあるいはイラディアンスのどちらを示しているか? を意識すること

(a) SH の基底関数 ( l = 0, 1, 2 )

sh0_basis    : ( 1 / 2 ) * sqrt(  1 / PI )                     = 0.28209

sh1_-1_basis : ( 1 / 2 ) * sqrt(  3 / PI ) * y                 = 0.48860 * y
sh1_0_basis  : ( 1 / 2 ) * sqrt(  3 / PI ) * z                 = 0.48860 * z
sh1_1_basis  : ( 1 / 2 ) * sqrt(  3 / PI ) * x                 = 0.48860 * x

sh2_-2_basis : ( 1 / 2 ) * sqrt( 15 / PI ) * y * x             = 1.09254 * y * x
sh2_-1_basis : ( 1 / 2 ) * sqrt( 15 / PI ) * y * z             = 1.09254 * y * z
sh2_0_basis  : ( 1 / 4 ) * sqrt(  5 / PI ) * ( 3 * z^2 - 1.0 ) = 0.31534 * ( 3 * z^2 - 1.0 )
sh2_1_basis  : ( 1 / 2 ) * sqrt( 15 / PI ) * z * x             = 1.09254 * z * x
sh2_2_basis  : ( 1 / 4 ) * sqrt( 15 / PI ) * ( x^2 - y^2 )     = 1.09254 * ( x^2 - y^2 )

(b) 入力のラディアンスの SH 係数を, 入力のイラディアンスに変換する場合

  • 実用上は完全ランバートな反射を考慮して, ( 1 / PI )をさらに乗算しておく
irradiance_sh0   = radiance_sh0 * PI
irradiance_sh1_* = radiance_sh1_* ( 2 / 3 ) * PI
irradiance_sh2_* = radiance_sh2_* ( 1 / 4 ) * PI 

(c) ラディアンスの SH 係数を, ( イラディアンス / PI) として展開するための基底関数

  • この (c) は, (b) をせずに ( イラディアンス / PI )として展開するためのもの
  • 実際は この (c) をするよりも, (b) の後に (a) で展開する方がややこしくなくていい
irradiance_sh0_basis   = PI                 * ( 1 / PI ) * sh0_basis   = sh0_basis
irradiance_sh1_*_basis = ( ( 2 / 3 ) * PI ) * ( 1 / PI ) * sh1_*_basis = ( 2 / 3 ) * sh1_basis
irradiance_sh2_*_basis = ( ( 1 / 4 ) * PI ) * ( 1 / PI ) * sh2_*_basis = ( 1 / 4 ) * sh2_basis
  • 従って, (a) より以下のようになる
irradiance_sh0_basis    : ( 1 / 2 ) * sqrt(  1 / PI )                      = 0.28209

irradiance_sh1_-1_basis : sqrt(  1 / ( 3 * PI ) ) * y                      = 0.32574 * y
irradiance_sh1_0_basis  : sqrt(  1 / ( 3 * PI ) ) * z                      = 0.32574 * z
irradiance_sh1_1_basis  : sqrt(  1 / ( 3 * PI ) ) * x                      = 0.32574 * x

irradiance_sh2_-2_basis : ( 1 /  8 ) * sqrt( 15 / PI ) * y * x             = 0.27313 * y * x
irradiance_sh2_-1_basis : ( 1 /  8 ) * sqrt( 15 / PI ) * y * z             = 0.27313 * y * z
irradiance_sh2_0_basis  : ( 1 / 16 ) * sqrt(  5 / PI ) * ( 3 * z^2 - 1.0 ) = 0.07884 * ( 3 * z^2 - 1.0 )
irradiance_sh2_1_basis  : ( 1 /  8 ) * sqrt( 15 / PI ) * z * x             = 0.27313 * z * x
irradiance_sh2_2_basis  : ( 1 / 16 ) * sqrt( 15 / PI ) * ( x^2 - y^2 )     = 0.27313 * ( x^2 - y^2 )

(d) キューブマップ(color, normal)などを SH 係数に変換する場合

color = texture( CUBE_MAP, normal ) の場合

sh0   = sh0_basis * color

// 下で使われている (a) の sh1_*_basis と sh2_*_basis の (x,y,z) にはそれぞれ normal の値を入れる
sh1_* = sh1_*_basis * color
sh2_* = sh2_*_basis * color