Autor Wątek: Łączenie światła z materiałami  (Przeczytany 2523 razy)

Offline BEZIMENNY45645

  • Użytkownik

# Lipiec 04, 2012, 16:54:13
Mam jeszcze pytanie może nie do końca związane z wątkiem. Tyczy się ono łączenia światła z materiałami. Czy możecie mi powiedzieć jakim to robicie sposobem? Przeszukiwałem wczoraj całe forum warsztatu w poszukiwaniu na to odpowiedzi ale nie znalazłem. Sorry jeszcze raz za offtopic,ale nie chce robić bałaganu na forum.

Offline Mr. Spam

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

Offline quaikohc

  • Użytkownik

# Lipiec 04, 2012, 17:35:57
co masz dokładnie na myśli? to w jaki sposób światła łączą się z materiałami definiuje wybrany model oświetlenia,  w uproszczeniu: każde światło jest określane przez jego intensywność która może być podzielona na: diffuse ambient specular (+ jeszcze na rgb) , komponenty te reprezentują ilość  wyemitowanego świała, materiały też określane są przez takie komponenty, ale definiują one ilość odbitego światła, w najprostszej formie są one przez siebie mnożone

Offline BEZIMENNY45645

  • Użytkownik

# Lipiec 04, 2012, 18:08:00
Tak to wiem,ale chodzi mi o to że mam np. wyrenderować siatkę z normal mapą. I mam shadery Normal Mappingu i np. oświetlenia punktowego. I jak to połączyć w jeden efekt nie mieszając tych shaderów. Znaczy nie modyfikować ich w żaden sposób.

Offline Interceptor

  • Użytkownik

# Lipiec 04, 2012, 18:20:58
Cytuj
pixelColor= Ambient + (Diffuse + Specular) * Shadow ( but let's forget about shadow).


Ambient = ambientMaterial * ambientLight


Diffuse = diffuseMaterial * diffuseLight * lamberFactor
lamberFactor = max (dot (lightVec, normal), 0.0)

Specular = specularMaterial * specularLight * speculatCoef
speculatCoef = pow (max (dot (halfVec, normal), 0.0), shininess)

Wiecej tutaj: http://fabiensanglard.net/bumpMapping/index.php

Offline quaikohc

  • Użytkownik

# Lipiec 04, 2012, 18:22:03
oświetlenie jest ściśle powiązane z materiałem, czemu chciałbyś to rozdzielać? shader od światła musi uwzględniać materiał,  możesz jedynie rozdzielić geometrię  od świateł stosując deferred shading, ale chyba nie o to Ci chodzi

Offline mihu

  • Użytkownik
    • mihu

  • +1
# Lipiec 04, 2012, 18:36:19
Problem ogólnie tyczy się nie tylko połączenia światła-materiał, ale wszelkich elementów obliczeń, które można chcieć usunąć/podmienić w zależności od oczekiwanego efektu. Jest kilka sposobów i żaden pewnie nie jest idealny.

1. Jeżeli masz tylko kilka możliwych kombinacji, możesz je zahardkodować w kilku shaderach, ewentualnie delegując, na tyle, na ile to możliwe, powtarzające się fragmenty obliczeń do osobnych funkcji. Funkcje można dla wygody zamieścić w jednym pliku, który będzie includowany przez pliki z konkretnymi shaderami.

2. Tzw. uber-shader - jeden duży shader obsługujący wszystkie możliwości. Wyłączenie lub wybór kawałka kodu może być wykonany przez
- dynamic branching (zwykłe instrukcje warunkowe)
- static branching (warunki typu if(flag), gdzie flag jest zmienną globalną typu bool shadera. W takiej sytuacji GPU (nie wiem czy zawsze) tworzy potajemnie osobny shader i wycina niepotrzebne kawałki kodu. Tutaj nie daję głowy za informacje, bo o SB kiedyś szukałem dość długo dokładnych informacji, ale znalazłem wiele sprzecznych. Chyba nie warto na tym polegać
- #ifdefy na wszystkie "włączalne" kawałki kodu, #define ustawiane z poziomu CPU przed kompilacją shadera, shader kompilowany z różnymi ustawieniami tyle razy, ile kombinacji potrzeba

Różne metody mają różne charakterystyki wydajnościowe. W metodzie 1. jest tylko jeden shader, ale w kodzie pozostają instrukcje warunkowe. W trzeciej metodzie shaderów jest wiele (częstsze zmiany shaderów podczas renderingu), ale nie zawierają zbędnego kodu.

3. Metody typu http://www.shawnhargreaves.com/hlsl_fragments/hlsl_fragments.html, gdzie każda "funkcjonalność", np. właśnie pobieranie wektora normalnego z tekstury, to oddzielny kawałek kodu z dokładnie zdefiniowanym wejściem i wyjściem, zapisywanym na ogół w jakichś metadanych. Fragmenty są na podstawie pożądanej kombinacji efektów łączone w jeden shader. Do tego zwykle trzeba napisać jakiś prosty parser, który nie tylko czyta metadane, ale też na przykład podmienia w łączonych kawałkach kodu wystąpienia jakichś zmiennych (np. jeśli kawałki kodu skleja się jako ciąg instrukcji w jednej funkcji, a nie każdy w osobnych funkcjach, to może się zdarzyć że wiele zmiennych o takiej samej nazwie znajdzie się w jednym zakresie widoczności - trzeba wtedy przerobić ich nazwy na unikalne).


Dodatkowo w deferred shadingu kod świateł i materiałów jest automatycznie rozdzielony, ale to nie jest rozwiązanie powyższego problemu, tylko naturalny efekt uboczny metody, która ogranicza różnorodność materiałów w silniku.

Offline Krzysiek K.

  • Moderator
    • DevKK.net

# Lipiec 04, 2012, 19:31:20
Cytuj
I jak to połączyć w jeden efekt nie mieszając tych shaderów.
Niech zgadnę? Masz dwa shadery ściągnięte z sieci, których nie rozumiesz i które chcesz połączyć ze sobą tak, żeby się nie narobić? ;)

Offline BEZIMENNY45645

  • Użytkownik

# Lipiec 04, 2012, 22:13:36
Nie shadery pisałem sam,jak chcesz to mogę ci przekopiować kod i opisać dokładnie co w nim robię. I napisać efekt podobny,ale inaczej działający. Nie jestem gościem,który kopiuje kody z internetu. Dzięki wszystkim za odpowiedź,dokładnie przejrzę to wszystko jutro,bo dzisiaj jestem padnięty.

Offline Krzysiek K.

  • Moderator
    • DevKK.net

# Lipiec 04, 2012, 22:32:43
Bez modyfikacji shaderów się nie obejdzie - musisz po prostu połączyć te dwa efekty w kodzie. Zastanawia mnie tylko, jak zrobiłeś normalmapping bez oświetlenia. :)

