我正在尝试使用几何着色器渲染任意宽线(在屏幕空间中)。乍一看似乎一切都很好,但在某些视图位置上,线条渲染不正确:
左侧图像呈现正确的渲染(正 X、Y 和 Z 轴上的三条线,2 像素宽)。
当相机移动到原点附近(实际上靠近线条)时,线条会像正确的图像一样渲染。着色器看起来很简单,但我不明白我的 GPU 上发生了什么:
--- Vertex Shader
#version 410 core
// Modelview-projection matrix
uniform mat4 ds_ModelViewProjection;
// Vertex position
in vec4 ds_Position;
// Vertex color
in vec4 ds_Color;
// Processed vertex color
out vec4 ds_VertexColor;
void main()
{
gl_Position = ds_ModelViewProjection * ds_Position;
ds_VertexColor = ds_Color;
}
--- Geometry Shader
#version 410 core
// Viewport size, in pixels
uniform vec2 ds_Viewport;
// Line width, in pixels
uniform float ds_LineWidth = 2.0;
// Processed vertex color (from VS, in clip space)
in vec4 ds_VertexColor[2];
// Processed primitive vertex color
out vec4 ds_GeoColor;
layout (lines) in;
layout (triangle_strip, max_vertices = 4) out;
void main()
{
vec3 ndc0 = gl_in[0].gl_Position.xyz / gl_in[0].gl_Position.w;
vec3 ndc1 = gl_in[1].gl_Position.xyz / gl_in[1].gl_Position.w;
vec2 lineScreenForward = normalize(ndc1.xy - ndc0.xy);
vec2 lineScreenRight = vec2(-lineScreenForward.y, lineScreenForward.x);
vec2 lineScreenOffset = (vec2(ds_LineWidth) / ds_ViewportSize) * lineScreenRight;
gl_Position = vec4(ndc0.xy + lineScreenOffset, ndc0.z, 1.0);
ds_GeoColor = ds_VertexColor[0];
EmitVertex();
gl_Position = vec4(ndc0.xy - lineScreenOffset, ndc0.z, 1.0);
ds_GeoColor = ds_VertexColor[0];
EmitVertex();
gl_Position = vec4(ndc1.xy + lineScreenOffset, ndc1.z, 1.0);
ds_GeoColor = ds_VertexColor[1];
EmitVertex();
gl_Position = vec4(ndc1.xy - lineScreenOffset, ndc1.z, 1.0);
ds_GeoColor = ds_VertexColor[1];
EmitVertex();
EndPrimitive();
}
--- Fragment Shader
// Processed primitive vertex color
in vec4 ds_GeoColor;
// The fragment color.
out vec4 ds_FragColor;
void main()
{
ds_FragColor = ds_GeoColor;
}
你的错误在于:
gl_Position = vec4(ndc0.xy + lineScreenOffset, ndc0.z, 1.0 /* WRONG */);
要解决这个问题:
vec4 cpos = gl_in[0].gl_Position;
gl_Position = vec4(cpos.xy + lineScreenOffset*cpos.w, cpos.z, cpos.w);
您所做的是:丢失有关 W 的信息,从而使 HW 限幅器失谐,将其从 3D 限幅器降级为 2D 限幅器。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)