シェーダで実装 キューブマッピング

shadercubemap.png

シェーダを使わなくても簡単に出来るのになぜやるのか?
後に屈折などシェーダでしか実装できないようなことをやるための基礎を把握するためです。
まずはフラグメントシェーダからみていきましょう。

フラグメントシェーダ

お便利な組み込み関数があります。textureCubeです。
これは

glBindTexture(GL_TEXTURE_CUBE_MAP, mTexId);
glTexImage2D ( GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB, img.Width,img.Height, 0, GL_RGB, GL_UNSIGNED_BYTE, img.Data);
glTexImage2D ( GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB, img.Width,img.Height, 0, GL_RGB, GL_UNSIGNED_BYTE, img.Data);
glTexImage2D ( GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB, img.Width,img.Height, 0, GL_RGB, GL_UNSIGNED_BYTE, img.Data);
glTexImage2D ( GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB, img.Width,img.Height, 0, GL_RGB, GL_UNSIGNED_BYTE, img.Data);
glTexImage2D ( GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB, img.Width,img.Height, 0, GL_RGB, GL_UNSIGNED_BYTE, img.Data);
glTexImage2D ( GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB, img.Width,img.Height, 0, GL_RGB, GL_UNSIGNED_BYTE, img.Data);

で渡したようなテクスチャを参照します。
使い方はこうです
色=textureCube(samplerCube,反射ベクトル);

テクスチャのuvwを渡すべきところには反射ベクトルを渡します。
uniform samplerCube cubemap;
varying vec3 reflectDir;  // 視線の反射ベクトル
void main(void)
{
 gl_FragColor=textureCube(cubemap, reflectDir);
}

textureCube関数の注意

シェーダバージョン(少なくとも)#420でtextureCube関数を使おうとすると次のようなエラーになります

error C7531: global function textureCube requires "#extension GL_NV_shadow_samplers_cube : enable" before use

RedBookのサンプルによると、texture関数のほうを使うのがおすすめのようです。

頂点シェーダ

varying vec3 reflectDir;  // 視線の反射ベクトル
void main(void)
{
  gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;
  vec3 normal =normalize(gl_NormalMatrix*gl_Normal);     // 法線ベクトル
  vec3 eyeDir =gl_Position.xyz;// 視線ベクトル
 
  reflectDir =reflect(eyeDir,normal);// 視線の反射ベクトル
 
}

reflect関数の中身

reflect関数の中身はこうなっている

reflectDir =reflect(eyeDir,normal);// 視線の反射ベクトル だったら
reflectDir=eyeDir-2.0*dot(normal,eyeDir)*normal;//と同じ

内積のページによると、視線と法線の内積はポリゴンの表裏判定にも使用される。

shader

サポートサイト Wikidot.com shader