在单次传递中绘制立方体贴图 OpenGL

Draw a cubemap in a single pass OpenGL

提问人:zeb 提问时间:6/9/2016 最后编辑:zeb 更新时间:6/9/2016 访问量:1501

问:

我正在尝试使用 OpenGL 中的几何阴影在单次传递中绘制到立方体贴图。 基本上需要我这样做才能将立方体贴图的内容复制到另一个立方体贴图中,并且可能没有相同的分辨率和像素布局。

我正在尝试实现我想要的结果,将单个点馈送到顶点着色器,然后从几何着色器中选择每个图层(立方体贴图的面)并发出四边形和纹理坐标。

到目前为止,我已经尝试了这种方法,只发出两个立方体贴图面(正 X 和负 X),看看它是否有效,但它不起作用。

使用 NSight,我可以看到有问题。

这是源立方体贴图:enter image description here

这是结果立方体贴图:enter image description here

唯一被吸引的面孔是正X,但它仍然不正确。

这是我的几何着色器:

#version 330 core

layout(points) in;
layout(triangle_strip, max_vertices = 8) out;

in vec3 pos[];
out vec3 frag_textureCoord;

void main()
{
    const vec4 positions[4] = vec4[4] ( vec4(-1.0, -1.0, 0.0, 0.0),
                                        vec4( 1.0, -1.0, 0.0, 0.0),
                                        vec4(-1.0,  1.0, 0.0, 0.0),
                                        vec4( 1.0,  1.0, 0.0, 0.0) );

    // Positive X
    gl_Layer = 0;

    gl_Position = positions[0];
    frag_textureCoord = vec3(1.0, -1.0, -1.0);
    EmitVertex();

    gl_Position = positions[1];
    frag_textureCoord = vec3(1.0, -1.0,  1.0);
    EmitVertex();

    gl_Position = positions[2];
    frag_textureCoord = vec3(1.0,  1.0, -1.0);
    EmitVertex();

    gl_Position = positions[3];
    frag_textureCoord = vec3(1.0,  1.0,  1.0);
    EmitVertex();                    
    EndPrimitive();

    // Negative X
    gl_Layer = 1;

    gl_Position = positions[0];
    frag_textureCoord = vec3(-1.0, -1.0,  1.0);
    EmitVertex();

    gl_Position = positions[1];
    frag_textureCoord = vec3(-1.0, -1.0, -1.0);
    EmitVertex();

    gl_Position = positions[2];
    frag_textureCoord = vec3(-1.0,  1.0,  1.0);
    EmitVertex();

    gl_Position = positions[3];
    frag_textureCoord = vec3(-1.0,  1.0, -1.0);
    EmitVertex();                    
    EndPrimitive();
}

这是我的片段着色器:

#version 150 core

uniform samplerCube AtmosphereMap;

in vec3 frag_textureCoord;

out vec4 FragColor;

void main()
{
    FragColor = texture(AtmosphereMap, frag_textureCoord) * 1.0f;
}

更新 使用 NSight 进行进一步调试表明,对于正 x 面,每个片段的值都为 of(我已经使用了,因为这些值不完全是这些值,而是近似值)。相反,负 x 面永远不会到达片段着色器阶段。frag_textureCoordvec3(~1.0, ~0.0, ~0.0)~


更新 将顶点位置的定义从 更改为 使我的着色器正确渲染正面 X 面,但负面仍然是错误的,即使调试片段着色器,我看到选择并应用了正确的颜色,但随后它变成了黑色。vec4(x, y, z, 0.0)vec4(x, y, z, 1.0)

C++ OpenGL

评论


答:

3赞 Nicol Bolas 6/9/2016 #1
gl_Layer = 0;

这是几何着色器输出。调用将导致所有输出变量的值变为未定义。因此,必须始终为应用该输出的每个顶点设置每个输出。EmitVertex

评论

0赞 zeb 6/9/2016
只是尝试在正 X 面之前添加,在每面之前添加负 X 面。正面的 X 脸部工作(就像以前一样)但负面的 X 脸仍然没有收到任何颜色。看起来只有正面的 X 面被绑定,因为除了 0 之外的每个图层都不起作用,但我已经为目标立方体贴图构建了帧缓冲区,用于纹理目标并将其附加到帧缓冲区。我只用于gl_Layer = 0;EmitVertex()gl_Layer = 1;EmitVertex()GL_TEXTURE_CUBE_MAPglFramebufferTextureGL_TEXTURE_CUBE_MAP_POSITIVE_X+...glTexImage2D
0赞 zeb 6/9/2016
我认为问题是由于我在将帧缓冲区绑定为绘制缓冲区时的调用,因为做了一个愚蠢的测试,我试图在之后删除调用,并且像这样可以看到负 X,但视口错误。此时,我应该如何设置立方体贴图的视口以对其进行渲染?glViewport()glViewport()glBindFramebuffer
0赞 zeb 6/9/2016
事实证明,我创建了尺寸为 256x256 像素的立方体贴图,当我将该纹理绑定为渲染目标并将视口设置为大于 181x181 像素的维度时,负 X 面不是渲染器。直到 181x181 一切正常,超过 181x181 它不再起作用,我不明白为什么