Każdy materiał od Rozdziału 5 miał jeden, płaski kolor kd. W tym rozdziale ten kolor zaczyna zależeć od tego, w które miejsce powierzchni trafił promień — a to właśnie robią tekstury.
Oprócz pozycji (3D) i normalnej (3D), każdy wierzchołek siatki niesie zwykle też UV — parę liczb (u,v), zazwyczaj z zakresu [0,1]. To współrzędne, które ustawiłeś ręcznie w edytorze UV w Blenderze czy Mayi, „rozkładając” zakrzywioną powierzchnię 3D na płaski obraz.
W punkcie trafienia nie mamy UV od razu — musimy je zinterpolować z UV trzech wierzchołków, tymi samymi wagami barycentrycznymi, które policzył algorytm Möllera–Trumbore w Rozdziale 4. Uwaga na nazewnictwo: w Rozdziale 4 wagi barycentryczne nazwaliśmy u i v — to zwykłe skalary mówiące, jak blisko którego wierzchołka leży punkt trafienia (u ≥ 0, v ≥ 0, u+v ≤ 1). UV z akapitu wyżej to zupełnie inna para liczb: współrzędna na mapie tekstury, z zakresu [0,1] niezależnie od kształtu trójkąta. Nazwy się powtórzyły przypadkiem, więc poniżej piszemy wagi barycentryczne jako same u, v, a współrzędne tekstury zawsze z przedrostkiem — uvA, uvB, uvC, uv_hit:
uv_hit to para liczb z zakresu [0,1] — ale obraz tekstury to zwykła siatka pikseli (tu nazywanych tekselami, od „texture” + „pixel”) o konkretnych wymiarach Tw × Th, np. 2048×2048. Żeby wiedzieć, który dokładnie teksel odczytać, musimy przeskalować uv_hit z zakresu [0,1] do tej siatki:
x, y rzadko wypadają na dokładny środek teksela — zwykle lądują gdzieś pomiędzy czterema najbliższymi. Filtrowanie najbliższego sąsiada po prostu zaokrągla (blokowe piksele z bliska). Filtrowanie biliniowe uśrednia cztery najbliższe teksele, ważąc je odległością — dokładnie tą samą logiką co interpolacja barycentryczna, tylko na kwadratowej siatce, nie trójkącie:
Osobny problem to wrapping: co zrobić, gdy u albo v wychodzi poza [0,1]? „Repeat” zawija wzór (u mod 1) — standard dla tekstur kaflowych. „Clamp” przycina do koloru z krawędzi. „Mirror” odbija naprzemiennie. To dokładnie te opcje, które widzisz jako Wrap Mode w Unity czy Unreal.
Alternatywa dla odczytu z obrazu: policz kolor prosto ze wzoru, na podstawie samego UV. Klasyczna szachownica:
Bardziej organiczne wzory — marmur, drewno, obłoki — buduje się z szumu Perlina: gładkiej, pseudolosowej funkcji, która wygląda naturalnie i nie ma szwów. To dosłownie budulec każdego node’a „Noise” w grafie materiału.
↓ Dodatek P — idea gradientowaKompromis jest praktyczny: tekstura proceduralna ma nieskończoną rozdzielczość i zero szwów, ale każde jej wywołanie to obliczenia — a skomplikowane, wielowarstwowe wzory (fBm, turbulencja) mogą być wolniejsze niż jeden odczyt z obrazu. Dlatego w produkcji proceduralne wzory często zapieka się (bake) do tekstury na koniec.
Base Color, Roughness, Normal, Metallic — każdy slot mapy w grafie materiału robi dokładnie ten sam odczyt UV z tego rozdziału, tylko wynik trafia do innego parametru równania z Rozdziału 5, nie tylko do kd.
↓ Dodatek J — ile kosztuje policzenie tej sieciMipmapping — z góry wyliczone, mniejsze wersje tekstury — istnieje z tego samego powodu co antyaliasing z Rozdziału 8: gdy tekstura jest widziana z daleka albo pod kątem, jeden teksel odpowiada za wiele pikseli ekranu, i bez mipmap dostajesz migoczący moiré na przeskalowanej teksturze, nie tylko na geometrii.
↓ Dodatek G — MipmappingKolor materiału mamy już w pełni sterowalny. W następnym rozdziale zajmiemy się tym, co ten kolor właściwie reprezentuje fizycznie: dielektryki, metale i modele BRDF — most między Blinn-Phongiem z Rozdziału 5 a prawdziwym PBR.