Autor Wątek: OpenGL shader node editor  (Przeczytany 2281 razy)

Offline Dragomirus

  • Użytkownik

# Październik 25, 2017, 13:51:25
Witam,
od dłuższego czasu programuje swój silnik i parę razy podchodziłem do tematu, ale zawsze jakoś pojawiały się bardziej istotne rzeczy, ale w końcu zabrałem się za pisanie swojego własnego edytora materiałów (dodam tutaj, że wzoruje się na RedKicie, Unreal itd.). Cała część 2D jest już gotowa, eytor rysuje diagramy/nody (nie wiem do końca jak to się nazywa). Problem pojawił się jednak przy przetłumaczeniu tego wszystkiego na język GLSL i pojawiło mi się w głowie parę pytań:
1. Co z atrybutami wierzchołka? No właśnie. Są one generowane w zależności od tego co jest potrzebne w materiale? np. gdy mam nod o nazwie normal mapping to pojawia się w VAO atrybut bitangent, tangent.
2. Z tego co potrafiłem zrozumieć z innego edytora to vertex shader służy tutaj tylko do przekazywania zmiennych z silnika takich jak na przykład pora dnia, ale też innych rzeczy takich jak pozycja uv, normalne itd. do fragment shadera. Dobrze rozumiem?
3. Node takie jak: add, multiply, clamp są poprostu funkcjami glsl'a? Problem w tym czy jak robię noda add gdzie mam parametry A i B to czy w rezultacie tworzy się nowa zmienna, która jest wynikiem tego działania czy korzystam z już wcześniej użytych zmiennych.
4. Node takie jak: vector, scalar są po poprostu typami uniform, które ustalam dla konkretnego modelu i przekazuje je do fragment shadera?
5. No i ostatnie pytanie czy wszystko dzieje się tylko i wyłącznie we fragment shaderze? W sensie wszystkie te obliczenia w materiale na nodach są w nim robione?

Ogólnie to docenie każdą inforamcję jaką ktoś posiada na każdy temat tego typu edytora. Mile widziany jest też kod ze zdjęciem nodów jeżeli ktoś ma takowy. Z góry dzięki :)

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Brajanowski

  • Użytkownik

# Październik 25, 2017, 18:57:24
Zauważ, że większość tych edytorów to po prostu służą do wypełnienia wartości materiału PBR (diffuse, metalic, normal map itp). Ja bym po prostu od tego grapha wygenerował kod który by wypełniał strukturę danych o materiale.

1. modele i tak będą miały te wartości chyba, więc możesz zignorować bo problem chyba nie warty zachodu(???)
2. nie wiem, nie czaje
3. możesz ale możesz równie dobrze wygenerować jedno wielkie działanie (zooptymalizuj jak dodajesz dwa consty czy coś)
4. nie wiem
5. no chyba jo, bo we fragmencie liczysz kolor pixela po rasteryzacji czy jakoś tak i jak liczysz dla materiału to tam wszystko raczej bedzie.

Offline Dragomirus

  • Użytkownik

# Październik 25, 2017, 22:26:50
Czyli w sumie te atrybuty wierzchołka to są stałe w zależności czy jaki Output będzie? W sensie że jak będę robił materiał dla modelu to zawsze jest normal, pozycja, tangent, bitangent oraz UV a jak robię materiał na przykład dla post procesów to mam tylko w sumie pozycje i Uv?

Co do 2 to chodziło mi oto że w vertex shaderze przekazuję tylko wartości do fragment shaderze a niczego nie liczę.

Jeżeli chodzi o 4 to chodziło mi o takie zmienne jak shiness żeby później obliczyć specular w zależności od tego jaki przedmiot to jest.

No i finalne pytanie bo znalazłem w necie node editor z podglądem na kod. Jest tam coś takiego ze zawsze jest jeden Output i on tam właśnie ma już diffuse metal itd. I w kodzie wygląda to tak że są zmienne o nazwie diffuse metal itd. I mają on wartość zero jeżeli nie ma nodow. Outputem już we fragment shaderze jest suma diffuse metal etc. Tak że zawsze one mają sens bo albo wartość czegoś jest zero albo nie. I teraz pytanie czy jak zmienna diffuse jest 0 i jest ona w sumie to czy czasem glsl przy kompilacji shadera nie wywalić automatycznie tej zmiennej? W ogóle czy glsl czasem nie optymalizuje sobie sam kodu przed skompilowaniem? Wiem że ciężko tłumacze ale z góry dzięki :)

Offline Mergul

  • Użytkownik

  • +1
# Październik 26, 2017, 10:00:07
1. Struktura wierzchołka jest zależna od modelu, jezeli chcesz material ktory wykorzystuje kolory wierzcholkow, a model takowych nie posiada, to nie mozesz mu przypisac tego materialu. Materiał może Ci generowac kilka shaderów dla roznych typow obiektow i roznych ustawien weierzcholkow, a zqwsze wypluwac odpowiednie parametry (chodzu o vertex program i liczenie podstawowych rzeczy jak UV, normal)

2. Liczysz w vertex shaderze. Obliczenia w shaderze masz rohione za plecami zazwyczaj.  wkoncu musisz policzyc wektor do oka, albo normalna, czy pozycje przemnozyc macierza.

3. Mozesz tworzyc nowe zmienne. OGL i tak to zopytmalizuje w czasie kompilacji. Kiedys jak jeszcze istnialy zewnetrzne programy do optymalizacji kodu OGL to generowaly wiele zmiennych tymczasowych. Mozesz sobie zobaczyc chociazby AMD Shader Analyzer (czy jakos tak) i podgladac assembler. Wynik bedzie identyczny.

