私はこの問題で約4日間立ち往生しています。ジオメトリを 3 つのテクスチャ (アルベド、法線、深度) を持つ FBO (G バッファ) にレンダリングしようとしています。これまでのところ、MRT 機能を「ある程度」実装しましたが、gDEBugger を使用してテクスチャを検査すると、黒く表示されます。何を変更しても、黒一色になります。実際に出力される値は正しいです。MRT を無効にして、フラグメント シェーダーがバック バッファーに出力されるようにして確認しました。テクスチャは適切に初期化されており、gDEBugger は私が設定したパラメータを適切に表示します。しかし、それらはすべて黒一色 (0、0、0、255) で塗りつぶされています。
GLSL 3.30 の MRT に関する詳しい情報はほとんどありません。ここで回答された質問と、Web 上の OpenGL/GLSL ドキュメントとチュートリアルに完全に依存しています (古いですが、コードを更新しました)。Google でこの問題の解決策を探すのにおそらく 1 日を費やしたでしょう。コードの順序や構文に問題がある場合は、指摘してください。この実装が正しいかどうかさえわかりません...
Visual C++ 2010、OpenGL 3.30、および GLSL 3.30 を使用しています (タイトルに記載されているとおり)。私のライブラリでは、GLFW 3.0 がウィンドウ、入力、および OpenGL コンテキストに使用され、GLEW 1.10.0 が拡張機能に使用されています。
このコードはすべて、ラッパー クラスから取得したものであることに注意してください。コードの順序は、実行時にすべて実行される方法です (つまり、ラッパー クラスがなく、すべてのコードが main () にあるようなものです)。
初期化段階
// Initialize textures
glGenTextures (3, tex_ids);
glEnable (GL_TEXTURE_2D);
glBindTexture (GL_TEXTURE_2D, tex_ids[0]); // Diffuse
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB8, res.x, res.y, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glBindTexture (GL_TEXTURE_2D, tex_ids[1]); // Normal
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB8, res.x, res.y, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glBindTexture (GL_TEXTURE_2D, tex_ids[2]); // Depth
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D (GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, res.x, res.y, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glBindTexture (GL_TEXTURE_2D, 0);
glDisable (GL_TEXTURE_2D);
// Initialize FBO
glEnable (GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex_ids[0]);
glFramebufferTexture2D ( GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
tex_ids[0],
0 ); // diffuse
glBindTexture(GL_TEXTURE_2D, tex_ids[1]);
glFramebufferTexture2D ( GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT1,
GL_TEXTURE_2D,
tex_ids[1],
0 ); // normal
glBindTexture(GL_TEXTURE_2D, tex_ids[2]);
glFramebufferTexture2D ( GL_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_TEXTURE_2D,
tex_ids[2], 0 ); // depth
glBindFramebuffer (GL_FRAMEBUFFER, 0);
glDisable (GL_TEXTURE_2D);
// Initialize shaders
// Snipped out irrelevant code relating to getting shader source & compiling shaders
glBindFragDataLocation (renderer_1prog, GL_COLOR_ATTACHMENT0, "diffuse_out");
glBindFragDataLocation (renderer_1prog, GL_COLOR_ATTACHMENT1, "normal_out");
glBindFragDataLocation (renderer_1prog, GL_DEPTH_ATTACHMENT, "depth_out");
// More snipped out code relating to linking programs and finalizing
Draw Stage - すべてのフレームで呼び出されます
// Bind everything
glUseProgram (renderer_1prog);
glBindFramebuffer (GL_DRAW_FRAMEBUFFER, fbo_id);
GLenum targ [3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_DEPTH_ATTACHMENT };
glDrawBuffers (3, targ);
// Draw mesh
glEnable (GL_CULL_FACE);
glEnable (GL_DEPTH_TEST);
teshmesh.draw ();
// Unbind fbo
glDisable (GL_CULL_FACE);
glDisable (GL_DEPTH_TEST);
glBindFramebuffer (GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer (GL_DRAW_FRAMEBUFFER, 0);
頂点シェーダー
#version 330
layout(location = 0)in vec4 v;
layout(location = 1)in vec3 c;
layout(location = 2)in vec3 n;
out vec4 pos;
out vec3 col;
out vec3 nrm;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 world;
void main () {
gl_Position = projection * view * world * v;
pos = view * world * v;
pos.z = -pos.z / 500.0;
col = c.xyz;
nrm = n;
}
フラグメントシェーダー
#version 330
in vec3 col;
in vec3 nrm;
in vec4 pos;
layout(location = 0) out vec3 diffuse_out;
layout(location = 1) out vec3 normal_out;
layout(location = 2) out vec3 depth_out;
out vec3 o;
void main () {
diffuse_out = col;
normal_out = (nrm / 2.0) + 0.5;
depth_out = vec3 (pos.z, pos.z, pos.z);
}