За да разберете това, ще трябва да вземете предвид целия конвейер за изобразяване. Резултатите от върховия шейдър (освен специалния изход gl_Position
) се предават като „асоциирани данни“ на върха към следващите етапи в конвейера.
Докато върховият шейдър работи върху един връх наведнъж, без изобщо да се интересува от примитивите, следващите етапи на тръбопровода вземат предвид примитивен тип (и информация за свързване на върхове). Това обикновено се нарича "примитивно сглобяване". Сега все още имаме единичните върхове със свързаните данни, произведени от VS, но също така знаем кои върхове са групирани заедно, за да дефинират основен примитив като точка (1 връх), линия (2 върха) или триъгълник (3 върхове).
По време на растеризирането се генерират фрагменти за всяко местоположение на пиксел в изходния пикселен растер, който принадлежи на примитив. По този начин свързаните данни на върховете, дефиниращи примитив, могат да бъдат интерполирани в целия примитив. В линия това е доста просто: прави се линейна интерполация. Нека наречем крайните точки A и B с всяка асоцииран изходен вектор v, така че да имаме v_A и v_B. Отвъд линията получаваме интерполираната стойност за v като v(x)=(1-x) * v_A + x * v_B във всяка крайна точка, където x е в диапазона от 0 (в точка A) до 1 (в точка Б). За триъгълник се използва барицентрична интерполация между данните на всичките 3 върха. Така че, докато няма съпоставяне 1:1 между върховете и фрагментите, изходните данни на VS все още дефинират стойностите на съответния вход на FS, просто не по директен начин, а индиректно чрез интерполация през използвания примитивен тип.
Формулата, която дадох досега, е малко опростена. Всъщност по подразбиране се прилага корекция на перспектива, ефективно чрез модифициране на формулата по такъв начин, че да се вземат предвид ефектите на изкривяване на перспективата. Това просто означава, че интерполацията трябва да действа, тъй като се прилага линейно в пространството на обекта (преди да бъде приложено изкривяването от проекцията). Например, ако имате проекция в перспектива и някакъв примитив, който не е успореден на равнината на изображението, преминаването с 1 пиксел надясно в пространството на екрана означава преместване на променливо разстояние върху реалния обект, в зависимост от разстоянието на действителната точка до равнината на камерата.
Можете да деактивирате корекцията на перспективата, като използвате квалификатора noperspective
за променливите in
/out
в GLSL. След това се използва линейната/барицентрична интерполация, както я описах.
Можете също така да използвате квалификатора flat
, който ще деактивира изцяло интерполацията. В този случай стойността само на един връх (така наречения "провокиращ връх") се използва за всички фрагменти от целия примитив. Целочислените данни никога не могат автоматично да се интерполират от GL и трябва да бъдат квалифицирани като flat
, когато се изпращат към фрагментния шейдър.
person
derhass
schedule
04.02.2015