Перспективная проекция - как проецировать точки, которые находятся за «камерой»? - PullRequest
9 голосов
/ 25 июля 2010

Я пишу свой собственный программный растеризатор на Java, и у меня возникли некоторые проблемы с ним ... взгляните на пример изображения, пожалуйста:

Изображение

В этом примере просто нарисуйте простую квадратную сетку на плоскости. Все работает хорошо, пока я не подвину камеру достаточно близко, чтобы некоторые точки могли двигаться за ней. После этого они больше не проецируются правильно, как вы можете видеть (вертикальные линии - точки, которые должны находиться за камерой, проецируются сверху экрана).

Мои матрицы преобразования и векторы совпадают с теми, которые использует DirectX (PerspectiveFovLH для проекции, LookAtLH для камеры).

Я использую следующий метод преобразования для проецирования 3D-точки:

  1. Создан трехмерный вектор для преобразования.
  2. Вектор умножается на матрицу ViewProjection.
  3. После этого точка преобразуется в экран следующим способом:

    // 'vector' is input vector in projection space
    // projection to screen
    double vX = vector.x / vector.z;        
    double vY = vector.y / vector.z;
    
    //translate
    //surfaceW is width and surfaceH is height of the rendering window.
    vX = (( vX + 1.0f) / 2.0f) * surfaceW;
    vY = ((-vY + 1.0f) / 2.0f) * surfaceH;
    
    return new Vector3(vX, vY, vector.z);
    

Как я уже говорил ранее, он работает нормально, пока точка не переместится за камеру. Дело в том, что я могу выяснить, когда точка находится за камерой (проверяя ее значение Z после окончательного преобразования), но поскольку я рисую линии и другие объекты на основе линий, я не могу просто пропустить эту точку.

Затем я попытался настроить конвейер преобразования в соответствии с Статья преобразования Direct3D в MSDN.

К сожалению, мне тоже не повезло с этим (те же результаты), поэтому любая помощь будет высоко оценена, так как я немного застрял на этом.

Спасибо.

С наилучшими пожеланиями, Alex

1 Ответ

8 голосов
/ 27 июля 2010

Вам необходимо пересечь линию с передней плоскостью отсечения в трехмерном пространстве и обрезать ее, чтобы нарисовать только видимый отрезок линии:

             |
             |
             |
x------------+-----------o
             |
             |
             |   * - camera
             |
             |
             |
       clipping plane

У вас есть линия xo, гдеx перед плоскостью отсечения и o за ней.Пересечь эту линию с плоскостью отсечения, чтобы получить точку +.Вы знаете, какие из x и o видимы, поэтому проведите линию от x до +.

Таким образом, вы не проецируете точки, которые находятся за камерой.

...