我有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)应该意味着我是"绘制"在整个视口。 修改顶点着色器的位置会导致片段着色器的输出值不同。
上面的代码有什么问题,为什么绘图从0.5 / rect_mesh_side_length开始?
这是最初发布的question。
有什么建议吗?
答案 0 :(得分:3)
片段着色器输入正在像素中心进行插值。 OpenGL 4.5规范的第15.2.2节(https://www.opengl.org/registry/doc/glspec45.core.pdf)"着色器输入"提供了此行为的详细说明以及如何对其进行控制。
这是我为了说明而快速制作的图表。
由于已经知道了网格的维度,因此可以将它们作为统一变量传递,并在片段着色器中使用以下代码。这将为您提供从0.0到1.0的坐标。
vec2 coord = floor(gl_FragCoord.xy) / vec2(horizontalVerticesCount - 1.0, verticalVerticesCount - 1.0);