Лекция 10::Задача 3

Петоъгълно боке

При сегашната реализация на DOF ефекта, една разфокусирана точка ще се размаже до кръгло петънце. В действителност, при истински фотоапарат, това ще се получи само ако обектива е отворен на най-широка апертура (т.е. на най-ниско f-число). В момента, в който увеличим f-числото, диафрагмата ще свие апертурата до по-тясна. Обикновено, диафрагмата във фотообективите представлява механизъм с определен брой остриета (5-6 за евтините обективи и до 12 за професионалните telephoto обективи). При тях апертурата добива формата на правилен многоъгълник. Така и точките извън фокус вече добиват формата на апертурата (ето пример, а тук има и с шестоъгълници). Изобщо, рисунъка на един обектив в областите извън фокус се нарича "боке". При обектив с 5 остриета на диафрагмата, се получава характерното "петоъгълно боке". Ще искаме да го имитираме (достатъчно е просто да променим формата на нашата "апертура", т.е. областта, от която генерираме начални точки за DOF лъчите).

Въведете целочислен параметър "diaphragmBlades" на камерата (по подразбиране да е 0). Ако diaphragmBlades e под 3, ползвайте досегашния алгоритъм. Ако е 3 или повече, трябва случайните числа u и v в getDOFRay() да се генерират в правилен многоъгълник (с diaphragmBlades страни), вместо в кръг. Въведете функция getNGonPoint(int numSides), която прави това (генерира случайна двумерна точка в правилен многоъгълник с радиус 1).

Тъй като задачата ви е лека в сравнение с на останалите, имате допълнително изискване: генерирането на точките да бъде "умно" - да ползва не повече от 3 извиквания на randomFloat()/rand() функциите, и да не ползва "отхвърляне" (например, генерирате в кръг, и ако е извън многоъгълника който искаме, генерирате нова и т.н.). Освен това внимавайте точките да са равномерно разпределени.

В data/hw10/task3.fmiray има тестова сцена, в която три шарени светлини са сложени на заден план и се появяват като добре видимо боке. Ако сложите diaphragmBlades да бъдат 5, резултатът трябва да изглежда нещо подобно: пример
(този рендер е с голям брой DOF семпли; ако ползвате настройки на сцената, както са в момента в SVN, нормално е да има доста шум (включително и "дупки") в петната на лампите)

Comments

Може ли малко хелп немога да

Може ли малко хелп немога да разбера първо как u и v в оригиналния код се дефинират в кръг (немогах да присъствам на лекцията а нещо не разбрах по кода)

Функцията random2DVector

Функцията random2DVector генерира u и v (т.е. тя реално генерира 3д вектор, но третия компонент е 0, само първите два са от значение).
Идеята за случайна точка в кръга е следната:
Избираме си случаен ъгъл от 0 до 2 пи
Избираме си случаен радиус от 0 до 1.
Крайната точка получаваме като завъртим точката (sqrt(r), 0) на избрания ъгъл.
Нуждата от коренуване се обяснява по следният начин: искаме да променим разпределението на случайната величина за радиуса, така че по-големите радиуси да се падат по-често. Това е така, защото вероятността дадена равномерно-разпределена случайна точка да е с точно определен радиус е пропорционална на обиколката на окръжността с този радиус. Иначе казано, ако за даден радиус r вероятността случайната точка да е с този радиус означим с P, то за радиус 2r вероятността трябва да е 2*P.
Коренуването прави точно това - изравнява вероятностите. Така генерирана, точката ще е равномерно разпределена в единичния кръг.

getNGonPoint(int numSides)

Може ли да дадете малко подсказка за генерирането на точка в правилен многоъгълник. След като си генерираме точка в единичния кръг, как да проверим дали точката е и в многоъгълника, като ъглите му не са фиксирани?

В условието съм казал изрично

В условието съм казал изрично да не го правите по този начин. Трябва да измислите схема, в която нямате "изхвърляне" на случайни точки, ако "не стават". Алгоритъма трябва да е така направен, че директно да генерира точките вътре в многоъгълника.

Hint: изберете си един случаен триъгълник от многоъгълника и генерирайте случайна точка вътре в него (сложното в задачата е само как да генерирате равномерни случайни точки в триъгълник. Ако се затрудните с това, пишете да дам още hintчета).

Заб: многоъгълника не е фиксиран, но просто си изберете някакъв начин да го фиксирате. Например, като осигурите, че единия му връх е (1, 0).

Ако може бих искала 2-ри hint

Ако може бих искала 2-ри hint и за триъгълника какви координати да използваме .. пак ли нещо случайно избрано.. или става по друг начин отново..?

Не, тук е по-лесно. Ползваш

Не, тук е по-лесно. Ползваш барицентрични координати, като генерираш двете числа по нормален начин (с randomFloat()). Виж лекция 7 за подробности. Има само една лека спънка, че сбора от барицентричните координати може да е невалиден (т.е. да е над 1). Тук трябва да измислите някаква хитра схема, която решава този проблем, без допълнителни извиквания на randomFloat().