После умножения на матрицу перспективной проекции (или матрицу клипов) вы получите однородный 4-вектор [x, y, z, w]. Это называется npc (нормализованные координаты проекции), а также называется координатами клипа. Чтобы получить 2D координаты на экране, вы обычно используете что-то вроде
xscreen = (x/w) * screen_width
yscreen = (y/w) * screen_width
Для точек перед камерой это дает вам то, что вы хотите. Но точки за камерой будут иметь w <0, и вы получите значения, которые соответствуют действительным координатам экрана, даже если точка находится за камерой. Чтобы избежать этого, вам нужно закрепить клип. Любая вершина, имеющая w <0, должна быть обрезана. </p>
Быстрая попытка состоит в том, чтобы просто не рисовать линии, если у любой вершины есть w <0. Это должно исправить странные полигоны, которые появляются в вашей сцене. Но это также удалит некоторые строки, которые должны быть видны. </p>
Чтобы полностью решить проблему, вам нужно обрезать все линии, у которых одна вершина находится перед камерой и одна вершина позади камеры. Отсечение означает разрезать линию пополам и выбросить половину, которая находится позади камеры. Линия «обрезается» плоскостью, проходящей через камеру и параллельной экрану дисплея. Задача состоит в том, чтобы найти точку на линии, которая соответствует этой плоскости (то есть, где линия пересекает плоскость). Это произойдет в точке на линии, где w == 0. Вы можете найти эту точку, но потом при попытке найти координаты экрана
xscreen = (x/w) * screen_width
yscreen = (y/w) * screen_width
В итоге вы делитесь на 0 (w == 0). Это причина "ближнего отсечения самолета". Ближайшая плоскость отсечения также параллельна экрану дисплея, но находится перед камерой (между камерой и сценой). Расстояние между камерой и ближней плоскостью отсечения является «ближним» параметром матрицы проекции:
[ near/width ][ 0 ][ 0 ][ 0 ]
[ 0 ][ near/height ][ 0 ][ 0 ]
[ 0 ][ 0 ][(far+near)/(far-near) ][ 1 ]
[ 0 ][ 0 ][-(2*near*far)/(far-near)][ 0 ]
Чтобы обрезать ближнюю плоскость, вы должны найти точку на линии, которая пересекает ближнюю плоскость отсечения. Это точка, где w == рядом. Так что если у вас есть линия с вершинами v1, v2, где
v1 = [x1, y1, z1, w1]
v2 = [x2, y2, z2, w2]
вам нужно проверить, находится ли каждая вершина перед или позади ближней плоскости отсечения. V1 впереди, если w1> = близко и сзади, если w1 <рядом. Если v1 и v2 оба впереди, то проведите линию. Если v1 и v2 оба позади, тогда не рисуйте линию. Если v1 впереди, а v2 сзади, вам нужно найти vc, где линия пересекает плоскость ближнего клипа: </p>
n = (w1 - near) / (w1 - w2)
xc = (n * x1) + ((1-n) * x2)
yc = (n * y1) + ((1-n) * y2)
zc = (n * z1) + ((1-n) * z2)
wc = near
vc = [xc, yc, zc, wc]
Теперь проведите линию между v1 и vc.