我编写了一个几何着色器来计算网格和平面的相交轮廓,但在相交点处,两条线之间有时会有 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
函数对于输入是对称的,所以结果应该是相同的。为什么我仍然看到这些差距?