キューブ マッピング テクニックを使用すると、奇妙な動作が発生します。すべてのピクセル シェーダーが黒色を返します。その結果、黒い画面が表示されました。
状況は次のとおりです。
シンプルなキューブ メッシュ (スカイボックス) とトラック ボール カメラだけで構成されたシーンがあります。
次に、リソース (6 つの個別のテクスチャの側面) を調べてみましょう。
画像の詳細は次のとおりです。
ご覧のとおり、これらのテクスチャは GL_RGB 形式でロードする必要があります。
ここで、初期化の部分として、クライアントの C++ テクスチャ ロード コードを見てみましょう (「DevIL」ライブラリを使用してイメージをロードします)。
glGenTextures(1, &this->m_Handle);
glBindTexture(this->m_Target, this->m_Handle);
{
glTexParameteri(this->m_Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(this->m_Target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(this->m_Target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(this->m_Target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(this->m_Target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
{
for (uint32_t idx = 0; idx < this->m_SourceFileList.size(); idx++)
{
ilLoadImage((const wchar_t*)this->m_SourceFileList[idx].c_str()); //IMAGE LOADING
{
uint32_t width = ilGetInteger(IL_IMAGE_WIDTH);
uint32_t height = ilGetInteger(IL_IMAGE_HEIGHT);
uint32_t bpp = ilGetInteger(IL_IMAGE_BPP);
{
char *pPixelData = (char*)ilGetData();
glTexImage2D(this->m_TargetList[idx], 0, GL_RGB8,
width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, pPixelData);
}
}
}
}
}
glBindTexture(this->m_Target, 0);
メイン ループ部分に関して、シェーダー プログラムに送信する情報 (テクスチャとマトリックス データ) は次のとおりです。
//TEXTURE DATA
scene::type::MaterialPtr pSkyBoxMaterial = pBatch->GetMaterial();
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_CUBE_MAP,
pSkyBoxMaterial->GetDiffuseTexture()->GetHandle());
this->SetUniform("CubeMapSampler", 1);
//MATRIX DATA
this->SetUniform("ModelViewProjMatrix", pBatch->GetModelViewProjMatrix());
キューブ マップ テクスチャがテクスチャ ユニット 1 にバインドされていることがわかります。
これが頂点シェーダーです。
#version 400
/*
** Vertex attributes.
*/
layout (location = 0) in vec3 VertexPosition;
/*
** Uniform matrix buffer.
*/
uniform mat4 ModelViewProjMatrix;
/*
** Outputs.
*/
out vec3 TexCoords;
/*
** Vertex shader entry point.
*/
void main(void)
{
TexCoords = VertexPosition;
gl_Position = ModelViewProjMatrix * vec4(VertexPosition, 1.0f);
}
そして最後にフラグメント シェーダー:
#version 400
/*
** Output color value.
*/
layout (location = 0) out vec4 FragColor;
/*
** Vertex inputs.
*/
in vec3 TexCoords;
/*
** Texture uniform.
*/
uniform samplerCube CubeMapSampler;
/*
** Fragment shader entry point.
*/
void main(void)
{
vec4 finalColor = texture(CubeMapSampler, TexCoords);
FragColor = finalColor;
}
したがって、コンパイルおよび実行されたすべてのプログラムは、次の結果を示します。
しかし、私は正確に NVIDIA NSight Debugger を使用しており、最初にキューブ マップが GPU に正しく読み込まれていることを示したいと思います。
上のコードに書かれているように、テクスチャはユニット テクスチャ 1 にバインドされた RGB テクスチャであり、GL_TEXTURE_CUBE_MAP テクスチャ タイプです。したがって、ここまではすべて正しいようです。
そして、フラグメントシェーダーで次の行を置き換えると:
vec4 finalColor = texture(CubeMapSampler, TexCoords);
行によって:
vec4 finalColor = vec4(TexCoords, 1.0f);
ワイヤーフレームなしで次の結果が得られます (モデル空間の頂点座標を色として直接レンダリングします)。
ワイヤーフレームでも同じ結果になります:
さらに、次の行を正確にしたい:
std::cout << glGetError() << std::endl;
常に「0」値を返すので、エラーはありません!
したがって、これらの最後の 2 つの写真は、マトリックス情報が正しく、頂点座標も正しいことを示していると思います (さらに、トラック ボール カメラを使用しており、シーン内を動き回るとキューブ アーキテクチャを認識できます)。したがって、シェーダー プログラムで復元したすべての情報は、キューブ サンプラーを除いて正しいものです。問題はこのサンプラーにあると思います。ただし、上で見たように、キューブ マップは正しく読み込まれているようです。
私はこの状況の前で本当に迷っています。すべてのピクセル シェーダーが #000000 色を返す理由がわかりません (RGBA 形式も使用してみましたが、結果は同じです)。