Svgtex to wtyczka (plugin) do Blendera, umożliwiająca użycie plików *.svg jako tekstur. Svgtex w pełni wykorzystuje wektorowy zapis obrazu, jakim jest format SVG. Umożliwia uzyskanie w Blenderze tekstur, które nawet w największym zbliżeniu nie tracą ostrości. Kod źródłowy komponentu jest udostępniony na zasadach GPL. Obecna wersja — 1.0 — współpracuje poprawnie z Blenderem od wersji 2.46 do wersji 2.49.

Do pobrania:
Skompilowany plik dla Win32 — wtyczka i program do podglądu (sprawdzania) obrazów SVG (0.4 MB, wyłącznie dla Windows, 32-bit);
Kod źródłowy — opcjonalny: jeżeli chcesz sam komponent skompilować/coś w nim zmienić;

Jeżeli chcesz powtórzyć operacje pokazane poniżej, pobierz
przykładowy model (12 MB) — model P-40B, wraz z teksturami, używany w tym tekście;

1. Instalacja i uruchomienie
Wtyczka to plik svgtex.dll. Znajdzesz go w spakowanym pliku *.zip. Zawartość rozpakuj i umieść w jakimś istotnym folderze (np. w katalogu plugins/texture Blendera).

Aby skorzystać z wtyczki, zmień najpierw typ tekstury na Plugin (Fig. 1.1):
Fig. 1.1 Zmiana typu tekstury — z rastrowej (Image) na „wtyczkę” (Plugin)

Spowoduje to zmianę układu paneli: znikną panele obrazu rastrowego, zastąpione przez panel o nazwie Plugin. Początkowo znajduje się na niej tylko przycisk Load Plugin. Naciśnij go (Fig. 1.2):
Fig. 1.2 Początkowy układ paneli Plugin

W oknie wyboru plików wskaż plik wtyczki: svgtex.dll. Koniecznie wyłącz ścieżki względne (Relative Paths - por. Fig. 1.3). Gdy ta opcja jest włączona, Blender nie będzie w stanie go załadować!
Fig. 1.3 Wskazanie pliku wtyczki

Jeżeli wtyczka załadowała się poprawnie, powinna wyświetlić w panelu Plugin dodatkowe kontrolki (Fig. 1.4):
Fig. 1.4 Załadowana wtyczka svgtex

Konieczność wpisywania pełnych nazw ścieżek jest uciążliwa, gdy musisz przenieść plik Blendera na inny komputer. Tam plik wtyczki może być w innym folderze, i trzeba parametry tekstur typu Plugin ustawiać od nowa.
Najwygodniej byłoby wpisywać w panelu Plugin tylko nazwę pliku *.dll — i niech komputer go sam znajdzie! To, na szczęście, jest możliwe. Wystarczy zebrać wszystkie wtyczki, z których korzystasz, w jedno miejsce (jeden katalog), a następnie dopisać jego nazwę do zmiennej środowiskowej Path.
Zmienne środowiskowe przestawiasz w Windows następująco:
  1. Podświetl ikonę Mój Komputer i przejdź do jej Właściwości;
  2. W oknie dialogowym Właściwości systemu przejdź do zakładki Zaawansowane i naciśnij umieszczony u dołu przycisk Zmienne środowiskowe
  3. W oknie dialogowym Zmienne środowiskowe podświetl na liście Zmienne systemowe zmienną Path i naciśnij przycisk Edytuj
  4. W oknie dialogowym Edytowanie zmiennej systemowej dopisz ścieżkę do folderu z wtyczkami Blendera (np. u mnie to C:\Program Files\Blender\plugins\texture). Zwróć uwagę, że separatorem poszczególnych ścieżek jest tu średnik! Nie zapomnij sprawdzić, czy jest przed i za dopisaną przez Ciebie nazwą!

Gdy plik wtyczki znajduje się w jednym z folderów wyliczanych przez Path, można mu w panelu Plugin usunać całą ścieżkę. Na innym komputerze możesz wskazać w tej zmiennej środowiskowej inny katalog. Pliki Blendera, w których wtyczki są wpisane tak, jak na Fig. 1.5, będą się poprawnie renderować na każdej z tych maszyn.

