我试图用一个drawcall渲染到立方体贴图的所有6个面.GL立方体贴图附加到一个屏幕外的帧缓冲对象.我得到的结果只是面部数字零受到帧缓冲清晰颜色和片段的影响着色器输出.目标是使用被调用6次的几何着色器(每个面一次),然后将gl_InstanceID分配给内置的gl_Layer.Fragment着色器阶段将读取gl_Layer值并基于in来遮蔽栅格.它是预期的所有6面临的将涂上一个独特的颜色,取决于gl_Layer值.
为了让测试看到我得到正确的gl_layer值,我试图通过以下片段着色器将图层ID渲染到纹理的alpha通道中:
#version 430
// Ouput data
layout(location = 0) out vec4 color;
in int gl_Layer;
void main(){
color = vec4(0.5,0.5,0.5,float(gl_Layer)/255.0);
}
Run Code Online (Sandbox Code Playgroud)
顶点着色器基本上什么都不做:
#version 430
in vec3 position;
void main(){
gl_Position = vec4(position, 1.0);
}
Run Code Online (Sandbox Code Playgroud)
并且几何着色器执行6次,渲染单位正方形(覆盖整个视口)并根据gl_InvocationID设置gl_Layer:
#version 430
layout(triangles, invocations = 6) in;
layout(triangle_strip, max_vertices = 4) out;
out int gl_Layer;
void main()
{
const vec2 vert_data[4] = vec2[]( vec2(-1.0, 1.0), vec2(-1.0, -1.0), vec2(1.0, 1.0), vec2(1.0, -1.0) );
for(int i=0; i<4; i++)
{
gl_Layer = gl_InvocationID;
gl_Position = vec4(vert_data[i].xy,0,1);
EmitVertex();
}
EndPrimitive();
}
Run Code Online (Sandbox Code Playgroud)
最后,这是我设置纹理和帧缓冲的方式:
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &fbtextures_count);
// how many textures to create? depends on complexity of your effects.
glActiveTexture(GL_TEXTURE0);
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glGenTextures(1, &fbcubetexture);
GLenum target = GL_TEXTURE_CUBE_MAP;
// initializing color maps
glBindTexture(target, fbcubetexture);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
initData(255,255, 255);
for (int i = 0; i < 6; i++)
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA8, cube_s, cube_s, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
}
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, fbcubetexture, 0);
GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, drawBuffers);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Run Code Online (Sandbox Code Playgroud)
我正在阅读客户端上的面部颜色:
for (int i = 0; i < 6; i++)
{
glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA,GL_UNSIGNED_BYTE, data);
}
Run Code Online (Sandbox Code Playgroud)
我得到的GL_TEXTURE_CUBE_MAP_POSITIVE_X的结果是正确的.但是剩下的脸部保留了相同的第一个初始化值.我还使用NVIDIA NSIGHT进行了调试,其中只看到一个面部绘制了整个立方体贴图纹理.
我阅读了几个示例,这些示例展示了如何通过几何着色器使用gl_Layer id进行多目标渲染,但所有这些都以不同方式执行.
例如,不清楚将立方体贴图纹理附加到FBO的单个渲染目标是否足够,或者每个面必须附加到不同的渲染目标?
应该glFramebufferTexture被用来绑定附件或glFramebufferTexture2D?
当立方体贴图附加到帧缓冲区时,glClearColor应该将所有面清除为某种颜色还是只清除第一种颜色?
我在这里想念什么?任何人都能以正确的方式展示如何做到这一点?
系统规格:
GPU:NVIDIA GeForce 960 GTX Windows7 64位MSVC120
我无法证明这就是问题所在。但这肯定是一个问题:
for(int i=0; i<4; i++)
Run Code Online (Sandbox Code Playgroud)
你说你的 GS 作为triangles输入。好吧,它们只有3 个顶点,而不是 4 个。所以你的三角形带中会有一个坏顶点。
当循环 GS 中的项目时,这样做总是更安全:
for(int i = 0; i < gl_in.length(); i++)
Run Code Online (Sandbox Code Playgroud)
这样,如果您更改输入基元类型,您的长度会自动更新。