FBO + 纹理:离屏生成几何数据的奇怪结果
FBO + texture: strange results from offscreen generation of geometry data
我有 2+ 遍渲染,其中第一阶段生成矩形网格的顶点位置并将它们存储在 2D 浮点纹理中。着色器看起来像这样:
顶点:
#version 330 core
out vec2 vfTexCoords;
const float halfSide = 1.0f;
const vec2[] pos = vec2[ 4 ]
(
vec2( -halfSide, -halfSide ),
vec2( halfSide, -halfSide ),
vec2( halfSide, halfSide ),
vec2( -halfSide, halfSide )
);
const vec2[] tex = vec2[ 4 ]
(
vec2( 0.0f, 0.0f ),
vec2( 1.0f, 0.0f ),
vec2( 1.0f, 1.0f ),
vec2( 0.0f, 1.0f )
);
void main()
{
vfTexCoords = tex[ gl_VertexID ];
gl_Position = vec4( pos[ gl_VertexID ], 0.0f, 1.0f );
}
片段:
in vec2 vfTexCoords;
layout (location = 0) out vec3 pos;
void main()
{
pos = vec3( vfTexCoords, 0.0f );
}
输出的 2D 浮动纹理被调整为矩形顶点网格的尺寸,并将其绑定到 FBO 的颜色附件之一。因此,FBO 大小继承自纹理大小。
视口设置为与矩形网格尺寸相同:
glViewport( 0, 0, horizontalVerticesCount, verticalVerticesCount );
所以,现在视口和纹理都具有相同的大小,之后:
glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
...输出顶点的位置应在 vec3(0.0, 0.0, 0.0) 到 vec3(1.0, 1.0, 0.0) 之间,因为纹理坐标从 0.0, 0.0 到 1.0, 1.0.
奇怪的是片段着色器输出顶点位置的x和y值从非零开始并且它们的最大值低于1.0。
对于 2 x 2 网格:
左下角:vec3( 0.25, 0.25, 0.0 ) ( 0.5 / mesh_side = 0.5 / 2 = 0.25 )
右上角:vec3( 0.75, 0.75, 0.0 )
对于 16 x 16 网格:
左下角:vec3( 0.03125, 0.03125 , 0.0 ) ( 0.5 / mesh_side = 0.5 / 16 = 0.03125 )
右上角:vec3( 0.96875, 0.96875, 0.0 )
将顶点着色器位置设置为从 vec3(-1.0, -1.0, 0.0) 到 vec3(1.0, 1.0, 0.0) 应该意味着我在整个视口上 "drawing"。
修改顶点着色器的位置会导致片段着色器的输出值不同。
上面的代码有什么问题,为什么绘图是从 0.5 / rect_mesh_side_length 开始的?
这是最初发布的 question。
有什么建议吗?
片段着色器输入在像素中心进行插值。 OpenGL 4.5 规范的第 15.2.2 节 (https://www.opengl.org/registry/doc/glspec45.core.pdf)"Shader Inputs" 详细描述了此行为及其控制方式。
这是我快速绘制的图表,仅供说明之用。
由于您已经知道网格的尺寸,您可以将它们作为统一变量传入并在片段着色器中使用以下代码。这将为您提供从 0.0 到 1.0 的坐标。
vec2 coord = floor(gl_FragCoord.xy) / vec2(horizontalVerticesCount - 1.0, verticalVerticesCount - 1.0);
我有 2+ 遍渲染,其中第一阶段生成矩形网格的顶点位置并将它们存储在 2D 浮点纹理中。着色器看起来像这样:
顶点:
#version 330 core
out vec2 vfTexCoords;
const float halfSide = 1.0f;
const vec2[] pos = vec2[ 4 ]
(
vec2( -halfSide, -halfSide ),
vec2( halfSide, -halfSide ),
vec2( halfSide, halfSide ),
vec2( -halfSide, halfSide )
);
const vec2[] tex = vec2[ 4 ]
(
vec2( 0.0f, 0.0f ),
vec2( 1.0f, 0.0f ),
vec2( 1.0f, 1.0f ),
vec2( 0.0f, 1.0f )
);
void main()
{
vfTexCoords = tex[ gl_VertexID ];
gl_Position = vec4( pos[ gl_VertexID ], 0.0f, 1.0f );
}
片段:
in vec2 vfTexCoords;
layout (location = 0) out vec3 pos;
void main()
{
pos = vec3( vfTexCoords, 0.0f );
}
输出的 2D 浮动纹理被调整为矩形顶点网格的尺寸,并将其绑定到 FBO 的颜色附件之一。因此,FBO 大小继承自纹理大小。
视口设置为与矩形网格尺寸相同:
glViewport( 0, 0, horizontalVerticesCount, verticalVerticesCount );
所以,现在视口和纹理都具有相同的大小,之后:
glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
...输出顶点的位置应在 vec3(0.0, 0.0, 0.0) 到 vec3(1.0, 1.0, 0.0) 之间,因为纹理坐标从 0.0, 0.0 到 1.0, 1.0.
奇怪的是片段着色器输出顶点位置的x和y值从非零开始并且它们的最大值低于1.0。 对于 2 x 2 网格: 左下角:vec3( 0.25, 0.25, 0.0 ) ( 0.5 / mesh_side = 0.5 / 2 = 0.25 ) 右上角:vec3( 0.75, 0.75, 0.0 )
对于 16 x 16 网格: 左下角:vec3( 0.03125, 0.03125 , 0.0 ) ( 0.5 / mesh_side = 0.5 / 16 = 0.03125 ) 右上角:vec3( 0.96875, 0.96875, 0.0 )
将顶点着色器位置设置为从 vec3(-1.0, -1.0, 0.0) 到 vec3(1.0, 1.0, 0.0) 应该意味着我在整个视口上 "drawing"。 修改顶点着色器的位置会导致片段着色器的输出值不同。
上面的代码有什么问题,为什么绘图是从 0.5 / rect_mesh_side_length 开始的?
这是最初发布的 question。
有什么建议吗?
片段着色器输入在像素中心进行插值。 OpenGL 4.5 规范的第 15.2.2 节 (https://www.opengl.org/registry/doc/glspec45.core.pdf)"Shader Inputs" 详细描述了此行为及其控制方式。
这是我快速绘制的图表,仅供说明之用。
由于您已经知道网格的尺寸,您可以将它们作为统一变量传入并在片段着色器中使用以下代码。这将为您提供从 0.0 到 1.0 的坐标。
vec2 coord = floor(gl_FragCoord.xy) / vec2(horizontalVerticesCount - 1.0, verticalVerticesCount - 1.0);