Tilbake til Bloggen
Veiledninger

Normal Map-konvensjoner: OpenGL vs DirectX forklart

Hvorfor normal map-en din ser invertert ut i Unreal men fin ut i Unity — en forklaring på klart norsk av tangent-space Y-akse-konvensjoner, med konkrete løsninger.

Admin23. april 20263 min lesing11

Du plugger en normal map inn i Unreal og overflaten lyses som om solen kommer fra under. Du plugger samme fil inn i Unity eller Blender — ser flott ut. Mesh-en er identisk. Teksturen er identisk. Hva skjer?

To industrier, en akse med uenighet

Normal maps lagrer en overflateretning i sine RGB-kanaler. Rød = X, grønn = Y, blå = Z. Hver PBR-engine dekoder dem på samme måte med ett unntak: tegnet på Y.

OpenGL-konvensjon (Y+): en lysere grønn kanal betyr at overflaten peker opp. Brukt av Unity, Godot, Blender (Cycles og Eevee), Substance Painter sin standardeksport, og enhver WebGL-basert engine.

DirectX-konvensjon (Y−): lysere grønn betyr at overflaten peker ned. Brukt av Unreal Engine, den eldre Direct3D-verktøykjeden, og noen CryEngine/Xbox-eraeiendeler.

Samme bytes i PNG-en. Motsatt fysisk betydning.

Hvordan fortelle med ett blikk

Se på en halvkulebump (som en knapp eller kuppel) i normal map-en din. I OpenGL-konvensjon vil bunnen av bumpen være mørkere grønn fordi overflaten roterer mot Y−, bort fra lyset. I DirectX-konvensjon er bunnen lysere grønn.

Hvis belysningen føles bakvendt i engine — uthevinger der det burde vært skygger — har du et konvensjonsavvik.

Løsningen tar 5 sekunder

I Unreal har teksturimportdialogen en Flip Green Channel-avkryssingsboks. Slå den på og engine-n inverterer G-kanalen ved sampling. Ingen grunn til å re-eksportere kilden din.

I Unity setter du teksturtypen til Normal map og importøren håndterer alt — Unity forventer OpenGL, men den advarer deg hvis filen ser feil ut. I Blender bruker du en Separate Color → Invert G → Combine Color node-kjede, eller bare velg DirectX-stilinput direkte i Normal Map-noden.

Hvorfor to standarder i første omgang?

På 1990-tallet definerte OpenGL og DirectX motsatte teksturkoordinatrom — OpenGL hadde Y som øker opp, DirectX hadde Y som øker ned. Da normal maps ble vanlig på midten av 2000-tallet, bakte hver verktøykjede sitt rom inn i sine utganger. Divergensen holdt seg fordi det er dyrt å flippe en etablert pipeline.

Generere normal maps uten forvirringen

aukimi Normal Map Generator lar deg velge konvensjonen eksplisitt når du eksporterer. Den kjører en Sobel-gradient på luminansen til høydekartets ditt, og pakker (−dx·s, −dy·s, 1) inn i RGB — med Y flippt når du velger DirectX. Du kan bytte konvensjon etter generering og laste ned på nytt uten å laste opp på nytt.

Internt er formelen identisk. Den eneste forskjellen er tegnet vi bruker på Y-komponenten før vi skriver den grønne kanalen. Når du vet det, kan du konvertere en fil mellom konvensjoner med en hvilken som helst bilderedigeringsprogram: åpne PNG-en, velg den grønne kanalen, inverter den, lagre. Det er alt "Flip Green Channel" gjør i Unreal.

Hurtigreferanse

  • Unity, Godot, Blender, Substance Painter (standard): OpenGL (Y+).
  • Unreal Engine, eldre Direct3D: DirectX (Y−).
  • Ser feil ut i Unreal? Slå på Flip Green Channel i importinnstillingene.
  • Ser feil ut i Unity? Du eksporterte sannsynligvis fra et DirectX-konvensjonsverktøy — inverter den grønne kanalen eller re-eksporter.

Når du har internalisert konvensjonen, er løsningen trivial. Det vanskeligste er å gjenkjenne det første gangen.

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

Likte du denne artikkelen?

ShareHN