我正在尝试实现单通线框,但我在这个过程中遇到了几个问题。
出于某些原因,在我的几何着色器工作之后,我只得到没有线框(比如glPolygoneMode
- 线)填充几何体。
)
但如果我禁用几何着色器,我会得到几何体:
我真正想要实现的是几何体及其线框。
实际上,我的图元是三角形条。我使用它们来避免在四边形上使用以提高性能。如何在绘制时跳过线框的边缘? (我已经看到了post如何做到这一点,但我仍然不清楚。)
#version 330
//
// (C) Copyright 2010 Patrick Cozzi and Deron Ohlarik
//
// Distributed under the MIT License.
// See License.txt or http://www.opensource.org/licenses/mit-license.php.
//
layout(location = 0) in vec3 in_Position;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
uniform mat4 og_viewportTransformationMatrix;
out vec2 windowPosition;
vec4 og_ClipToWindowCoordinates(vec4 v, mat4 viewportTransformationMatrix);
void main()
{
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(in_Position, 1.0);
windowPosition = og_ClipToWindowCoordinates(gl_Position, og_viewportTransformationMatrix).xy;
}
vec4 og_ClipToWindowCoordinates(vec4 v, mat4 viewportTransformationMatrix)
{
v.xyz /= v.w; // normalized device coordinates
v.xyz = (viewportTransformationMatrix * vec4(v.xyz, 1.0)).xyz; // window coordinates
return v;
}
#version 330
//
// (C) Copyright 2010 Patrick Cozzi and Deron Ohlarik
//
// Distributed under the MIT License.
// See License.txt or http://www.opensource.org/licenses/mit-license.php.
//
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
in vec2 windowPosition[];
noperspective out vec3 distanceToEdges;
float og_distanceToLine(vec2 f, vec2 p0, vec2 p1);
void main()
{
vec2 p0 = windowPosition[0];
vec2 p1 = windowPosition[1];
vec2 p2 = windowPosition[2];
gl_Position = gl_in[0].gl_Position;
distanceToEdges = vec3(og_distanceToLine(p0, p1, p2), 0.0, 0.0);
EmitVertex();
gl_Position = gl_in[1].gl_Position;
distanceToEdges = vec3(0.0, og_distanceToLine(p1, p2, p0), 0.0);
EmitVertex();
gl_Position = gl_in[2].gl_Position;
distanceToEdges = vec3(0.0, 0.0, og_distanceToLine(p2, p0, p1));
EmitVertex();
}
float og_distanceToLine(vec2 f, vec2 p0, vec2 p1)
{
vec2 l = f - p0;
vec2 d = p1 - p0;
//
// Closed point on line to f
//
vec2 p = p0 + (d * (dot(l, d) / dot(d, d)));
return distance(f, p);
}
#version 330
//
// (C) Copyright 2010 Patrick Cozzi and Deron Ohlarik
//
// Distributed under the MIT License.
// See License.txt or http://www.opensource.org/licenses/mit-license.php.
//
uniform float u_halfLineWidth;
uniform vec3 u_color;
noperspective in vec3 distanceToEdges;
out vec4 fragmentColor;
void main()
{
float d = min(distanceToEdges.x, min(distanceToEdges.y, distanceToEdges.z));
if (d > u_halfLineWidth + 1.0)
{
discard;
}
d = clamp(d - (u_halfLineWidth - 1.0), 0.0, 2.0);
fragmentColor = vec4(u_color, exp2(-2.0 * d * d));
}
帮我弄清楚我错在哪里。
更新
我已经更新Fragment shader
和Geometry shader
提及Andon M. Coleman的回答,但问题2 中描述的问题仍未解决。
更新2
我刚刚在fragmet着色器中做了一些小编辑,这解决了我的问题。
更新片段着色器
#version 330
//
// (C) Copyright 2010 Patrick Cozzi and Deron Ohlarik
//
// Distributed under the MIT License.
// See License.txt or http://www.opensource.org/licenses/mit-license.php.
//
uniform float u_halfLineWidth;
uniform vec3 u_color;
noperspective in vec3 distanceToEdges;
out vec4 fragmentColor;
void main()
{
float d = min(distanceToEdges.y, max(distanceToEdges.x, distanceToEdges.z));
if (d > u_halfLineWidth + 1.0)
{
fragmentColor = vec4(u_color, 1);
return;
}
fragmentColor = vec4(vec3(0,0,0), 1);
}
答案 0 :(得分:3)
discard
。目前, 丢弃 片段与片段着色器中线框的距离不合适。这是不正确的行为,这将 仅 绘制线框。
discard
。if (d > u_halfLineWidth + 1.0)
{
//discard; // DO NOT DO THIS
//
// Instead, do this
//
fragmentColor = vec4 (0.0, 0.0, 0.0, 1.0);
return;
}
当然,这将生成黑色填充网格,但如果使用颜色u_color
,则网格的填充部分将与线框无法区分。最终你可能想要定义一个与线框颜色分开的每顶点颜色,但是由你来决定如何做到这一点。
您链接的文章中的想法是,对于几何着色器发出的每个三角形,它应该为每个顶点写入相对边缘的距离。如果您知道三角形中的一条边是 内部 边缘,因此不应包含在线框中,则应设置顶点的距离 与该边 相对,它从不插入 0 (或您为线框选择的任何宽度)。
void main()
{
vec2 p0 = windowPosition[0];
vec2 p1 = windowPosition[1];
vec2 p2 = windowPosition[2];
// Alternate between using the first and last vertex as the one opposite the
// interior edge based on primitive ID.
bool strip_flip = (bool (gl_PrimitiveIDIn & 1));
gl_Position = gl_in[0].gl_Position;
if (strip_flip)
distanceToEdges = vec3(og_distanceToLine(p0, p1, p2), 0.0, 0.0);
else
distanceToEdges = vec3(og_distanceToLine(p0, p1, p2), 0.0, 99999.0);
EmitVertex();
gl_Position = gl_in[1].gl_Position;
if (strip_flip)
distanceToEdges = vec3(99999.0, og_distanceToLine(p1, p2, p0), 0.0);
else
distanceToEdges = vec3(0.0, og_distanceToLine(p1, p2, p0), 99999.0);
EmitVertex();
gl_Position = gl_in[2].gl_Position;
if (strip_flip)
distanceToEdges = vec3(99999.0, 0.0, og_distanceToLine(p2, p0, p1));
else
distanceToEdges = vec3( 0.0, 0.0, og_distanceToLine(p2, p0, p1));
EmitVertex();
}
这通过在第一个/最后一个顶点之间交替工作,该顶点用作与条带插入的内边缘相对的顶点。对于每个奇数三角形,内边缘与第一个顶点相对,对于每个偶数三角形,它与最后一个相对。这基本上是三角形条带的操作方式,每个连续的三角形上的绕组都是相反的,这使得识别哪个边缘变得容易。
为确保distanceToEdges
永远不会在此边缘方向上插入小于或等于u_HalfLineWidth + 1.0
的任何内容,所述坐标将从其正常的 0.0 值推送到<强> 99999.0 强>
想象一下,在虚线边缘反映出一个三角形,然后你应该对几何着色器的作用有了很好的了解。