본문으로 건너뛰기

노멀맵 OpenGL·DirectX 판별 · 초록 채널

볼록한 부분이 오목하게 보이거나 빛이 반대쪽에서 오는 것처럼 보이면, 노멀맵의 초록(G) 채널 규약이 엔진과 다른 경우가 대부분입니다. Godot와 유니티는 OpenGL 방식(Y+), 언리얼은 DirectX 방식(Y−)을 씁니다. 파일 이름이나 눈대중으로는 의외로 자주 틀립니다.

OpenGL과 DirectX 노멀맵은 초록 채널만 다릅니다. OpenGL 방식 초록(Y+)은 "위를 향함"이고 Godot와 Unity가 이것을 읽으며, DirectX 방식(Y−)은 "아래를 향함"입니다. 규약이 틀린 맵은 위아래 가장자리 음영이 뒤바뀌어, 위에서 비추면 볼록한 곳이 반쯤 오목하게 보이고 좌우는 멀쩡해 보입니다. 초록을 뒤집거나(255 − g, 손실 없음) 엔진의 가져오기 반전을 쓰세요. 어느 쪽인지 모르면 Studio 점검 패널이 측정해 주며, 확인을 누르기 전에는 아무것도 바꾸지 않습니다.

스프라이트, 스프라이트 시트 또는 반복 텍스처(PNG)를 끌어다 놓으세요
빈 Studio 열기
브라우저에서 처리하며 파일은 업로드되지 않습니다.
Studio 텍스처 작업 공간: 가져온 ambientCG 노멀맵을 높은 신뢰도로 DirectX라고 판별했고, 규약을 확인하기 전에는 아무것도 바뀌지 않는 화면
CC0 에셋(ambientCG)을 연 실제 Studio 화면입니다.
내보내기 대상
  • Godot 4 2D lights검증됨· Godot 4.7.2
  • Unity 6 URP 2D검증됨· Unity 6000.5.3f1 (URP 17.5)
  • PNG set + JSON일반 파일

초록 채널의 의미와 뒤집힘을 놓치기 쉬운 이유

탄젠트 공간 노멀맵에서 빨강은 X(이미지 오른쪽), 파랑은 Z(표면 바깥), 초록은 Y입니다. 두 규약은 빨강·파랑은 같고 Y가 어느 쪽인지만 다릅니다. Godot의 CanvasTexture 레퍼런스는 Godot가 X+, Y+, Z+ 좌표를 기대한다고 하고, Unity 매뉴얼은 Unity가 Y+ 노멀맵("OpenGL 형식이라고도 함")을 쓴다고 합니다.

PNG 안에는 어느 규약인지 적혀 있지 않고 둘 다 올바른 맵입니다. 좌우 조명은 그대로 맞기 때문에 뒤집힘을 놓치기 쉽습니다. 음영의 위아래 절반만 바뀌므로 조명을 좌우로 움직이면 멀쩡하고 위아래로 움직여야 어색합니다. 출처가 파일 이름에 표시한다면(ambientCG의 NormalGL·NormalDX) 도움이 되지만, 아니면 추측일 뿐입니다.

Nerulio 점검 패널은 이것을 측정합니다. OpenGL로 읽었을 때 실제 표면의 기울기는 서로 모순이 없어야 하는데(높이장의 교차 미분이 같음), DirectX 맵은 반대 부호로 이를 깹니다. 스프라이트에서는 실루엣의 노멀이 바깥을 향하는지 보는 두 번째 검사도 합니다. 판정마다 신뢰도와 근거가 붙고, 대각선 입체가 없는 맵은 추측 대신 "판별 불가"가 나옵니다.

빨강이 뒤집힌 경우가 문제의 나머지 절반입니다. 어떤 생성기는 X를 반대로 쓰며, 비교 측정에서 NormalMap-Online의 기본 출력이 그랬습니다. 스프라이트라면 실루엣 검사가 빨강을 따로 재서 "빨강 뒤집힘"을 알려 주지만, 불투명 텍스처에서는 빨강 뒤집힘과 초록 뒤집힘이 어떤 검사로도 똑같아 보이고 패널도 그렇게 표시합니다.

Y+ (OpenGL)
초록이 128보다 크면 이미지 위쪽을 향함. Godot, Unity.
Y− (DirectX)
초록이 128보다 크면 아래쪽을 향함. 예: ambientCG의 NormalDX 파일.
초록 뒤집기
g → 255 − g. 두 번 하면 원래 바이트로 돌아옵니다.

