Проблем с изрязване на правоъгълници с фрустум

Опитвам се да внедря отрязване на фрустума в моята OpenGL 2d игра. Единственият вид геометрични обекти в моята игра на този етап са правоъгълници, така че си помислих, че това ще бъде доста лесно, но получавам неочаквани резултати. Настроил съм симетрична перспективна проекция с ъгъл на зрително поле от 45 градуса и близки и далечни равнини съответно на 0,01 и 50. Векторът на окото винаги е успореден на оста z, камерата може да се движи само по осите x и y.

Идеята ми беше да получа правоъгълната област от световното пространство, която в момента е видима за камерата, в z-координатата на правоъгълника, който се опитвам да отсея. Тъй като камерата гледа към центъра на пресечения край, изчислявам разстоянието до краищата на тази видима правоъгълна област, както следва:

GLfloat maxDistance = givenRectangle.z * tanf(0.5 * (fovAngle * M_PI/180) );

След това добавям и изваждам това разстояние към и от координатите x и y на камерата, за да получа максималните и минималните видими x и y, и след това тествам дадения правоъгълник, за да видя дали е между тези стойности.

Въпросът ми е дали тук съм на прав път и защо горната формула връща абсурдно малка стойност (нещо*10^-37), когато имам обект при z=5, който трябва ясно да се вижда с камерата при ( 0,0,0)?


person Jacob    schedule 31.01.2011    source източник
comment
Да, технически имам само 2d правоъгълници в 3d перспектива, така че както искате да го наречете :) Причината, поради която искам перспективната проекция е, че искам да мога да увеличавам и намалявам, имам свят с ориентация на камерата отгоре надолу   -  person Jacob    schedule 31.01.2011
comment
бихте ли ми обяснили тази част, моля: След това добавям и изваждам това разстояние към и от координатите x и y на камерата, за да получа максималните и минималните видими x и y, и след това тествам дадения правоъгълник, за да видя дали е между тези стойности.   -  person jocelyn    schedule 23.01.2013


Отговори (1)


Вземам проблема отгоре, проверих вашата формула - вижте скицата, за да потвърдите, че съм ви разбрал правилно.

въведете описание на изображението тук

Като се има предвид, че знаем A и Z и искаме да решим X, първо написах:

tan(A) = X/Z

пренареждам, получавам:

X = Z tan(A)

Тъй като Z = 5 и A = 22,5 градуса...

X = 5* тен (22,5 градуса)

X = 2.07106781

И така, изглежда, че сте изчислили правилно, но кодът ви е грешен – може би функцията ви за тен очаква градуси, а не радиани, или fovAngle не е зададен? Мисля, че трябва да отстраните грешки и да проверите ръчно всяка стойност.


Връщайки се към по-широкия проблем да разберете какво се крие във вашия фрустум и какво не, може да откриете, че можете да използвате различен тест, за да отговорите на същия въпрос по-елегантно. Много графични програмисти използват тест "от страната на равнината". Помислете, че вашият фрустум за гледане е обем от пространство, ограничено от набор от 6 равнини (4 за страните на прозореца за изглед, близка изрязваща равнина и далечна изрязваща равнина).

Дадена е точка на равнина и нормала за равнината, можете доста лесно да изчислите уравнението на равнина, което от своя страна прави тривиално тестването дали дадена точка е "вътре" (по посока на нормалата) в дадена равнина. Преминете през всичките 6 равнини и бързо ще управлявате дадена точка във или извън обема на гледане.

Наистина хубавото в този тест е колко лесно можете да го използвате повторно: всеки прост изпъкнал многоъгълник, върху който случайно искате да направите тестове (напр. правоъгълник), може да бъде описан като набор от равнини, което ви позволява да използвате повторно вашите "вътрешен или външен" тест. Много общо.

person Community    schedule 04.03.2011
comment
Благодаря ви за отговора, наистина това имах предвид. Също така разбрах какъв е проблемът: това беше нещо с двоен указател към fovAngle, което не работеше правилно в моя конкретен код... Един въпрос относно вашия начин на отрязване на фрустум: прав ли съм, като подозирам, че този по-общ подход е по-бавен за прости правоъгълници от метода, който описах? - person Jacob; 06.03.2011
comment
Радвам се, че открихте грешката, звучи като разочароващо. Да, методът със самолети със сигурност ще бъде по-бавен. Може да ви спести усилия за разработка на някакъв етап, но с вашата конкретна ситуация може да е прекалено. - person Edward Dixon; 07.03.2011
comment
Говорейки за скорост, ако така или иначе пишете 2D игра и наистина искате да дадете всичко от себе си за производителност, помислете дали да не използвате перспектива. Ако вместо това използвате ортографска проекция, вашият тест за правоъгълник в екрана отново ще бъде по-прост, 0 ‹ x ‹ screen_width. - person Edward Dixon; 07.03.2011
comment
Ако искате да можете да намалите мащаба на сцената и да видите дали обектът се вижда или не, имате нужда от тази техника, дори в 2d! - person jocelyn; 22.01.2013