我正在尝试编写一个几何着色器来替换glLineWidth
行为。我想用可定制的宽度绘制线条(现在用制服就够了)。线条应始终具有相同的粗细,而不管相机投影或到线条位置的距离如何。
基于大量的谷歌搜索,我提出了以下几何体着色器:
# version 330
layout (lines) in;
layout (triangle_strip, max_vertices = 4) out;
uniform mat4 u_model_matrix;
uniform mat4 u_view_matrix;
uniform mat4 u_projection_matrix;
uniform float u_thickness = 4; // just a test default
void main()
{
float r = u_thickness / 2;
mat4 mv = u_view_matrix * u_model_matrix;
vec4 p1 = mv * gl_in[0].gl_Position;
vec4 p2 = mv * gl_in[1].gl_Position;
vec2 dir = normalize(p2.xy - p1.xy);
vec2 normal = vec2(dir.y, -dir.x);
vec4 offset1, offset2;
offset1 = vec4(normal * r, 0, 0);
offset2 = vec4(normal * r, 0, 0);
vec4 coords[4];
coords[0] = p1 + offset1;
coords[1] = p1 - offset1;
coords[2] = p2 + offset2;
coords[3] = p2 - offset2;
for (int i = 0; i < 4; ++i) {
coords[i] = u_projection_matrix * coords[i];
gl_Position = coords[i];
EmitVertex();
}
EndPrimitive();
}
为了完整起见,下面是顶点着色器:
# version 330
in vec4 a_position;
void main() {
gl_Position = a_position;
}
..。和我的片段着色器:
# version 330
uniform vec4 u_color = vec4(1, 0, 1, 1);
out vec4 fragColor;
void main() {
fragColor = u_color;
}
我不能让数学在所有情况下都起作用。使用正交摄像头时,上面的设置效果很好:
但对于透视相机,问题是线条的大小不是固定的。相对于物体的距离,它会变得越来越大和越来越小。
我还以为这条线用透视相机也是一样的大小。我做错了什么?
3条答案
按热度按时间ykejflvf1#
我不是Maven,但我以前做过这方面的工作,我将提供我的见解。
我假设你的e1d0d1直接来自顶点着色器,它是使用投影矩阵计算出来的。这意味着它们的
w
组件是点的“剪辑空间位置”;这是管道用来赋予投影效果的东西(越远的东西越小)。因此,需要考虑到这一点。幸运的是,您唯一需要做的就是将您的偏移量与之相乘。
这应该会给你带来你想要的效果。
eh57zj3b2#
我设法修复了它,考虑了视区的大小,并使用它来缩放我的r。我不知道这是否是解决这个问题的最有效的方法(我绝对不是一个数学头脑),但它确实有效。
在下面的代码中,我现在在屏幕空间而不是相机/视图空间中完成所有工作,并且我使用u_viewportInvSizeVec2(它是1/viewportSize)来缩放我想要的半径!
8ftvxx2r3#
几何体着色器并不以速度快而闻名。使用几何体着色器是性能杀手,因此只有在所有其他选项都不在考虑范围内时才建议使用。不使用几何体着色器的可能解决方案在回答OpenGL线宽时提供。
无论如何,如果要使用几何体着色器,则通过顶点着色器中的模型视图投影矩阵X变换顶点坐标:
按透视分割计算几何体明暗器中的规格化设备坐标:
规格化设备空间是一个立方体,其左侧、底部、靠近(-1,-1,-1)和右侧,顶部,背面(1,1,1)。
计算直线两点之间的向量.按视区大小缩放以考虑视区的纵横比。最后,将Unit vector放到行中:
计算垂直于该线的Hal厚度偏移向量,并将其转换到归一化设备空间。这是通过反转长宽比缩放并乘以2来实现的:
将偏移向量添加到规格化的设备坐标,并“撤消”透视分割:
可以进一步优化并生成以下几何图形着色器
片段着色器
完整示例:https://github.com/Rabbid76/graphics-snippets/blob/master/example/cpp/opengl/example_shader_geometry_1_line.cpp