Лекция 9::Задача 0 (трудна)
- Forums:
Surface Area Heuristic
Споменахме, че има и по-добри подходи за избиране на оптимална разделяща равнина при стоежа на K-d дървото. Един от тях се нарича Surface Area Heuristic (SAH); той цели да отдели несиметрично разположени триъгълници (например, концентрирани в единия край на Bounding Box-а) от свободните пространства, като взима под внимание не само броя триъгълници във всяко подпространство, ами и относителната големина на подпространството. "Големината" определяме чрез площта на повърхнината на bounding box-a (т.е. при bounding box WxHxL, S = 2 * (W*H + W*L + H*L))
Формално, нещата изглеждат така: оценката f за единично пространство е:
f := costIntersect * numTriangles * surfaceArea,
докато, ако пространството разделим на две, цената е
f_split := costSplit + f(left) + f(right)
:= costSplit + costIntersect * numTrianglesLeft * surfaceAreaLeft + costIntersect * numTrianglesRight * surfaceAreaRight
където costSplit и costIntersect са относителните "цени" за, респективно, обхождане на възел от дървото, и за пресичане с възел. Jacco Bikker предлага 0.3 и 1.0, респективно.
Целта е да намерим разделяща равнина, която минимизира тази оценка (f_split). Това е една тежка оптимизационна задача, но можете да намерите приблизително решение чрез някой от следните два подхода:
1) Разделяте интервала между left и right краищата на BBox-а на равномерни подинтервали (например 20 стъпки) и пресмятате SAH в тези 20 позиции; накрая взимате най-добрата
2) Ползвате троично търсене между left и right (http://en.wikipedia.org/wiki/Ternary_search)
Като бонусче, можете да реализирате и termination критерия: ако f_split е по-голямо от f без значение каква разделяща равнина избираме, то най-добре да спрем дотук и да обявим възела за листо (повече детайли относно SAH има в статията на Jacco Bikker: http://devmaster.net/posts/raytracing-theory-implementation-part-7-kd-tr... (втората половина))
В ревизия 252 съм добавил и специална сцена с много тежък обект (станфордския дракон, 100 000 триъгълника). След като си изготвите прототипа върху meshes.fmiray и работи добре, ползвайте дракона за сравнения; при добре реализиран SAH трябва да постигнете ускорение между 10% и 30% в пресичането (строежа на дървото ще е доста по-бавен, но това не бива да ви притеснява).
Comments
Какво забавяне в строежа на
Какво забавяне в строежа на дървото е приемливо? Например ако render-time спада с 20%, но строежа на дървото отнема 10на пъти повече време?
Правилно ли съм разбрал от поставеното условие, че costSplit и costIntersect са константи със съответни стойности 0.3 и 1.0 ?
Няма проблем строежа на
Няма проблем строежа на дървото да отнема много повече време. Причината за което е, че можеш да увеличаваш резолюцията на която рендерираш, и, след даден момент, ползата от по-доброто дърво ще оправдае времето за строежа му.
Иначе да, ползвайте 0.3 и 1.0, можете да експериментирате и с други стойности, за да намерите оптимален вариант (въпреки че тези вършат добра работа).
А откъде мога да взема
А откъде мога да взема размерите на Bounding Box-а? И къде точно трябва да напиша алгоритъма? Предполагам, че трябва да е в build в mesh.h, но малко се изгубих в тази функция.
Аз лично взех размерите като
Аз лично взех размерите като разлика на vmax и vmin по всяко направление.
build е добро място за алгоритъма, но нищо не ти пречи да си направиш нова функция, в която да го реализираш и да я извикаш от buildKDTree вместо build.
Даже бих те посъветвал да направиш точно така (нова функция в класа Mesh), за да можеш лесно да сменяш между двата алгоритъма и да правиш сравнение кой колко време отнема и какви подобрения/забавяния се получават.
Благодаря!
Благодаря!
здрасти, аз пратих писмо с
Здрасти,
аз пратих писмо с въпрос, но още никой не ми е отговорил.
Имаш отговор (вече)
Имаш отговор (вече)