Що саме змушує поверхню перекриватися іншою?


10

Я не можу реально зрозуміти, що викликає перекриття однієї поверхні іншою. У 3D-двигуні, який я створюю, моя техніка виходить з ладу у кращих випадках.

Мій метод - сортування поверхонь, які слід пофарбувати, від найбільш віддалених до найближчих. Для визначення близькості я порівнюю середні значення z. Однак іноді поверхня, що перекривається, має більш високе середнє значення z, ніж перекриття. Таким чином, поверхня надалі зафарбована ближче - в результаті виходить химерне відображення так:

Великий фіолетовий квадрат із перерізом червоного кольору збоку

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

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

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

Відповіді:


11

Ви ніби намагаєтеся реалізувати Алгоритм живопису . Я здогадуюсь, що ви намагаєтесь записати растер з нуля як навчальну вправу, оскільки більшість сучасних апаратних засобів 3D використовують те, що згадував Барт (буфер Z / Depth). Щоб алгоритм художників працював у всіх випадках, вам потрібно бути готовим до розподілу поверхонь у міру їх вирішення для вирішення можливих сценаріїв (наприклад, проблема полігону, що перекривається, показана на сторінці Вікіпедії).

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

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


Ви правильно сказали, що я створюю простий рендер. Справа в тому, що я не використовую жодної 3D-бібліотеки. Я сам роблю всі розрахунки проекції, а потім малюю лінії за допомогою двовимірної бібліотеки малювання. Це не найшвидше, і я нічого не роблю на основі пікселя. У мене просто 4 точки кожної поверхні і заповнюють прямокутну форму кольором. Оскільки я малюю повну поверхню за один раз, чи я правильний, кажучи, що мені доводиться малювати назад спереду?
pimvdb

Звучить дуже весело та чудово. Повернення вперед - це ваш єдиний спосіб, якщо ви робите це без будь-якої форми глибини буфера. Я думаю, вам доведеться опрацювати всі координати екрана ваших полігонів, а потім перевірити наявність яких-небудь перекриттів. Там, де вони перекриваються по глибині, вам, можливо, знадобиться порубати багатокутники для візуалізації, щоб ви могли фактично вирішити сортування правильно. Можливо, ви також захочете розглянути "Назад обличчя" як спосіб видалення полігонів, які не обов'язково повинні бути видимими
Роджер Перкінс

Роджер Перкінс має рацію. Ви не зможете домогтися правильного z-сортування таким чином (тобто у вас завжди будуть крайові регістри), якщо ви не рубаєте багатокутники. Однак це може стати досить повільним.
bummzack

У мене це працює! Те, що я зробив, - це поєднання відсікання та сортування задньої поверхні: у суцільному кубі деякі грані не видно, а інші - максимум 3). Тому я намалював спочатку невидимі частини, а видимі - над ними. Це працює як шарм, якщо я видаляю одну або кілька сторін, вони перекриваються, але все ж малюються у правильному порядку. Дякую!
pimvdb

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

3

У вас є проблема видимості . Одне рішення - використання z-буфера .


Дякую, але буферизація z вимагає візуалізації за пікселем, якщо я не помиляюся. Я цього не роблю - я малюю прямі лінії між проектованими точками куба. Чи можливо ще буферизація z?
pimvdb

Навіть якщо ви малюєте прямі лінії, в якийсь момент, перш ніж зображення вийде на екран (або файл растрового зображення), воно буде в піксельному форматі.
Барт ван Хекелом

Це правильно, але моя бібліотека малюнків занадто повільна, щоб робити піксельне відображення з 20 кадрів в секунду. Спасибі, хоча.
pimvdb

2

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

Приклад (попередження, ASCII вперед):

          /
         /
cam     /
-->    / 
      /
     /--       <--B
    /
    ^--A

Є дві грані A і B. З точки зору камери A стоїть перед B. Однак середнє z-значення B менше. Давайте розглянемо інші z-значення:

  • мінімальне z-значення A дорівнює 4
  • максимальне z значення A дорівнює 11
  • тому середнє z значення A становить 7,5
  • мінімальне z-значення B дорівнює 6
  • максимальне z-значення B дорівнює 8
  • тому середнє z значення B становить 7

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

У алгоритмі Ньюелл http://en.wikipedia.org/wiki/N_Well's_algorithm , що ви робите, це сортування min / max-діапазонів z-значень. Якщо діапазони двох граней не збігаються, ви можете точно знати, яке з них знаходиться попереду. Якщо вони це роблять, іноді вам абсолютно доводиться розділяти обличчя. Іноді достатньо буде простежити кожну вершину для оклюзії чи іншої техніки.


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

1

Добре, що ви дізнаєтесь про візуалізацію, роблячи. Кудос. У цьому випадку не існує рішення "алгоритм малювання", замість того, щоб намагатися виправити його сортуванням, на PS1 ми використовували, щоб просто намагатися тримати багатокутники приблизно однакового розміру, коли вони були поруч (що ви робите як наскільки я можу сказати), і задню поверхню (що ви не робите)

Відкидання задніх поверхонь - це перевірка нормальної поверхні екранного простору на її напрямок (просто отримайте знак елемента глибини з простору екрану, перетвореного у звичайний (у нашому випадку це z нормального), або поперечний добуток двох векторів трикутник, тобто хрест (v1-v0, v2-v0))

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


Дякую за Вашу відповідь. Я читав про відсікання задньої поверхні, але справа в тому, що я хотів би мати можливість видалити одну сторону. З твердим кубом це може спрацювати чудово, але якщо я видаляю одну сторону, то відбувається окулісія - тому я все одно потребую їх сортування. У всякому разі, мені виникла ідея вистрілити промінь від джерела через середину поверхні. Якщо згодом цей промінь перетинає іншу поверхню, то перша поверхня перекривається другою. Не могли б ви сказати мені, чи правда ця ідея? Дякую!
pimvdb

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