Jak malować na modelach 3D

Sep 17 2020

Przeszukiwałem ten temat bardzo długo i praktycznie nie znalazłem żadnych informacji na jego temat.

Jeśli mamy model 3d z układem uv. Jaka jest podstawowa technika malowania 3d na wspomnianym modelu pędzlem? Pociągnięcie pędzla składa się z danych / obrazu pikseli pędzla ułożonych po kolei. Czy zatem rzutujemy każdy pojedynczy obraz pędzla na powierzchnię obiektu? (Chociaż w rzeczywistości, aby to zrobić, zamiast tego rzutowalibyśmy obiekt na przestrzeń obrazu). Wcześniej udało mi się rzutować tekstury na obiekty. Rzutowanie każdego pojedynczego pędzla zdecydowanie wydaje się wykonalne, ale nie jestem pewien, czy jest to praktyczne z punktu widzenia wydajności i czy istnieją lepsze techniki.

Odpowiedzi

1 wychmaster Sep 18 2020 at 15:18

Nie mogę podać "lepszego" podejścia, ale myślę, że podejście do

rzutować każdy pojedynczy obraz pędzla na powierzchnię obiektu

nie jest tak naprawdę problemem wydajności, jeśli zaimplementujesz to za pomocą GPU. Zwłaszcza w środowisku edytorskim, w którym niewiele się dzieje w porównaniu z grą komputerową. Wszystko, co zasadniczo chcesz zrobić, to renderować pojedynczy obraz na klatkę na ograniczonym zestawie tekstur. Mogę dać ci szkic tego, jak podszedłbym do tematu, gdybym potrzebował tej funkcji. Ponieważ jednak nie wdrożyłem go jeszcze samodzielnie, mogą wystąpić pewne komplikacje i problemy, o których nie pomyślałem, więc daj mi znać w komentarzach, jeśli coś nie działa zgodnie z oczekiwaniami.

  1. Znajdź dotknięte powierzchnie

    • Użyj rogów tekstury pędzla i wygeneruj zmniejszoną ściętą projekcję pędzla
    • Sprawdź wszystkie obiekty względem niego i znajdź najbliższe powierzchnie -> Jeśli już używasz jakiegoś rodzaju uboju w swojej scenie, użyj ponownie już usuniętej listy obiektów, ponieważ pędzel może tylko „zobaczyć” to, co widzi kamera
    • Zidentyfikuj podpowierzchnie / trójkąty, na które działa pędzel
  2. Zbierz wszystkie tekstury, których to dotyczy. Powinieneś wiedzieć dla każdej powierzchni, na którą ma to wpływ, jaką posiada teksturę. Optymalnie cały obiekt ma tylko jedną teksturę UV.

  3. Utwórz program cieniujący, aby renderować teksturę.

    • uważaj, Vertex Shader musi obliczyć znormalizowane współrzędne UV i przekazać je w dół potoku jako położenie wierzchołka, ponieważ są one pozycją w twojej teksturze. Sprawdź, jakich dodatkowych informacji potrzebujesz, aby przekazać potok.
    • W Fragment Shader zastąp każdy piksel znajdujący się pod pędzlem. W przypadku pędzli innych niż prostokątne może być konieczne użycie mieszania.
    • Pozycja szczotki jest trochę trudna. Potrzebujesz go w przestrzeni UV tekstur w Fragment Shader i nie jestem pewien, czy możesz to obliczyć w Vertex Shader. Więc może być konieczne zrobienie tego w Fragment Shader lub alternatywnie w Geometry Shader. Problem, który widzę, polega na tym, że kąt, pod jakim rzut pędzla uderza w powierzchnię, nie może być obliczony w Vertex Shader i konieczne jest określenie pokrytego obszaru. Geometry Shader ma wystarczającą ilość informacji, aby obliczyć kąt i pokryty obszar. W Fragment Shader również nie możesz obliczyć kąta, ale tam możesz po prostu sprawdzić, czy i gdzie znajduje się on w ściętym rzucie pędzla.
  4. Teraz po prostu wyrenderuj swoje tekstury.

    • Zwiąż teksturę pędzla
    • Dla każdej dotkniętej tekstury
      • Powiąż teksturę jako cel renderowania
      • Renderuj wszystkie obiekty, na które ma to wpływ, i pozwól GPU ustalić, które piksele należy nadpisać.
  5. (Opcjonalnie) Jeśli chcesz zapisać swoje modyfikacje, musisz odczytać tekstury z GPU i zapisać je.

Ponieważ główna praca jest wykonywana przez GPU, powinna być dość szybka. Jednak widzę pewne problemy z opisanym podejściem, gdy pędzel uderza w wiele obiektów / tekstur, które częściowo nakładają się. Ustalenie, który piksel pędzla wpływa na teksturę / obiekt, który może się zabrudzić. Mogą istnieć pewne sztuczki dotyczące szablonów / buforów głębokości, które można zastosować, ale myślę, że jest to temat na inne pytanie.

1 Thomas Sep 18 2020 at 15:13

Dopóki żaden piksel na teksturze nie jest używany dwukrotnie, można wyrenderować geometrię i wyświetlić współrzędne uv (współrzędne tekstury). Zwykle są połączeniem czerwieni i zieleni (2d). Używając pędzla, wystarczy odczytać trafione współrzędne UV i pokolorować teksturę w pozycji (uv) na żądany kolor.

Wskazówka: pomaluj na drugą teksturę, aby nie zniszczyć oryginalnego koloru tekstury.

Wady: Czasami rozdzielczość tekstur różnych trójkątów w geometrii jest różna. Więc na niektórych twarzach będzie wyglądać ładnie, a na innych będzie pikselowany.

Jak wspomniano wcześniej, jeśli siatka (geometria) użyje dwukrotnie tej samej części tekstury (dwie ściany celujące w te same współrzędne tekstury), a na jednej z nich narysujesz, druga również zostanie pomalowana.

the1bird Sep 17 2020 at 07:19

Można to zrobić na różne sposoby.

Ale najbardziej logicznym sposobem jest dla mnie próbkowanie punktów wzdłuż ścieżki, a następnie użycie krzywych splajnów / benziera, aby uczynić ją gładką (dodatkowe punkty można interpolować), a następnie rzutowanie i zapisywanie na teksturze. Dlatego nie trzeba próbkować „każdego” punktu.