我进行了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 );


...由于纹理坐标在0.0、0.0到1.0、1.0之间变化,因此输出顶点的位置应在vec3(0.0,0.0,0.0)到vec3(1.0,1.0,0.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)应该意味着我正在整个视口上“绘制”。
修改顶点着色器的位置会导致片段着色器的输出值不同。

上面的代码有什么问题,为什么图形从0.5 / rect_mesh_side_length开始?

这是最初发布的question

有什么建议么?

最佳答案

片段着色器输入正在像素中心进行插值。 OpenGL 4.5规范(https://www.opengl.org/registry/doc/glspec45.core.pdf)的第15.2.2节“着色器输入”详细介绍了此行为及其控制方式。

这是我快速绘制的图表,仅供参考。



由于您已经知道网格的尺寸,因此可以将它们作为统一变量传递,并在片段着色器中使用以下代码。这将为您提供从0.0到1.0(含)的坐标。

vec2 coord = floor(gl_FragCoord.xy) / vec2(horizontalVerticesCount - 1.0, verticalVerticesCount - 1.0);

关于c++ - FBO +纹理:从屏幕外生成几何数据会产生奇怪的结果,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28031750/

10-13 08:10