Offline BEZIMENNY45645

  • Użytkownik

# Lipiec 05, 2012, 11:03:28
Normal mappingu jeszcze nie zrobiłem,ale podałem to jako przykład,bo chciałbym zrobić jakiś elastyczny system materiałów,który pozwalał by mi na robienie takich rzeczy jak podany normal mapping. Teraz będę robił jakąś proste mapowanie tekstur,ale nie chce za np. miesiąc przepisywać całego systemu materiałów,bo wcześniej o tym nie pomyślałem. Chyba zastosuje ten efekt 3 co podał mihu,bo on najbardziej by mi odpowiadał, ponieważ jest dość elastyczny.

Offline quaikohc

  • Użytkownik

# Lipiec 05, 2012, 11:11:15
dobra strategia : zaczynanie od najcięższej i najbardziej czasochłonnej do zaimplementowania metody, której jestem pewien, że nie potrzebujesz

Offline Krzysiek K.

  • Moderator
    • DevKK.net

# Lipiec 05, 2012, 12:23:32
Cytuj
ale nie chce za np. miesiąc przepisywać całego systemu materiałów,bo wcześniej o tym nie pomyślałem.
Znam tylko Jedną Osobę (chociaż coprawda w trzech) która jest wszechwiedząca i to nie jesteś Ty. Nie jesteś w stanie pomyśleć o wszystkim, bo i tak później coś wyskoczy czego nie przewidzałeś.

Jak dla mnie, to najlepszym podejściem do małych, średnich i sporych produkcji jest założyć jeden system materiałów (diffuse+normalmap+specular map), ew. z niewielkim zbiorem opcji (emissive, alpha test). Możesz się bawić w wielkie możliwości, ale tego i tak pewnie nie wykorzystasz.

Offline BEZIMENNY45645

  • Użytkownik

# Lipiec 05, 2012, 14:17:39
Myślałem o tym,żeby napisać na razie kilka prostych materiałów,a dopiero później go rozwinąć do jakiegoś poważniejszego menedżera,tylko teraz chciałem jako takie podłoże pod to zrobić,i właśnie po to zadałem to pytanie o materiałach na forum. Dobra dzięki za wszystkie odpowiedzi. Jak uda mi się coś lepszego stworzyć do mojego silniczka to wrzucę to na warsztat.Jeszcze raz dzięki.

Offline BEZIMENNY45645

  • Użytkownik

# Lipiec 07, 2012, 17:32:59
Zrobiłem tak jak napisałem tylko nastąpił pewien problem. Materiał ze światłem renderuję za pomocą multi-passu. W jednym sampluje teksturę,a w drugim liczę oświetlenie. I tu następuje problem. Gdy sampluje teksturę z oświetleniem pokazuje się tak jak na screenie.(Nie zwracajcie uwagi na kolor,bo zmieniałem wartości kilka razy i nie ma to nic z tym wspólnego)



Tutaj Piksel Shader w przebiegu łączącym. Dodam że przy oddalaniu kamerą te figury tak jakby rozjeżdzają się i zjeżdżają.
Texture2D light : register(t0);
Texture2D diffuse : register(t1);

SamplerState sampLinear : register(s0);


struct PS_INPUT
{
float4 pos : SV_POSITION;
float2 tex : TEXCOORD0;
};

float4 PS(PS_INPUT input) : SV_TARGET
{
    float4 l= light.Sample(sampLinear,input.tex);
    float4 d = diffuse.Sample(sampLinear,input.tex);
    return l;
}


Mam nadzieję,że podpowiecie mi w którym kierunku szukać,bo już 2 dni siedzę i nie wymyśliłem,próbowałem odpalać PIXEM i nic interesującego nie znalazłem.

Offline Veldrin

  • Użytkownik

# Lipiec 07, 2012, 18:57:22
A tak btw to czym jest normal mapping jak nie konkretnym rodzajem materiału?

Materiał obiektu można opisać zestawem parametrów, zdefiniować wybrany model oświetlenia i rozszerzać o zestaw parametrów jak dodatkowe tekstury/właściwości. To dość generyczna struktura(do projektowania przynajmniej).

Ja u siebie określiłem pewny zestaw bazowych parametrów oraz możliwość rozszerzania o kolejne inty/floaty/tekstury. No i zestaw parametrów + shader + callback aktualizacji parametrów po stronie CPU tworzył zgrabny system.