Проблема с отсечением программного 3D-рендеринга: треугольники исчезают или имеют пробелы при пересечении ближней плоскоJAVA

Программисты JAVA общаются здесь
Anonymous
Проблема с отсечением программного 3D-рендеринга: треугольники исчезают или имеют пробелы при пересечении ближней плоско

Сообщение Anonymous »

Я пишу программу 3D-рендеринга на Java (в целях обучения). Я реализовал перспективную проекцию, текстуры, освещение, Z-буфер и отсечение задней поверхности. Все работает нормально, кроме обрезки.
Я пытаюсь обрезать треугольники по ближней плоскости (z = 0,2), а также по краям экрана (X и Y в пространстве NDC). Я использую алгоритм Сазерленда-Ходжмана для каждой плоскости.
Мой конвейер:
  • Преобразование вершин с помощью MVP (модель + представление + проекция) -> Пространство отсечения
  • Деление перспективы -> NDC
  • Отсечение по ближней плоскости и экрану края
  • Преобразовать в экранные координаты и растрировать
Проблема:
  • Когда треугольник пересекает ближнюю плоскость, иногда он полностью исчезает
  • Иногда между двумя треугольниками возникают промежутки, образующие quad
Что я пробовал:
  • Изменение порядка вершин в полученных треугольниках (для случая «2 внутри»)
  • Различные близкие значения (0.1f, 0.5f, 1.0f)
  • Удаление отсечения задней поверхности (без эффекта)
  • Удаление Z-буфера (без эффекта)
Вот мой код отсечения (упрощенный):

Код: Выделить всё

public static List clipTriangle(RenderPolygon originPolygon) {
List inside = new ArrayList();
List outside = new ArrayList();

if (distToPlane(originPolygon.v0.pos) >= 0) inside.add(originPolygon.v0); else outside.add(originPolygon.v0);
if (distToPlane(originPolygon.v1.pos) >= 0) inside.add(originPolygon.v1); else outside.add(originPolygon.v1);
if (distToPlane(originPolygon.v2.pos) >= 0) inside.add(originPolygon.v2); else outside.add(originPolygon.v2);

List clipped = new ArrayList();
if (outside.isEmpty()) clipped.add(originPolygon);
else if (inside.size() == 1) {
Vertic vIntersect0 = planeIntersect(inside.getFirst(), outside.get(0));
Vertic vIntersect1 = planeIntersect(inside.getFirst(), outside.get(1));

clipped.add(new RenderPolygon(inside.getFirst(), vIntersect0, vIntersect1, originPolygon.normal, originPolygon.texture, originPolygon.color));
} else if (inside.size() == 2) {
Vertic vIntersect0 = planeIntersect(inside.get(0), outside.getFirst());
Vertic vIntersect1 = planeIntersect(inside.get(1), outside.getFirst());

clipped.add(new RenderPolygon(inside.get(0), inside.get(1), vIntersect0, originPolygon.normal, originPolygon.texture, originPolygon.color));
clipped.add(new RenderPolygon(inside.get(1), vIntersect1, vIntersect0, originPolygon.normal, originPolygon.texture, originPolygon.color));
}
return clipped;
}
Вопрос: Что может быть причиной исчезновения треугольников или появления пробелов? Неправильный ли порядок вершин в случае «2 внутри»? Должен ли я обрезать пространство клипа (с помощью w) вместо NDC? Будем признательны за любую помощь.
Полный код: https://github.com/224ia/3D-Render/tree/ClippingTrouble

Вернуться в «JAVA»