Fig. 1.5 Wtyczka svgtex wskazana w sposób „niezależny od komputera”
2. Użycie svgtex
W pole File name wpisz ścieżkę do pliku SVG (w tym przykładzie to plik decals.svg). Należy wpisywać ścieżki względne — względem pliku *.blend, w którym aktualnie pracujesz. Zmień jeszcze tło na ciemnoszare, Alpha na 0, i możesz już włączyć Enable. W panelu Preview pojawi się podgląd tekstury (Fig. 2.1):
Fig. 2.1 Przykład tekstury wektorowej - znaki rozpoznawcze i napisy eksploatacyjne samolotu

Gdybyś pomylił się w nazwie pliku, lub coś poszło nie tak, jak powinno, w podglądzie tekstury pojawi się jednolity, czerwony kolor. W takim przypadku zajrzyj do tekstowej konsoli Blendera — powinien się tam pojawić opis błędu, zgłoszonego przez svgtex (na przykład: „nie można znaleźć pliku”).

Jak na razie, na podglądzie tekstury obraz wektorowy wygląda identycznie jak rastrowy (por. Fig. 1.1). W przykładzie, który wykorzystujemy, jest to tekstura ze znakami rozpoznawczymi i innymi emblematami, nakładana na model samolotu. Jak w takim razie będzie się prezentować na renderze?
UWAGA: aby uzyskać z svgtex pełen efekt, musisz włączyć opcję OSA (ustawienia na panelu Render). W przeciwnym razie zawartość pliku SVG zostanie nałożona na model w domyślnej, zazwyczaj bardzo niskiej rozdzielczości.

Fig. 2.2 pokazuje porównanie modeli ze znakami rozpoznawczymi naniesionymi za pomocą tekstury wektorowej (a) i rastrowej (b). Tekstura rastrowa decals.png ma rozmiary 2048x2048 pixeli:
Fig. 2.2 Porównanie tekstury wektorowej i rastrowej — model w „zwykłej” odległości od kamery

Mówiąc szczerze, porównanie Fig. 2.2a) i Fig. 2.2b) wygląda na łamigłówkę typu „znajdź wszystkie różnice”. Z trudem udało mi się zidentyfikować te dwie, które pokazuję. Sądzę, że obydwie mają tę samą przyczynę: svgtex stosuje prostsze filtry przybliżania pikseli, niż te, których używa Blender do plików rastrowych. W każdym razie nie widać tu żadnych przewag tekstury wektorowej nad rastrową.

Ale zbliżmy się teraz do jakiegoś fragmentu modelu — na przykład łopaty śmigła (Fig. 2.3). Przypadek (a) pokazuje zbliżenie z teksturą rastrową, a przypadek (b) — to samo ujęcie z teksturą wektorową. Przypadek (c) to jeszcze bliższe ujęcie tekstury wektorowej. Można już wyraźnie odczytać napis na łopacie, a nawet emblemat: Curtiss Electric Propellers!:
Fig. 2.3 Porównanie małych napisów w wersji rastrowej (decals.png) i wektorowej (decals.svg)

Wniosek: tekstury wektorowe są przydatne tam, gdzie wykonujesz większe zbliżenia modelu.
3. Jak to działa?
Zasada działania svgtex nie jest jakąś szczególną tajemnicą. Podczas renderowania Blender żąda od wtyczki podania barwy konkretnego teksela (piksela tekstury). Svgtex, aby „udzielić odpowiedzi”, tworzy w pamięci rastrowe fragmenty obrazu. Użyje ich także przy okazji następnych „pytań” Blendera. Każdy z tych fragmentów ma rozmiar 256x256 pikseli — tak, by zajmował w RAM nie więcej niż 1 MB. W ten sposób oryginalny obraz jest dzielony jak szachownica, na kwadratowe, jednolite obszary. Svgtex przygotowuje i przechowuje tylko takie „pola” tej szachownicy, których zażądał od niego Blender. Dodatkowo, jeżeli całe takie „pole” jest zupełnie jednolite, zamiast 1 MB danych przechowywany jest pojedynczy, reprezentujący je piksel.