예시: 위를 향한 픽셀 하나를 두 방식으로 읽기

Nerulio가 옮겨 놓은 Godot 2D 조명 모델로 계산, 흰 픽셀 하나와 점광원 하나, 주변광 없음:

이미지 위쪽으로 45° 기운 면
  OpenGL 바이트 (128, 218, 218)      DirectX 바이트 (128, 37, 218)

조명이 픽셀 위 64px, 높이 64px:
  OpenGL 맵을 OpenGL로 읽음    N·L = 1.00  → 255 (가장 밝음)
  DirectX 맵을 OpenGL로 읽음   N·L = 0.00  →   0 (어두움)
같은 조명을 픽셀 아래 64px에 두면:
  DirectX 맵을 OpenGL로 읽음   N·L = 1.00  → 255: 반대쪽에서 밝아짐

뒤집기: 255 − 37 = 218,  255 − 218 = 37   (두 번 = 원래 바이트)

가로 방향 면은 뒤집어도 변하지 않으므로, 맵이 틀렸는데도 좌우 조명 시험은 통과할 수 있습니다. 반드시 위나 아래에 조명을 두고 시험하세요.

이렇게 작동합니다

  • 검사 패널은 표면 자체로 규약을 잽니다. OpenGL로 읽었을 때 실제 표면의 기울기는 서로 맞아떨어져야 하고, DirectX 맵은 이를 측정 가능한 방식으로 깨뜨립니다.
  • 스프라이트에서는 실루엣으로 독립된 두 번째 검사를 합니다. 가장자리의 노멀은 바깥을 향해야 하며, 두 검사가 일치하면 신뢰도가 올라갑니다.
  • 판정마다 신뢰도와 근거를 보여 줍니다. 대각선 굴곡이 없는 평평한 맵은 추측 대신 판정을 내리지 않고, “OpenGL입니다/DirectX입니다”를 누르기 전에는 아무것도 바뀌지 않습니다.
  • 스프라이트에서는 뒤집힌 빨강(R) 채널도 찾아 “Flip red (X−)”로 고칩니다. 투명한 가장자리가 없는 텍스처에서는 빨강과 초록을 구분할 수 없으며, 패널이 그렇게 알려 줍니다.
  • 두 규약 모두 내보냅니다. PNG 세트에 _n(OpenGL)과 _n_dx(DirectX), 또는 한쪽만 담은 노멀맵 PNG 하나.

사용 방법

  1. 텍스처 작업 공간에 그림과 그 노멀맵을 넣습니다.
  2. 노멀 맵 패널에서 소스를 가져온 노멀맵으로 정합니다.
  3. 검사 패널에서 판정, 신뢰도, 근거를 읽습니다.
  4. “OpenGL입니다” 또는 “DirectX입니다”를 누르고(표시되면 Flip red도), C로 평면과 조명을 비교합니다.
  5. 엔진이 읽는 규약으로, 또는 두 가지가 다 든 PNG 세트로 내보냅니다.

결과 확인

  • 조명 시험: 바로 위의 조명은 위를 향한 가장자리를, 바로 왼쪽의 조명은 왼쪽을 향한 가장자리를 밝혀야 합니다.
  • 알려진 모양으로 바이트 시험: 돔이나 베벨 버튼의 위쪽 절반은 OpenGL 맵에서 초록이 128보다 큽니다.
  • 왕복 시험: 초록을 두 번 뒤집어 원본과 비교하면 바이트가 똑같아야 합니다.

엔진별로 쓸 노멀맵

엔진·출처초록 규약Studio에서 쓸 파일
Godot 4OpenGL (Y+)_n.png 또는 Godot 4 번들(CanvasTexture와 조명 씬)
유니티(URP 2D)OpenGL (Y+)_n.png 또는 Unity 6 번들(Secondary Texture _NormalMap)
언리얼 엔진DirectX (Y−)_n_dx.png
ambientCG 다운로드NormalGL = OpenGL, NormalDX = DirectXGodot·유니티에는 NormalGL
출처를 모르는 맵검사 패널에서 측정판정을 확정한 뒤 원하는 쪽으로 내보내기
빨강이 반대인 스프라이트 맵빨강 뒤집힘(X−)Flip red (X−) 후 내보내기

