Powrót do bloga
Poradniki

Konwencje Normal Map: OpenGL vs DirectX wyjaśnione

Dlaczego normal map wygląda odwrócona w Unrealu, ale świetnie w Unity — zwyczajne wyjaśnienie konwencji osi Y przestrzeni stycznej, z konkretnymi rozwiązaniami.

Admin23 kwietnia 20263 min czytania11

Podłączasz normal mapę do Unreala i powierzchnia oświetla się tak, jakby słońce świeciło od dołu. Tę samą plik podłączasz do Unity'ego lub Blendera — wygląda świetnie. Mesh jest identyczny. Tekstura jest identyczna. Co się dzieje?

Dwie branże, jedna oś niezgody

Normal mapy przechowują kierunek powierzchni w kanałach RGB. Red = X, green = Y, blue = Z. Każdy engine PBR dekoduje je w ten sam sposób, z jednym wyjątkiem: znakiem Y.

Konwencja OpenGL (Y+): jaśniejszy kanał zielony oznacza, że powierzchnia wskazuje w górę. Używane przez Unity, Godot, Blender (Cycles i Eevee), domyślny eksport Substance Painter i każdy engine oparty na WebGL.

Konwencja DirectX (Y−): jaśniejszy kolor zielony oznacza, że powierzchnia wskazuje w dół. Używane przez Unreal Engine, starszą linię narzędzi Direct3D i niektóre zasoby CryEngine/Xbox.

Te same bajty w PNG. Przeciwne znaczenie fizyczne.

Jak stwierdzić na pierwszy rzut oka

Spójrz na półkulistą wypukłość (jak guzik lub kopułę) w swojej normal mapie. W konwencji OpenGL dno wypukłości będzie ciemniejsze zielone, ponieważ powierzchnia obraca się w kierunku Y−, z dala od światła. W konwencji DirectX dno jest jaśniejsze zielone.

Jeśli oświetlenie wygląda odwrotnie w silniku — światła gdzie powinny być cienie — masz niezgodność konwencji.

Naprawa zajmuje 5 sekund

W Unrealu dialog importu tekstury ma opcję Flip Green Channel. Włącz ją, a silnik odwróci kanał G w momencie próbkowania. Nie musisz ponownie eksportować źródła.

W Unity ustaw typ tekstury na Normal map, a importer zajmie się wszystkim — Unity oczekuje OpenGL, ale ostrzeże cię, jeśli plik wygląda źle. W Blenderze użyj łańcucha węzłów Separate Color → Invert G → Combine Color, lub po prostu wybierz bezpośrednio wejście w stylu DirectX w węźle Normal Map.

Dlaczego dwie standardy na początek?

W latach 90. OpenGL i DirectX definiowały przeciwne przestrzenie współrzędnych tekstury — OpenGL miał Y rosnące w górę, DirectX miał Y rosnące w dół. Gdy normal mapy stały się powszechne w połowie 2000., każdy łańcuch narzędzi wbudował swoją przestrzeń w swoje wyjścia. Rozbieżność utrzymała się, ponieważ przerzucenie ustalonego pipeline'u jest kosztowne.

Generowanie Normal Map bez zamieszania

Generator Normal Map aukimi pozwala na jawny wybór konwencji podczas eksportu. Uruchamia gradient Sobela na jasności heightmapy, a następnie pakuje (−dx·s, −dy·s, 1) do RGB — z Y odwróconym, gdy wybierzesz DirectX. Możesz przełączać konwencję po generacji i ponownie pobrać bez ponownego przesyłania.

Wewnętrznie formuła jest identyczna. Jedyną różnicą jest znak, który stosujemy do składnika Y przed zapisaniem kanału zielonego. Wiedząc to, możesz konwertować plik między konwencjami za pomocą dowolnego edytora obrazów: otwórz PNG, wybierz kanał zielony, odwróć go, zapisz. To wszystko, co robi "Flip Green Channel" w Unrealu.

Szybka instrukcja

  • Unity, Godot, Blender, Substance Painter (domyślnie): OpenGL (Y+).
  • Unreal Engine, starszy Direct3D: DirectX (Y−).
  • Wygląda źle w Unrealu? Włącz Flip Green Channel w ustawieniach importu.
  • Wygląda źle w Unity? Prawdopodobnie eksportowałeś z narzędzia o konwencji DirectX — odwróć kanał zielony lub ponownie eksportuj.

Po internalizacji konwencji naprawa jest trywialna. Najtrudniejsza część to rozpoznanie tego po raz pierwszy.

#normal-map#3d#pbr#shaders#opengl#directx

Podobał Ci się ten artykuł?

ShareHN