OpenGL 分层渲染干扰第 0 层
OpenGL layered rendering interferes with layer 0
我在几何着色器中使用 gl_Layer = gl_InvocationID;
渲染到附有 3D 纹理的帧缓冲区。
这大部分工作正常。除了着色器的每次调用也会渲染到层 0 以及我指定的层。
我怎样才能避免这种情况?设置帧缓冲区时我缺少什么重要的东西吗?也许用 glFramebufferTexture
?
几何着色器
#version 400
layout(invocations = 32) in;
layout(points) in;
layout(triangle_strip, max_vertices = 3) out;
out vec3 raster_color;
float blue;
void main()
{
gl_Layer = gl_InvocationID;
blue = float(gl_InvocationID) / 31.0;
gl_Position = vec4( -1.0, -1.0, 0.0, 1.0 );
raster_color = vec3( 0.0, 0.0, blue );
EmitVertex();
gl_Position = vec4( 1.0, -1.0, 0.0, 1.0 );
raster_color = vec3( 1.0, 0.0, blue );
EmitVertex();
gl_Position = vec4( 0.0, 1.0, 0.0, 1.0 );
raster_color = vec3( 1.0, 1.0, blue );
EmitVertex();
EndPrimitive();
}
片段着色器
#version 400
in vec3 raster_color;
out vec4 fragment_color;
void main()
{
fragment_color = vec4( raster_color, 1.0 );
}
EmitVertex
使它 returns 之后的所有每个顶点 输出 无效。此着色器中最明显的逐顶点输出是:
raster_color
gl_Position
但是,你可能没有意识到gl_Layer
也是per-vertex或者需要为哪个顶点设置。
gl_Layer
对于此着色器中第一个顶点之后的每个顶点都将是未定义的。有些驱动程序会保持原样并简单地工作,其他人会用它做任何他们想做的事情,你不能对 EmitVertex (...)
之后的 gl_Layer
做任何假设。 你在玩火,因为它可能不是定义图元层的第一个顶点(稍后会详细介绍)。
要解决此问题,请按以下方式重新编写几何着色器:
#version 400
layout(invocations = 32) in;
layout(points) in;
layout(triangle_strip, max_vertices = 3) out;
out vec3 raster_color;
float blue;
void main()
{
blue = float(gl_InvocationID) / 31.0;
gl_Position = vec4( -1.0, -1.0, 0.0, 1.0 );
raster_color = vec3( 0.0, 0.0, blue );
gl_Layer = gl_InvocationID; // Handle case where First Vertex is Layer Provoking
EmitVertex();
gl_Position = vec4( 1.0, -1.0, 0.0, 1.0 );
raster_color = vec3( 1.0, 0.0, blue );
gl_Layer = gl_InvocationID; // Handle case where Layer Provoking vertex is Undefined
EmitVertex();
gl_Position = vec4( 0.0, 1.0, 0.0, 1.0 );
raster_color = vec3( 1.0, 1.0, blue );
gl_Layer = gl_InvocationID; // Handle case where Last Vertex is Layer Provoking
EmitVertex();
EndPrimitive();
}
我想借此机会指出图元中只有1个顶点需要设置gl_Layer
;这个顶点被称为 Layer Provoking Vertex。您的着色器假定第一个顶点是层激发顶点,但这是特定于实现的。如有疑问,最好的解决方案是覆盖所有基础(为所有顶点设置 gl_Layer
)。
您需要在 运行 时检查 GL_LAYER_PROVOKING_VERTEX
以确定哪个顶点定义了您的图层。如果你不想这样做,你可以按照我上面描述的方式编写你的着色器。引发顶点约定通常是第一个或最后一个,但几何着色器的工作方式留下了任意顶点可以定义层的可能性(GL_UNDEFINED_VERTEX
,这是你应该假设的情况)。
原来这不是 gl_Layer
的问题。这只是 glTexParameter
中的一个语法错误导致我生成的 3D 纹理重复而不是夹在边缘。
我在几何着色器中使用 gl_Layer = gl_InvocationID;
渲染到附有 3D 纹理的帧缓冲区。
这大部分工作正常。除了着色器的每次调用也会渲染到层 0 以及我指定的层。
我怎样才能避免这种情况?设置帧缓冲区时我缺少什么重要的东西吗?也许用 glFramebufferTexture
?
几何着色器
#version 400
layout(invocations = 32) in;
layout(points) in;
layout(triangle_strip, max_vertices = 3) out;
out vec3 raster_color;
float blue;
void main()
{
gl_Layer = gl_InvocationID;
blue = float(gl_InvocationID) / 31.0;
gl_Position = vec4( -1.0, -1.0, 0.0, 1.0 );
raster_color = vec3( 0.0, 0.0, blue );
EmitVertex();
gl_Position = vec4( 1.0, -1.0, 0.0, 1.0 );
raster_color = vec3( 1.0, 0.0, blue );
EmitVertex();
gl_Position = vec4( 0.0, 1.0, 0.0, 1.0 );
raster_color = vec3( 1.0, 1.0, blue );
EmitVertex();
EndPrimitive();
}
片段着色器
#version 400
in vec3 raster_color;
out vec4 fragment_color;
void main()
{
fragment_color = vec4( raster_color, 1.0 );
}
EmitVertex
使它 returns 之后的所有每个顶点 输出 无效。此着色器中最明显的逐顶点输出是:
raster_color
gl_Position
但是,你可能没有意识到gl_Layer
也是per-vertex或者需要为哪个顶点设置。
gl_Layer
对于此着色器中第一个顶点之后的每个顶点都将是未定义的。有些驱动程序会保持原样并简单地工作,其他人会用它做任何他们想做的事情,你不能对 EmitVertex (...)
之后的 gl_Layer
做任何假设。 你在玩火,因为它可能不是定义图元层的第一个顶点(稍后会详细介绍)。
要解决此问题,请按以下方式重新编写几何着色器:
#version 400
layout(invocations = 32) in;
layout(points) in;
layout(triangle_strip, max_vertices = 3) out;
out vec3 raster_color;
float blue;
void main()
{
blue = float(gl_InvocationID) / 31.0;
gl_Position = vec4( -1.0, -1.0, 0.0, 1.0 );
raster_color = vec3( 0.0, 0.0, blue );
gl_Layer = gl_InvocationID; // Handle case where First Vertex is Layer Provoking
EmitVertex();
gl_Position = vec4( 1.0, -1.0, 0.0, 1.0 );
raster_color = vec3( 1.0, 0.0, blue );
gl_Layer = gl_InvocationID; // Handle case where Layer Provoking vertex is Undefined
EmitVertex();
gl_Position = vec4( 0.0, 1.0, 0.0, 1.0 );
raster_color = vec3( 1.0, 1.0, blue );
gl_Layer = gl_InvocationID; // Handle case where Last Vertex is Layer Provoking
EmitVertex();
EndPrimitive();
}
我想借此机会指出图元中只有1个顶点需要设置gl_Layer
;这个顶点被称为 Layer Provoking Vertex。您的着色器假定第一个顶点是层激发顶点,但这是特定于实现的。如有疑问,最好的解决方案是覆盖所有基础(为所有顶点设置 gl_Layer
)。
您需要在 运行 时检查 GL_LAYER_PROVOKING_VERTEX
以确定哪个顶点定义了您的图层。如果你不想这样做,你可以按照我上面描述的方式编写你的着色器。引发顶点约定通常是第一个或最后一个,但几何着色器的工作方式留下了任意顶点可以定义层的可能性(GL_UNDEFINED_VERTEX
,这是你应该假设的情况)。
原来这不是 gl_Layer
的问题。这只是 glTexParameter
中的一个语法错误导致我生成的 3D 纹理重复而不是夹在边缘。