문제 해결

증상유력한 원인확인 방법해결
조명이 위에 있는데 아래에서 비친 듯하고 좌우는 멀쩡함엔진이 읽는 것과 다른 초록 규약바로 위에 조명을 두면 윗가장자리가 밝아지는지초록 뒤집기. Godot라면 Import 독에서 Process › Normal Map Invert Y를 켜고 다시 가져오기
조명이 왼쪽인데 오른쪽이 밝고 위아래는 멀쩡함생성기가 빨강을 뒤집어 저장함한쪽에서 비춰 보기. 스프라이트라면 점검 패널이 "빨강 뒤집힘" 표시점검 패널의 빨강 뒤집기 (X−), 또는 그 툴의 빨강 반전을 끄고 다시 생성
어느 방향이든 반대: 볼록이 오목높이 자체가 반전됨(빨강·초록 모두 뒤집힘)위 두 시험이 동시에 실패반전한 높이로 다시 만들거나 빨강과 초록을 함께 뒤집기
패널이 "판별 불가"라고 함대각선 입체가 없음. 곧은 홈, 단일 경사, 평면에는 방향성 정보가 없음맵에 둥글거나 대각선인 모양이 있는지출처로 판단(ambientCG·Poly Haven은 파일 이름에 표시)하거나 비춰 보고 판단
손으로 그린 도트 스프라이트에서 신뢰도가 낮음양식화된 맵에서는 두 검사가 서로 다른 답을 냄판정 아래의 근거 줄위에서 비춰 눈으로 확인. "OpenGL입니다"나 "DirectX입니다"를 누르기 전에는 적용되지 않음
초록을 뒤집었는데도 Unity에서 틀림sRGB(Color Texture)가 켜져 맵이 감마 변환됨노멀맵의 가져오기 설정sRGB 끄기. Unity 2D 노멀맵 참고

다른 방법

방법이럴 때 더 낫습니다
OpenGL ↔ DirectX 변환기(텍스처 랩)규약을 이미 알고 파일 전체 초록만 한 번에 뒤집으면 될 때.
엔진의 가져오기 반전Godot의 Process › Normal Map Invert Y는 파일은 그대로 두고 가져올 때 뒤집습니다. 같은 파일을 DirectX 방식 엔진과 함께 쓸 때 편합니다.

엔진별 내보내기와 검증 방법

"검증됨"은 실제 CC0 에셋으로 내보낸 파일을 해당 엔진·도구가 직접 불러와 원본과 비교했다는 뜻입니다. 불러오지 않은 형식은 그렇게 표시합니다.

대상파일검증
Godot 4 2D lights_lit.tscn · CanvasTexture .tres · normal / specular PNG검증됨 Godot 4.7.2실제 CC0 사례 6개를 Godot(gl_compatibility)가 렌더링했고, 확인한 모든 프레임이 Studio 조명 미리보기와 1/255 이내로 같았습니다. 초록을 뒤집은 같은 렌더는 3.8~37단계 어긋나므로 잘못된 규약을 잡아낼 수 있습니다.
Unity 6 URP 2DPNG · nerulio-texture.json · Editor/NerulioNormalMapImporter.cs검증됨 Unity 6000.5.3f1 (URP 17.5)12회 중 12회 통과(사례 6개 × 감마·리니어 색 공간): URP가 적용한 조명이 내보낸 노멀맵과 일치합니다(평균 오차 0.0037~0.0085). 빛의 감쇠는 URP 방식이라 밝기는 미리보기가 아니라 Unity 기준입니다.
PNG set + JSONalbedo · _n (OpenGL) · _n_dx (DirectX) · 16-bit height · AO · specular · manifest일반 파일어떤 엔진이나 도구에서도 쓰는 일반 파일이며, 엔진 실행 검증은 주장하지 않습니다.

검증 근거

Godot 4.7.2가 실제 CC0 사례 6개(도트, HD 스프라이트, 반복 텍스처, 가져온 DirectX 맵)를 렌더링했고 확인한 모든 프레임이 Studio 미리보기와 1/255 이내였습니다. Unity 6000.5 URP 2D: 12회 중 12회 통과(사례 6개 × 감마·리니어). 규약을 아는 실제 맵으로 OpenGL/DirectX 판별: 1K 전체 맵 128개 100% 정답, 표본 1,562개 중 틀린 "높음" 판정 0건(초록이 밝으면 OpenGL이라는 단순 규칙은 46%).

