Як слід обробляти відсічні вершини, які знаходяться ближче до ока, ніж найближча площина затиску?


13

Я розгортаю свій власний 3D-движок у JavaScript і використовую лише малюнок на полотні, не WebGL. Це ще один клон Minecraft; Я люблю коробки, не судіть мене.

Поки все працює чудово, за винятком однієї речі: у 3D, коли деякі вершини йдуть за близькою площиною відсікання, їх проекція на екран виходить дивною (припускаючи, що інші вершини, які використовуються для відстеження площини, знаходяться попереду).

Я спробував вирізати ці точки, але тоді я бачу корита поверхонь, які використовують ці вершини. У WebGL / OpenGL відеокарта опікується цими точками, і літак відображається правильно, але я не маю доступу до обладнання, тому я повинен сам це кодувати.

Я не зовсім впевнений, що з цього зробити, на даний момент останнє, що мені прийшло в голову, - це повернути проекцію очок за площиною відсікання гравця, що здається логічним, оскільки я повинен спроектувати точку на екран, який знаходиться попереду. вершини.

Ось мої думки:

введіть тут опис зображення

Ось кілька зображень для ілюстрації того, що відбувається:

введіть тут опис зображення

Здалеку блакитна скринька виглядає ідеально добре.

введіть тут опис зображення

Коли деякі вершини йдуть за близькою площиною відсікання гравця, я роблю зворотну проекцію, але це не виглядає правильно:

focalLength *= -1;
2d.x = x*focalLength/z;
2d.y = y*focalLength/z;

Зауважте, що сіре поле позаду повністю видалено, оскільки всі вершини, які використовуються для малювання його облич, знаходяться позаду гравця.

введіть тут опис зображення

Це те, що відбувається при погляді вгору або вниз.

Я не знаю, що робити з цього питання, я сподіваюся, що хтось уже стикався з тією ж проблемою і може допомогти мені.


1
Якщо точки розташовані ближче до ока, ніж найближча площина затиску, їх слід обрізати - і це дійсно може дати вам бачити об'єкт "крізь". Це типова поведінка; зіткнення зазвичай перешкоджає саме цьому зоровому артефакту. Це єдине, що не було у вашому рішенні для відсікання?

@JoshPetrie: Я розумію, що точки повинні бути відрізані, але якщо я це зробити, то весь квадрат зникне, як одна-дві вершини, через які повинна пройти звичайна схема малювання, відсутні (в 2d), і гравець зможе побачити через ту площу. Я хотів би, щоб вони знаходилися «поза» полотна (на проекції), щоб квадрат міг ще намалюватись. Я не впевнений, чи мені достатньо ясно.
Соленоїд

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

Те, що ви говорите, має сенс, реконструкція займає занадто багато часу, тому це не є рішенням. Я сподівався, що є спосіб все-таки намалювати цю вершину на площині 2d, яка була за плеєром, щоб lineTo(x,y)функцію все-таки можна було викликати, тільки я не знаю, як вона поводиться ... це причудливий вимір, я згоден.
Соленоїд

Погляньте на цей підручник , він пояснює, як обчислити відсікання окремих трикутників та об’єктів у цілому
ѕняєє ѕιіgnι

Відповіді:


1

Призначення найближчої площини відсікання полягає в тому, що це площина відсікання . Трикутники, які знаходяться поза площиною відсікання, обрізають : нарізають шматочками так, щоб кожен залишився шматок знаходився в межах відсікання.

Ви можете спробувати проігнорувати близький кліп, якщо бажаєте. Насправді OpenGL і D3D взагалі можуть відключити відсічення біля площини (хоча буфер глибини все ще має мінімальне близьке значення). Проблема не в недалекому кліпі.

Проблема полягає у вершинах, які знаходяться позаду камери.

Ви не можете відображати трикутники за камерою. Не з перспективної проекції. Такі трикутники не мають сенсу в математиці за перспективними прогнозами. Крім того, вони також знаходяться поза плодом.

Вимкнення біля обрізання перетворює фруст у піраміду. Причина, коли піраміда зупиняється на точці, полягає в тому, що точки над пірамідою знаходяться позаду всіх чотирьох сторін піраміди. Тож будь-яка точка за камерою (вістря піраміди) знаходиться вгорі, внизу, зліва та праворуч від видимої області екрана. Все одночасно.

Як я вже говорив: вершини під перспективною проекцією, що знаходяться за камерою, не мають сенсу.

Ви повинні реалізувати відсікання. Ви повинні виявити, коли за камерою знаходиться якась вершина трикутника у просторі кліпу ( перед поділом в перспективі). Якщо це так, то слід зафіксувати цей трикутник, генеруючи лише трикутники, які знаходяться перед камерою.

Це не простий процес. Він буде залучати математику, яка має сенс лише за умови повного розуміння однорідних систем координат. Крім того, ви можете просто випрямити будь-який трикутник, якщо якась вершина знаходиться за камерою.


До цих пір я скидав весь трикутник, але потім побачив через площину (див. Малюнки вище). Мені дуже потрібна картина, щоб зрозуміти, чому це геометрично не має сенсу. Єдине рішення - обчислити перетин площини на пряму, коли одна з вершин знаходиться за площиною відсікання, і використовувати це перетин, щоб простежити лінію від вершини, що знаходиться попереду, на жаль, це дорого.
Соленоїд

0

Якщо частина трикутника позаду найближчої площини ви могли б зробити перевірку на піксель, щоб побачити, чи знаходиться положення пікселя за площиною відсікання?

Ви можете ставитися до ближньої площини, як до будь-якої іншої плоскості відсікання. Наприклад, обрізні площини використовуються для таких речей, як водні літаки (для відбиття та заломлення). Я б подумав, що ця відсікаюча площина працюватиме так само, як і близька площина відсікання, і кліп на основі пікселя.

Я знаю, як обробляти відсічні площини в HLSL за допомогою DirectX, але їх реалізація може бути власницькою. Якщо ви можете отримати інформацію про це, це може бути корисним.

Окрім цього, тут є посилання, яке може допомогти вам: http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter42.html


За тестування пікселів надзвичайно дорого в інтерпретованій мові, як Javascript, зараз я отримую ледь прийнятний кадр в секунду.
Соленоїд
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.