2011-01-12 11 views
5

W nowatorskich nowych wersjach OpenGL (3.0 i 4.0 w górę), wbudowane atrybuty wierzchołków, takie jak gl_Vertex, są uznawane za przestarzałe. "Nową metodą" renderowania czegokolwiek jest określenie własnych atrybutów wierzchołków dla pozycji, koloru itp., A następnie powiązanie tych niestandardowych atrybutów z buforami.W jaki sposób nowoczesne shadery OpenGL powinny być tak napisane, aby były ze sobą kompatybilne?

Moje pytanie brzmi: jak można to zrobić bez ścisłego powiązania kodu renderującego i modułu cieniującego? Jeśli piszę moduł cieniujący, który używa pozycji "pozycja" jako pozycji wierzchołka, kod hosta za pomocą modułu cieniującego musi to wiedzieć i przekazać dane werteksów jako "położenie". Jeśli chcę użyć innego modułu cieniującego, który został napisany w celu przechwytywania danych wierzchołków w "vertex_pos", muszę najpierw przepisać ten moduł cieniujący lub zmodyfikować mój kod hosta, aby zamiast tego wysyłać dane werteksów jako "vertex_pos".

Czy istnieje zestaw nazw najlepszych praktyk dla standardowych atrybutów wierzchołków i fragmentów, które powinny być używane przez wszystkie moduły cieniujące? Czy są tam bałkanizowane standardy specyficzne dla silnika, takie, że moduł cieniujący napisany dla jednego silnika nie może działać na innym bez modyfikacji? Czy też nie ma żadnych standardów, tak, że na ogół każdy obiekt potrzebuje własnego niestandardowego kodu renderującego, aby dopasować go do własnego shadera?

Odpowiedz

3

Po prostu nazywaj je starymi nazwami. Jeśli masz profil podstawowy (tzn. Brak kompatybilności wstecznej), zarezerwowane nazwy starszych specyfikacji GLSL są uznawane za nierozpoznawalne; uwalnia się od ; redeclaring ich do wiązania atrybutów vertex. Wydaje się, że zmieniasz ich atrybut dostępności. W profilu zgodności te nazwy zmiennych są wstępnie przydzielane i wiązane.

Sprowadza się to do tego, że zachowanie starej nazwy w modułach cieniujących jest wygodne i wydaje się działać z aktualnymi kompilatorami GLSL. Jeśli chcesz przejść bezpiecznie, użyj preprocesora do przepisania zarezerwowanych nazw prefiksu gl_ na własny prefiks i powiąż go.

+2

Właściwie to nie jest prawda. GLSL zastrzega ** dowolną ** nazwę zaczynającą się na "gl_". Jeśli główny kompilator pozwala na użycie "gl_Vertex", to nie jest zgodny ze specyfikacją. Specyfikacja 1.50 wyjaśnia, że ​​składnia redeclaration jest ważna tylko dla zmiany właściwości zadeklarowanego typu. Więc nie powinno ci pozwolić na ich redeclare. –

+0

@Nicol: Teraz zaczyna się lawiracja języka: Niektóre osoby mogą widzieć przestarzałe nazwy zmiennych jako predefiniowane identyfikatory z profilu zgodności, a używanie ich w programie GLSL 1.50 jest zmianą właściwości redeclaration; Specyfikacja IMHO nie jest do końca jasna, chociaż w punkcie "# version" wydaje się wskazywać, że rdzeń oznacza "Brak dostępnych nazw kompatybilności". Jeśli ktoś chce być bezpieczny, może użyć preprocesora '#define gl_Vertex glVertex' i użyć tej nazwy w profilu podstawowym. – datenwolf

1

Po pierwsze, aby odpowiedzieć na twoje pytanie. Nie jestem świadomy takiej standardowej konwencji nazewnictwa.

Ale ... jest to bardziej skomplikowane niż nazwy atrybutów. Ukryty pod pytaniem jest pojęcie semantyki atrybutów. Każdy z atrybutów wejściowych ma jakąś formę semantyki, której oczekuje każdy moduł cieniujący.

A czego nauczyłem się od nazw stałych gl_ jest to, że nie określają ich semantyki.

  • W której przestrzeni znajduje się gl_Position? (odpowiedź: całkowicie zależy od tego, co przekazał host. Silnik nie musi przechodzić w coś, co jest przestrzenią lokalną, np. jeśli przekształcił już to, ponieważ wymagał przestrzeni świata z różnych powodów).
  • to gl_TexCoord1 współrzędna tekstury, czy tak naprawdę, styczna? a co z jego zasięgiem? Czy jest zakodowany?

Nie jest jasne, czy można znaleźć konkretną nomenklaturę, która naprawdę rozwiązuje wszystkie te problemy, ale wymagałoby to kompatybilności różnych silników.

Bardziej problematyczne, nie jest nawet oczywiste, że określony silnik (lub konkretny zasób) miałby zdolność dostarczania określonych atrybutów wymaganych przez moduł cieniujący pochodzący z innego silnika. Co wtedy ?

To są wszystkie powody, dla których kończymy z bałkanizowanymi środowiskami cieniowania.

+0

Specyfikacja OpenGL jasno określa, co należy przekazać, a także zna mundury i atrybuty. Takie rzeczy, jak nadużywanie gl_TexCoord1 do określania stycznej, mają swój początek w czasach, gdy dostępne były tylko ograniczone atrybuty wierzchołków, a dane musiały być przekazywane innymi metodami. Dla danych wejściowych OpenGL 4 nie określa w ogóle żadnych nazw specjalnych, wszystkie są swobodnie nazwanymi atrybutami wierzchołków, ale oczywiście nazwy wyjściowe muszą być dobrze zdefiniowane. Heck, nawet standardowe matryce zostały usunięte, teraz wszystkie macierze muszą być określone przez uniformy. – datenwolf

+1

@datenwolf: Chodzi mi o to, że skoro tylko GL dostarcza shadery, semantyka danych wejściowych staje się obowiązkiem gospodarza, a nie GL. Dzieje się tak nawet wtedy, gdy używasz zmiennych gl_ * i nie dajesz żadnej gwarancji, że twój moduł cieniujący będzie działał na innym silniku, np. Widziałem shadery, które nie zużywają nawet Pozycji, mimo że wymaga się ich dostarczenia. – Bahbar

+0

Ta utrata semantyki powoduje, że rdzeń OpenGL-3/4 nie ma już wstępnie zdefiniowanych zmiennych wejściowych. Obsługuje tylko ogólne atrybuty wierzchołków i możesz je nazwać, jak chcesz. Shadery są w każdym razie powiązane z bazowym mechanizmem renderowania, ponieważ każda zaawansowana technika renderowania zależy od kilku przejść renderowania, które są kontrolowane przez silnik. A shadery muszą napisać, żeby pasowały do ​​tych przejść. – datenwolf

0

Zobacz mój numer question dla listy możliwych implementacji atrybutów/jednolitej semantyki. Obawiam się, że nawet w przypadku OpenGL 3.4 problem ten nie zostanie rozwiązany, a pozostawiasz dużo miejsca na własnych urządzeniach, aby zdefiniować kontrakt między shaderów a kodem.

Powiązane problemy