한계

  • 불투명 텍스처에서는 빨강 뒤집힘과 초록 뒤집힘을 구별할 수 없으며, 패널이 DirectX 판정 옆에 그렇게 표시합니다.
  • 판정은 신뢰도가 붙은 측정이지 보증이 아니며, 확인하기 전에는 아무것도 적용하지 않습니다.
  • 높이를 잘못 추측해 만든 맵처럼 형태 자체가 틀린 맵은 Nerulio가 고칠 수 없습니다.
  • 투명한 가장자리가 없는 그림(반복 텍스처)에서는 빨강이 뒤집힌 것과 DirectX 초록을 구별할 수 없습니다. 점검 패널이 이를 알리고 "빨강 뒤집기"를 제공합니다.
  • 시트는 스프라이트 작업 공간에서 프레임을 자르기 전까지 그림 하나로 조명됩니다. 텍스처 작업 공간은 프레임을 자르지 않습니다.
  • 림 라이트는 미리보기 전용이며, Unity로는 스페큘러 맵을 내보내지 않습니다(Godot는 내보냄).
  • Unity는 자체 빛 감쇠를 씁니다. 내보낸 노멀맵은 Unity에서 검증했지만 밝기 곡선은 Unity 방식입니다.

버전과 출처

판별 정확도(convention_eval.mjs, 2026-09-24): 1K 전체 맵 128장 100% 정답, 256² 조각은 판정을 낸 것의 100%(판정률 99.2%), 64² 조각 99.6%, 실제 스프라이트 프레임 213개 100%. 빨강을 뒤집은 같은 프레임에서도 초록은 100% 맞았고 213개 모두 빨강 뒤집힘을 보고했습니다. 표본 1,562개에서 틀린 "높음" 판정은 0개였고, "초록이 대부분 높으면 OpenGL"이라는 단순 규칙은 46%였습니다. 엔진 규약은 Godot·Unity 문서를 따릅니다.

참고한 공식 문서

자주 묻는 질문

Godot, 유니티, 언리얼은 어느 규약인가요?

Godot와 유니티는 OpenGL 방식(Y+), 언리얼은 DirectX 방식(Y−)입니다. Studio의 Godot 4·Unity 6 내보내기는 OpenGL로 쓰며, Godot 4.7.2와 Unity 6000.5.3f1에서 예상대로 조명되는 것을 확인했습니다.

판별은 얼마나 정확한가요?

규약을 아는 실제 맵으로 쟀습니다. 1K 맵 128장 100 %, 256² 조각은 판정을 낸 것 중 100 %(99.2 %에 판정), 64² 조각 99.6 %, 스프라이트 프레임 213장 100 %. 1,562개 표본에서 틀린 “높음” 판정은 0건입니다. “초록이 밝으면 OpenGL” 같은 단순 규칙은 46 %였습니다.

DirectX인 걸 이미 알면 초록만 뒤집으면 되나요?

네. 아래 링크한 기존 텍스처 랩 페이지가 초록을 한 번에 뒤집습니다. 검사 패널은 확신이 없는 파일용이고, 바꾸기 전에 조명 결과부터 보여 줍니다.

빨강이 뒤집혔다고 나오는 이유는?

빨강을 반대로 쓰는 생성기가 있습니다(NormalMap-Online 기본 출력이 그렇습니다). 스프라이트는 실루엣으로 빨강을 따로 재므로, 판정은 초록 기준이고 빨강은 따로 보고하며 신뢰도는 “중간”까지만 냅니다.

무료인가요? 계정이 필요한가요?

이 페이지의 기능은 모두 무료이며 계정 없이 쓸 수 있습니다. 워터마크나 막혀 있는 내보내기가 없습니다.

스프라이트가 업로드되나요?

아니요. Studio는 이 브라우저 탭 안에서 디코딩·패킹·내보내기를 합니다. 프로젝트는 브라우저(IndexedDB)에 자동 저장되며 .nerulio 파일로 저장할 수 있습니다.

Aseprite나 엔진 플러그인을 설치해야 하나요?

아니요. .aseprite 파일은 브라우저에서 읽고 씁니다. 엔진별 번들에는 그 엔진에 필요한 것이 들어 있습니다(Godot는 가져오기 설정과 씬, Unity와 Godot 타일셋은 작은 편집기 스크립트).