Programming of Spherical Harmonics Lighting (1)
This time I have decoded the SH lighting parameters of Grace Cathedral by GLSL fragment shader, mapped the upper and lower hemisphere to the disk.
今回は Grace Cathedral の SH のパラメータをデコードしたものについて, 上半球と下半球をそれぞれ円盤に対してマッピングしてみました.
Some part of upper hemisphere seems quite bright.
上半球のライティングが部分的に結構まぶしい感じです.
Decoding the Grace Cathedral SH lighting parameters ( upper hemisphere ).
Decoding the Grace Cathedral SH lighting parameters ( lower hemisphere ).
I have pasted part of my source code below.
下に今回, 僕が書いたソースコードの一部を貼り付けました.
////////////////////////////////////////////////// // GLSL fragment shader to decode SH lighting // ( l_max = 2, 9 coefficients ) // hanecci // ////////////////////////////////////////////////// varying vec3 v_normal; const int SH_NUM = 9; uniform vec3 sh_light_array[ SH_NUM ]; float computeSH( const vec4 normal4, const int colorIndex ) { const float SH_C1 = 0.429043; const float SH_C2 = 0.511664; const float SH_C3 = 0.743125; const float SH_C4 = 0.886227; const float SH_C5 = 0.247708; const int SH_L_0_0 = 0; const int SH_L_1_M1 = 1; const int SH_L_1_0 = 2; const int SH_L_1_1 = 3; const int SH_L_2_M2 = 4; const int SH_L_2_M1 = 5; const int SH_L_2_0 = 6; const int SH_L_2_1 = 7; const int SH_L_2_2 = 8; mat4 m44 = mat4( SH_C1 * sh_light_array[ SH_L_2_2 ][ colorIndex ], SH_C1 * sh_light_array[ SH_L_2_M2 ][ colorIndex ], SH_C1 * sh_light_array[ SH_L_2_1 ][ colorIndex ], SH_C2 * sh_light_array[ SH_L_1_1 ][ colorIndex ], // SH_C1 * sh_light_array[ SH_L_2_M2 ][ colorIndex ], - SH_C1 * sh_light_array[ SH_L_2_2 ][ colorIndex ], SH_C1 * sh_light_array[ SH_L_2_M1 ][ colorIndex ], SH_C2 * sh_light_array[ SH_L_1_M1 ][ colorIndex ], // SH_C1 * sh_light_array[ SH_L_2_1 ][ colorIndex ], SH_C1 * sh_light_array[ SH_L_2_M1 ][ colorIndex ], SH_C3 * sh_light_array[ SH_L_2_0 ][ colorIndex ], SH_C2 * sh_light_array[ SH_L_1_0 ][ colorIndex ], // SH_C2 * sh_light_array[ SH_L_1_1 ][ colorIndex ], SH_C2 * sh_light_array[ SH_L_1_M1 ][ colorIndex ], SH_C2 * sh_light_array[ SH_L_1_0 ][ colorIndex ], SH_C4 * sh_light_array[ SH_L_0_0 ][ colorIndex ] - SH_C5 * sh_light_array[ SH_L_2_0 ][ colorIndex ] ); vec4 tmpNormal4 = m44 * normal4; return dot( normal4, tmpNormal4 ); } void main (void) { const int redColorIndex = 0; const int greenColorIndex = 1; const int blueColorIndex = 2; vec3 normal = normalize( v_normal ); vec4 normal4 = vec4( normal, 1.0 ); float red = computeSH( normal4, redColorIndex ); float green = computeSH( normal4, greenColorIndex ); float blue = computeSH( normal4, blueColorIndex ); gl_FragColor = vec4( red, green, blue, 1.0 ); }
////////////////////////////////////////////////// // // Setting SH parameters of Grace Cathedral as GLSL uniform // ( l_max = 2, 9 coefficients ) // hanecci // ////////////////////////////////////////////////// const int SH_NUM = 9; const int RGB_NUM = 3; const int SH_ARRAY_NUM = SH_NUM * RGB_NUM; float g_sh_light_array[ SH_ARRAY_NUM ]; GLint g_sh_light_array_location = -1; void initSHLightArray() { const int SH_L_0_0 = 0; const int SH_L_1_M1 = 1; const int SH_L_1_0 = 2; const int SH_L_1_1 = 3; const int SH_L_2_M2 = 4; const int SH_L_2_M1 = 5; const int SH_L_2_0 = 6; const int SH_L_2_1 = 7; const int SH_L_2_2 = 8; // SH parameters of Grace cathedral // L 0 0 ( rgb ) g_sh_light_array[ 3 * SH_L_0_0 + 0 ] = 0.79f; g_sh_light_array[ 3 * SH_L_0_0 + 1 ] = 0.44f; g_sh_light_array[ 3 * SH_L_0_0 + 2 ] = 0.54f; // L 1 -1 g_sh_light_array[ 3 * SH_L_1_M1 + 0 ] = 0.39f; g_sh_light_array[ 3 * SH_L_1_M1 + 1 ] = 0.35f; g_sh_light_array[ 3 * SH_L_1_M1 + 2 ] = 0.60f; // L 1 0 g_sh_light_array[ 3 * SH_L_1_0 + 0 ] = -0.34f; g_sh_light_array[ 3 * SH_L_1_0 + 1 ] = -0.18f; g_sh_light_array[ 3 * SH_L_1_0 + 2 ] = -0.27f; // L 1 1 g_sh_light_array[ 3 * SH_L_1_1 + 0 ] = -0.29f; g_sh_light_array[ 3 * SH_L_1_1 + 1 ] = -0.06f; g_sh_light_array[ 3 * SH_L_1_1 + 2 ] = 0.01f; // L 2 -2 g_sh_light_array[ 3 * SH_L_2_M2 + 0 ] = -0.11f; g_sh_light_array[ 3 * SH_L_2_M2 + 1 ] = -0.05f; g_sh_light_array[ 3 * SH_L_2_M2 + 2 ] = 0.12f; // L 2 -1 g_sh_light_array[ 3 * SH_L_2_M1 + 0 ] = -0.26f; g_sh_light_array[ 3 * SH_L_2_M1 + 1 ] = -0.22f; g_sh_light_array[ 3 * SH_L_2_M1 + 2 ] = -0.47f; // L 2 0 g_sh_light_array[ 3 * SH_L_2_0 + 0 ] = -0.16f; g_sh_light_array[ 3 * SH_L_2_0 + 1 ] = -0.09f; g_sh_light_array[ 3 * SH_L_2_0 + 2 ] = -0.15f; // L 2 1 g_sh_light_array[ 3 * SH_L_2_1 + 0 ] = 0.56f; g_sh_light_array[ 3 * SH_L_2_1 + 1 ] = 0.21f; g_sh_light_array[ 3 * SH_L_2_1 + 2 ] = 0.14f; // L 2 2 g_sh_light_array[ 3 * SH_L_2_2 + 0 ] = 0.21f; g_sh_light_array[ 3 * SH_L_2_2 + 1 ] = -0.05f; g_sh_light_array[ 3 * SH_L_2_2 + 2 ] = -0.30f; g_sh_light_array_location = glGetUniformLocation( g_ProgramId, "sh_light_array" ); } void setSHUniform() { glUniform3fv( g_sh_light_array_location, SH_NUM, g_sh_light_array ); }