4. UE4 ma constant scalar i uniform scalar. Cosntant to po prostu zmienna w shaderze. A uniform jest dla materialu i przekazywana jest od materialu. Zeby to wartosc zmieniac w czasie rzeczywistym to maja chociazby MaterialInstance, czyli identyczny material, ale inne parametry.

5.W sumie to tak. Obliczenia w vetex sh zazwyczaj sa robione automatycznie, a Ty robiac materiał odczuwasz tak jakbys edytowal tylko kolory. Wyjatkiem sa momenty kiedy np. chcesz offset wierzcholkowi dac. Wtedy obliczenia dzieja sie w wierzcholkach. Zawsze mozesz zobic zeby mozna bylo bloczkami tez liczyc co per vertex :D To nie jest problem, chcesz, robisz.

GLSL wyrzuca te zmienne ktore nie sa uzywane do wyliczenia ostatecznego wyjscia. Czyli jak zmienna nie wplywa w zaden sposob na ostateczny kolor pixela to jest wyrzucana.

Offline Dragomirus

  • Użytkownik

# Październik 26, 2017, 13:27:55
Dobra chyba już mam wszystko co potrzebowałem do zrozumienia mechaniki takiego edytora i mogę pisać sam. Dzięki za odpowiedzi :)

Offline wezu

  • Użytkownik

# Październik 26, 2017, 15:46:35
O tym co GLSL wywala przy kompilacji decyduje driver, więc z tym może być różnie. Mój windowsowy driver od AMD nie widzi problemu gdy w vertex shaderze jest "out vec3 foobar;" a w fragment "in vec4 foobar;" jeśli 'foobar' nie jest nigdzie używany, ale ta same karta z driverami linuxowymi wywal się na tym samym shaderze nawet nie z ostrzeżeniem ale wręcz błędem (pewnie słusznie). Drivery od nvidi pozwalają (czasem) na używanie funkcji z Cg albo HLSL w shaderach GLSL. Na mobilkach przyjmuj, że nic nie jest optymalizowane. NIC.

Kiedyś było tak, że należało jak najwięcej obliczeń robić na vertex shaderze, bo zazwyczaj wierzchołków jest kilka - kilkaset tysięcy, a fragmentów miliony, ale teraz to nie zawsze jest lepsze - interpolacja i przekazywanie wartości może okazać się droższe niż policzenie wszystkiego per pixel.

Jeszcze taka ogólna uwaga - jeśli byś korzystasz z deferred shading z PBR, to cały system materiałów/shaderów robi się naprawdę prosty bo żonglujesz tylko kilkoma zmiennymi dla wszystkich możliwych materiałów.

 

Offline Mergul

  • Użytkownik

# Październik 26, 2017, 16:48:02
Jeżeli chodzi o to co wypluwa GLSL to pewne najprostsze optymalizacje możemy założyć ze robi... a ogólnie to jezeli hcesz zeby działało wszędzie to na każdym kroku możesz zostać zaskoczonym :D np. 1.0f jest jak najbardziej ok, chyba że odpalasz to na prockach mali na GLES 2.0 to Ci sypie jako błąd. Jeden kompilator Ci da tak a inny inaczej. Najlepiej trzymać sie standadu, a że to bywa cięzkie (bo cięzko znaleźć często informacje) to po prostu testować na każdym możliwym sprzęcie. NVIDIA jest najmniej wybredna (połowa błędów przejdzie i będzie działać).
Ja shadery trzymam w moim byte code z którego generuje odpowiedni shader w zależności od sprzętu.

Offline Dragomirus

  • Użytkownik

# Listopad 08, 2017, 18:23:00
Długo mnie nie było tutaj :P
Przede wszystkim mobilki pomijam bo zależy mi na fajnyche efektach graficznych, a wiem, że one tego nie pociągną. Poza tym w końcu zrobiłem tak, a raczej zrobię dzisiaj dopiero, że dodałem dodatkowe nody odpowiadające za atrubuty wierzchołków i tak mam: vertex color, normal, position, ale też takie rzeczy jak worldnormal itd. Ogólnie to buffer i atrybuty dopasowują się do nodów. Co do optymalizacji to raczej chodziło mi o sytuacje:

vec4 alala = vec4(1, 1, 1, 1);
vec4 alala2 = vec4(alala.xyz, 0);

Pytanie raczej było czy obie zmienne, które są używane w ciele fragment shadera znikną podczas kompilacji jeśli ich już nie używam w dalszej części kodu :).

Offline Mergul

  • Użytkownik

# Listopad 15, 2017, 19:21:56
Raczej tak. Jakiego kompilatora outputu nie sprawdzałem (mobilki też) to liczba zmiennych się nie liczy. Ważne są ich zależności. Z resztą tak jak pisałem, istniały kiedyś (jeszcze za czasów OGL 2) optymalizatory kodu GLSL, i generowały ogromną ilość śmieciowych zmiennych. Jeżeli tworzysz coś statycznie to wgl. wywali Ci to kompilator.

Offline Dragomirus

  • Użytkownik

# Listopad 24, 2017, 15:52:35
Dzieki wielkie za pomoc :). Chce wstawic screen z edytora bo prawie skonczony jest, ale cos nie moge sie zarejestrowac na stronie warsztatu. No nic jeszcze raz wielkie dzieki :)