【发布时间】:2013-06-02 15:46:24
【问题描述】:
我编写了一个几何着色器来计算网格和平面的相交轮廓,但在相交点处,两条线之间有时会有 1 个像素宽的间隙。
着色器首先计算三角形顶点到平面的有符号距离。然后它检查两个距离是否有不同的符号,以确定是否存在与边缘的交叉点。如果是这样,它会在交点处发出一个顶点,该顶点被计算为边缘点之间的加权平均值。
#version 330
layout(triangles) in;
layout(line_strip, max_vertices = 3) out;
out vec3 vertexPosition;
uniform vec3 planePos;
uniform vec3 planeNormal;
uniform mat4 mvpMatrix;
uniform vec2 screenSize;
void intersection(in vec4 a, in float distA, in vec4 b, in float distB)
{
if (sign(distA) * sign(distB) <= 0.0f && !(sign(distA) == 0 && sign(distB) == 0))
{
float fa = abs(distA);
float fb = abs(distB);
float fab = fa + fb;
vec4 ptIntersection;
// Don't divide by zero.
if (fab < 0.001)
ptIntersection = (a + b) * 0.5;
else
ptIntersection = (fa * b + fb * a) / fab;
gl_Position = mvpMatrix * ptIntersection;
vertexPosition = gl_Position.xyw;
EmitVertex();
}
}
void main()
{
vec4 a = gl_in[0].gl_Position;
vec4 b = gl_in[1].gl_Position;
vec4 c = gl_in[2].gl_Position;
float distA = dot(a.xyz - planePos, planeNormal);
float distB = dot(b.xyz - planePos, planeNormal);
float distC = dot(c.xyz - planePos, planeNormal);
intersection(a, distA, b, distB);
intersection(b, distB, c, distC);
intersection(c, distC, a, distA);
}
我知道这有点便宜,因为我忽略了所有三个点都位于平面上的特殊情况。 !(sign(distA) == 0 && sign(distB) == 0) 确保如果两个点位于平面上,则不会为该边发射任何顶点。所以如果三个都在平面上,就没有输出了。但我想这不一定是坏事。我喜欢它的地方是没有疯狂的分支,如果可能的话,我想保持这种状态。
所以我想知道:为什么我会看到这些差距?假设有两个三角形 (a,b,c) 和 (c,b,d)。 a 和 b 在平面上方,c 和 d 在下方。对于第一个三角形,着色器生成与 (b,c) 的交点,第二个三角形生成与 (c,b) 的交点。假设两个浮点数的相加是可交换的,那么 intersection 函数是对称的输入,所以结果应该是相同的。为什么我仍然看到这些差距?
【问题讨论】:
-
你以前问过这个问题吗?
-
@Nicol 是的,但几分钟后我意识到我最初的分析是错误的,所以我删除了它。
-
您尝试过使用不变量限定符吗?
-
你确定这不是 z-buffer 的问题吗?我只是问,因为绿线中间的小角。我希望,如果它是几何着色器中的计算问题,那么那里的水平或垂直间隙而不是这样的 corner。
-
小角恰好出现在行光栅化器从水平切换到垂直的位置。