使用几何着色器

时间:2015-10-15 18:50:27

标签: opengl glsl

我试图用一个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);
}

顶点着色器基本上什么都不做:

#version 430  

in vec3 position;


void main(){
     gl_Position = vec4(position, 1.0);
}

并且几何着色器执行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();
}

最后,这就是我设置纹理和帧缓冲的方法:

    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); 

我正在阅读客户端上的面部颜色:

 for (int i = 0; i < 6; i++)
 { 
    glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA,GL_UNSIGNED_BYTE, data); 
 }

我为GL_TEXTURE_CUBE_MAP_POSITIVE_X获得的结果是正确的。但是剩下的脸部保留了相同的第一个初始化值。我还使用NVIDIA NSIGHT进行了调试,其中只看到一个脸部的整个立方体贴图纹理。

我阅读了数十个示例,这些示例展示了如何通过几何着色器将gl_Layer id用于多目标渲染,但所有这些都以不同的方式执行。

例如,目前尚不清楚将立方体贴图纹理附加到FBO的单个渲染目标是否足够,或者每个面必须附加到不同的渲染目标?

glFramebufferTexture 是否应该用于绑定附件或 glFramebufferTexture2D

当立方体贴图附加到帧缓冲区时,glClearColor应该将所有面部清除为某种颜色还是只清除第一种颜色?

我在这里想念什么?任何人都可以以正确的方式展示如何做到这一点?

系统规格:

GPU:NVIDIA GeForce 960 GTX Windows7 64bit MSVC120

1 个答案:

答案 0 :(得分:2)

我不能证明这是问题所在。但这肯定是一个问题:

for(int i=0; i<4; i++)

你说你的GS需要triangles作为输入。好吧,那些只有三个顶点,而不是4.所以你的三角形条带中会有一个坏顶点。

当循环GS中的项目时,执行此操作总是更安全:

for(int i = 0; i < gl_in.length(); i++)

这样,如果更改输入基元类型,则会自动更新长度。