Svgtex tworzy fragmenty wielu różnych wersji obrazu, różniących się rozdzielczością. Każda kolejna wersja ma czterokrotnie większą liczbę pikseli od poprzedniej. Pierwsza wersja obrazu jest zawarta w pojedynczym fragmencie, czyli „wpasowana” w obszar 256x256 pikseli. Następna ma wymiary 512x512 pikseli, i składa się z 4 fragmentów. Kolejna wersja to obraz 1024x1024 pikseli (złożony z 16 fragmentów o rozmiarach 256x256). W grafice komputerowej o takim szeregu obrazów mówi się, że są uporządkowane według „poziomu szczegółowości” (Level of DetailsLoD) . Poziom ten określa się jako liczbę całkowitą. Na potrzeby Svgtex przypisałem LoD = 0 dla obrazu 256x256, LoD = 1 dla 512x512, LoD = 2 dla 1024x1024, itd. W odpowiedzi na żądane Blendera svgtex określa wymagany LoD obrazu, i zwraca piksel z jego odpowiedniej wersji. Jeżeli żądany fragment jeszcze nie istnieje — jest w tym momencie generowany.

Wtyczkę svgtex pisałem przede wszystko z myślą o własnych potrzebach. Jednak zdawałem sobie sprawę, że kiedyś udostępnię ją innym użytkownikom. Poświęciłem więc trochę czasu na napisanie obsługi większości elementów, występujących w formacie SVG. W efekcie komponent potrafi narysować prawie wszystko, co przewiduje ten standard. Poniżej wyliczam to, co nie zostało zaimplementowane:

Oczywiście, odwieczna mądrość programistów mówi „w każdym programie zawsze jest jeszcze co najmniej jeden nie wykryty błąd”. Komponent na razie był porównywany z rezultatami, które zwracał Inkscape, oraz przeszedł test praktyczny na rysunkach, które przygotowywałem dla moich modeli. Wydaje mi się, że udało mi się wyeliminować przynajmniej większość jego błędów. W razie czego, udostępniam kompletny kod źródłowy.
4. Opis parametrów wtyczki
Rodzaj i położenie kontrolek wtyczki svgtex w panelu Plugin jest efektem wielu bolesnych kompromisów z ograniczeniami, jakie narzuca struktura danych Blendera (zdefiniowana w plugin.h). Na przykład — pole na nazwę pliku *.svg powinno być pierwszą kontrolką tej wtyczki. Niestety, okazuje się, że można je „wepchnąć” wyłącznie pewnym, nie opisanym w dokumentacji Blendera sposobem, i w dodatku tylko jako pole ostatnie (Fig. 4.1):
Fig. 4.1 Funkcje kontrolek wtyczki svgtex

Poniżej podaję znaczenie wszystkich kontrolek, w tej kolejności, jak występują w paneli:

Po tym wyczerpującym opisie pozostaje dorzucić kilka rad praktycznych:
  • Zaraz po załadowaniu wtyczki możesz podnieść limit Mem Max i wykonać pierwszy rendering, by potem odczytać z pola Used, ile svgtex zużył pamięci. Potem ustaw Mem Max na 110% wartości Used;
  • Dla tekstur oznaczeń i innych dokładnych rysunków, stosuj Interpol = 0 lub 1 i Fid = 0.0;
  • Dla tekstur nierówności stosuj Interpol = 1 i Fid = -0.5, by zaokrąglenia i załamania granic paneli były bardziej płynne;
  • 5. svgview.exe: pomoc do podglądu plików SVG
    „Ubocznym produktem” prac nad svgtex jest prosta przeglądarka plików *.svg. Znajdziesz ją w tym samym folderze, co plik svgtex.dll. To w istocie testowy program z biblioteki AGG, w którym sprawdzałem działanie parsera obrazu. Możesz używać svgview.exe do sprawdzenia, jak svgtex wyświetli konkretny obraz. Wystarczy wywołać ten program w linii poleceń, podając jako argument nazwę pliku *.svg (Fig 5.1):
    Fig. 5.1 Obsługa programu svgview.exe

    Powiększenie obrazu możesz w svgview.exe zmieniać za pomocą suwaka Scale, umieszczonego u góry ekranu. Do przesuwania obrazu służy myszka — wystarczy ją przesunąć z wciśniętym lewym przyciskiem. Przy każdej zmianie skali lub przesunięciu obraz jest rysowany na nowo. Liczby u góry ekranu (Fig. 5.1) podają, ile wierzchołków napotkano, i ile trwało przerysowanie obrazu.
    Zwróć uwagę na ogromną liczbę wierzchołków pokazaną na ilustracji — niemal 2 miliony (Fig. 5.1). To mój „stress test”: plik skin.svg, zawierający wszystkie szczegóły nierówności poszycia modelu samolotu. Narysowanie zawartości tego pliku wymaga od interpretera SVG sporego wysiłku, głównie z powodu sposobu odwzorowania nitów. Każdy rząd nitów to jest w nim jeden tekst, a każdy nit to pojedynczy znak tekstu (kropka). (Nity są na tyle małe i „blade”, że na Fig. 5.1 ich nie widać. Otwórz jednak sam ten obraz pod svgview.exe i zwiększ skalę, a je zobaczysz — małe, ciemniejsze kółka). Prawie wszystkie (95%) wierzchołki spośród naliczonych przez program 1 983 458 należą do nitów (każde „kółko” ma ich po 32).

    Tak duża ilość tekstu — 50 tysięcy znaków — zaczyna być dla przeglądarek SVG wyzwaniem. Gdy go tworzyłem (w Inkscape), miałem problemy z szybkością tego edytora. Zacząłem więc mierzyć czas przerysowania całego pliku skin.svg przez interpretery SVG, które miałem pod ręką: Inkscape, Firefox, i mój svgview. Fig. 5.2 przedstawia rezultaty, uzyskane ma moim laptopie (Dell Latitude 610 - Intel Centrino 1.6 MHz, 1 GB RAM, Windows XP):

    Interpreter SVG Czas narysowania (s) Zajęty RAM (MB)
    Inkscape 0.49 45.0 398
    Sketsa Editor 6.3 od 2.0 do 20.0 350
    Firefox 3.5 12.0 27
    svgview.exe 1.5 2
    Fig. 5.2 Czas i pamięć, użyte do przerysowywania pliku skin.svg
    Jak widać, svgview.exe potrzebuje na zaledwie 1.4 sekundy i 2 MB RAM na to, co w Inkscape zajmuje 45s i 400 MB RAM! Przy czym zapewniam, że w kodzie mojego parsera SVG można dokonać jeszcze wielu prostych optymalizacji, a sam program jest był skompilowany w pochodzącym z 1998r MS VC 6.0. Co prawda Inkscape jest edytorem, więc dane SVG musi przechowywać i przetwarzać w trochę inny sposób. Ale popatrz na inn edytor: Sketsa. Tam ktoś wraźnie intensywnie optymalizował przerysowywanie. Przy powiększeniach poniżej 100% przerysowywanie jest rzedu 2s, a przy powiększeniach powyżej 100% - od 5 do 20s. Sądzę że rozrzutność wykorzystania zasobów komputera przez Inkscape może być przejawem jakiegoś grubego błędu w architekturze programu.
    Inna rzecz, że Sketsa ma uboższą od Inkscape funkcjonalność. Co więcej, pokazuje biały ekran przy próbie powiększenia skin.svg do 400% i zawiesza się przy próbie selekcji jakiegokolwiek elementu z tego rysunku. Nie polecam tego programu, tym bardziej że jest płatny.
    Nie spodziewałem się takiej wydajności po moim kodzie, choć AGG, którą wykorzystują svgtex i svgview, jest ładną biblioteką szablonów C++. Być może to właśnie te szablony umożliwiają kompilatorowi daleko posuniętą optymalizację poprzez zastąpienie wywołań wielu metod przez "płaski" kod wynikowy? Ale efekt wyszedł całkiem interesujący!
    6. Funkcje zaawansowane
    Dodatkową kontrolę nad svgtex możesz uzyskać, podstawiając w polu File Name zamiast pliku *.svg specjalne, krótkie pliki *.xml. Nazwałem je skrótami XML, gdyż m.in. pozwalają wskazać plik lub pliki SVG, z których ma powstać tekstura. To zaawansowana funkcjonalność, z której nie musisz korzystać, jeżeli nie znasz (i nie zamierzasz poznać) podstaw składni XML. Jeżeli jednak masz ochotę spróbować — przejdź do opisu skrótów XML.