Mam klasę, która generuje kształt 3D na podstawie danych wejściowych z kodu wywołującego. Dane wejściowe to między innymi długość, głębokość, łuk itp. Mój kod doskonale generuje geometrię, jednak mam problemy z obliczaniem normalnych powierzchni. Po zapaleniu mój kształt ma bardzo dziwne zabarwienie / teksturę z niepoprawnych obliczanych normalnych powierzchni. Ze wszystkich moich badań uważam, że moja matematyka jest poprawna, wydaje się, że coś jest nie tak z moją techniką lub metodą.
Jak na wysokim poziomie można programowo obliczyć normalne powierzchnie dla wygenerowanego kształtu? Używam Swift / SceneKit na iOS do mojego kodu, ale ogólna odpowiedź jest w porządku.
Mam dwie tablice reprezentujące mój kształt. Jednym z nich jest tablica punktów 3D reprezentująca wierzchołki tworzące kształt. Druga tablica to lista indeksów pierwszej tablicy, która odwzorowuje wierzchołki na trójkąty. Muszę wziąć te dane i wygenerować 3. tablicę, która jest zestawem normalnych powierzchni, które pomagają w oświetleniu kształtu. (patrz SCNGeometrySourceSemanticNormal
w SceneKit` )
Lista wierzchołków i indeksów jest zawsze różna w zależności od danych wejściowych do klasy, więc nie mogę wstępnie obliczyć ani zakodować na stałe normalnych powierzchni.
Odpowiedzi:
Po prostu nie chcesz w pełni płynnych wyników. Chociaż metoda skomentowana przez Nathana Reeda: „Oblicz każdy wierzchołek, aby stawić czoła normalnej wartości, zsumuj je, normalizuj sumę”, na ogół działa ona czasami niestety spektakularnie. Ale to nie ma tutaj znaczenia, możemy użyć tej metody, dodając do niej klauzulę odrzucenia.
W takim przypadku po prostu chcesz, aby niektóre części nie były wygładzane względem niektórych innych części. Chcesz selektywne twarde krawędzie. Na przykład płaski górny i dolny element są oddzielone od trójkątnego paska z boku, podobnie jak każdy płaski obszar.
Zdjęcie 1 : pożądany wynik.
W efekcie chcesz tylko uśrednić wierzchołki zakrzywionego obszaru, a wszyscy inni mogą użyć normalnej wartości, którą same tworzą z trójkąta. Lepiej więc myśleć o siatce jako o 9 oddzielnych regionach, które są obsługiwane bez innych.
Zdjęcie 2 : Obraz przedstawiający strukturę siatki i normalne.
Z pewnością można to automatycznie wywnioskować, nie uwzględniając normalnych, które znajdują się poza pewnym kątem od podstawowych wierzchołków normalnych. Pseudo kod:
To działa, ale możesz po prostu tego uniknąć podczas tworzenia, ponieważ rozumiesz, że oddzielne płaszczyzny działają inaczej. Więc tylko zakrzywione boki wymagają normalnego połączenia kierunku. W rzeczywistości możesz po prostu bezpośrednio obliczyć je na podstawie matematycznego kształtu.
źródło
Widzę głównie trzy sposoby obliczania normalnych dla wygenerowanego kształtu.
Normy analityczne
W niektórych przypadkach masz wystarczającą ilość informacji o powierzchni, aby wygenerować normalne. Na przykład normalność dowolnego punktu na kuli jest łatwa do obliczenia. Mówiąc prościej, kiedy znasz pochodną funkcji, znasz również normalną.
Jeśli twój przypadek jest wystarczająco wąski, abyś mógł użyć norm analitycznych, prawdopodobnie zapewnią najlepszy wynik pod względem precyzji. Technika nie skaluje się jednak zbyt dobrze: jeśli musisz także obsługiwać przypadki, w których nie możesz użyć normalnych analitów, łatwiej jest zachować technikę, która obsługuje ogólny przypadek i całkowicie upuścić analityczną.
Normalne wierzchołki
Iloczyn krzyżowy dwóch wektorów daje wektor prostopadły do płaszczyzny, do której należą. Tak więc uzyskanie normalności trójkąta jest proste:
Ponadto w powyższym przykładzie długość produktu krzyżowego jest proporcjonalna do obszaru wewnątrz abc . Tak więc wygładzoną normalną w wierzchołku współdzielonym przez kilka trójkątów można obliczyć, sumując iloczyny krzyżowe i normalizując jako ostatni krok, ważąc w ten sposób każdy trójkąt jego obszarem.
Jeśli pracujesz z quadami, możesz skorzystać z fajnej sztuczki: dla quada abcd , użyj
crossProduct(c - a, d - b)
i poradzi sobie dobrze w przypadkach, w których quad jest w rzeczywistości trójkątem.Iñigo quilez napisał kilka krótkich artykułów na ten temat: sprytną normalizację siatki oraz normalną i powierzchnię wielokątów .
Normalne z częściowych pochodnych
Normalne można obliczyć w module cieniującym fragmenty z pochodnych cząstkowych. Matematyka z tyłu jest taka sama, z tym wyjątkiem, że odbywa się to w przestrzeni ekranu. W tym artykule Angelo Pesce opisano technikę: Normalne bez normalnych .
źródło