2012-01-14 22 views
8

Próbuję po raz pierwszy przekazać wartość boolowską do mojego modułu cieniującego wierzchołków; Do tej pory używam tylko floatów.OpenGL ES (2.0) Język cieniowania: Jak wprowadzić boolean do vertex shader i przejść do shadera fragmentów?

Dana boolean jest prymitywna, więc nie można jej przekazać jako jednolitej. Jednak ma tę samą wartość dla wszystkich wierzchołków danego prymitywu.

Z "Khronos spec" wynika, że ​​"zmiana" jest jedynym sposobem przekazania danych do modułu cieniującego fragmentu, ale nic dziwnego, że deklaruje "zmienny bool my_bool;" powoduje błąd analizatora składni, gdy jest zdefiniowany w moim procesorze wierzchołków.

Jestem przekazując logiczną do mojego vertex shader jak:

attribute bool a_my_bool; 

zdefiniować zmienną, próbując przejść do modułu cieniującego fragmentu:

varying bool v_my_bool; 
void main() { 
    // ... 
    v_my_bool = a_my_bool; 
} 

Czy ktoś mógłby mi powiedzieć, jak Mogę osiągnąć to, co zamierzam?

Odpowiedz

12

Od §4.3.5 z The OpenGL® ES Shading Language version 1.0.17 (PDF):

Zmienny kwalifikator może być używany tylko z typami danych float, vec2, vec3, vec4, mat2, mat3 i mat4 lub tablice z nich.

I od §4.3.3:

Kwalifikator atrybut może być używany tylko z typów danych float, vec2, vec3, vec4, mat2, mat3 i mat4. Zmiennych atrybutu nie można zadeklarować jako tablic lub struktur .

Więc nie można mieć attribute bool, nie mówiąc już o varying bool według spec.

Jeśli naprawdę potrzebujesz wartości boolowskiej dla każdego wierzchołka, możesz użyć 0.0 dla fałszu i 1.0 dla prawdziwej. Podczas testowania sprawdź pod kątem x > 0.5.np .:

// vertex shader 
attribute float a_my_bool; 
varying float v_my_bool; 
void main() { 
    // ... 
    v_my_bool = a_my_bool; 
} 

// fragment shader 
varying float v_my_bool; 
void main() { 
    if (v_my_bool > 0.5) { 
     // my_bool is true 
     // ... 
    } else { 
     // my_bool is false 
     // ... 
    } 
} 

Dopóki wszystkie wierzchołki w każdym trójkącie mają tę samą wartość, powinno to działać. Jeśli nie są spójne, otrzymasz różne fragmenty tego samego trójkąta, który zachowuje się inaczej. (Jeśli przylegasz do 0,0 i 1,0, ćwiartka trójkąta najbliższego "dziwnemu" kątowi będzie zachowywać się inaczej od reszty.)

3

Gorąco radzę, aby nie używać tego atrybutu i przełączać go na uniformy, nawet jeśli boolean jest dołączony do danego prymitywu. W Uniformie ustawisz go raz i użyjesz wiele razy, z atrybutem zwiększysz dużo przepustowości pamięci wymaganej w każdym losowaniu. Jedyny sens, jaki widzę w tym przypadku, polega na tym, że wykonujesz ekstremalne grupowanie swoich prymityków, ale nawet w takim przypadku rzeczywiste korzyści tego rozwiązania muszą być ostrożnie oszacowane, ponieważ ryzyko polega na uzyskaniu odwrotnego efektu.

O różnych zmiennych, jeden Częstym błędem jest nie deklarować zmienne w obu cieniowania wierzchołków i fragmentów i brakuje jednego z 2.

mogłoby to budzić łączącego błąd i chcesz go zauważyć w każdym razie poprzez sprawdzenie kompilacji i łączenie wyników.

Innym aspektem, który chciałbym sprawdzić na miejscu jest upewnienie się, że zmienne są przypisane i użyte w kodzie, ponieważ kompilator usuwa nieużywane treści (optymalizacja martwego kodu), co powoduje bardzo częsty problem.

Powiązane problemy