メッシュとプレーンの交差輪郭を計算するジオメトリ シェーダーを作成しましたが、交差ポイントで 2 つの線の間に 1 ピクセル幅のギャップが生じることがあります。
シェーダーはまず、三角形の頂点から平面までの符号付き距離を計算します。次に、2 つの距離の符号が異なるかどうかをチェックして、エッジとの交差があるかどうかを判断します。その場合、エッジ ポイント間の加重平均として計算される交点で頂点を放出します。
#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);
}
3 つの点すべてが平面上にあるという特殊なケースを無視したので、それがちょっと安っぽいことはわかっています。は!(sign(distA) == 0 && sign(distB) == 0)
、2 つの点が平面上にある場合、そのエッジに対して頂点が放出されないようにします。したがって、3 つすべてが平面上にある場合、出力はありません。しかし、それは必ずしも悪いことではないと思います。私が気に入っているのは、クレイジーな分岐がないことです。可能であればそのままにしておきたいです。
だから私は疑問に思っています:なぜこれらのギャップが見えるのですか? 2 つの三角形 (a、b、c) と (c、b、d) があるとします。a と b は平面の上にあり、c と d は下にあります。最初の三角形では、シェーダーは (b,c) との交点を生成し、2 番目の三角形では (c,b) との交点を生成します。2 つの float の加算が可換であると仮定すると、intersection
関数は入力に関して対称であるため、結果は同じになるはずです。これらのギャップがまだ見られるのはなぜですか?