LOD 단계 전환 시 캐릭터 실루엣 손실을 수치화하고 자동 보정하는 메시 최적화 파이프라인

캐릭터 LOD 전환에서 발생하는 실루엣 깨짐을 IoU와 경계 거리로 측정하고 중요 부위 가중치와 자동 재생성 규칙으로 보정하는 실전 메시 최적화 방법을 정리합니다.

✓ 복사 완료!
챕터GPU & 드로우콜/배칭 최적화
난이도중급
상태● 검토 완료
대상 엔진
UnityUnreal Engine
최종 업데이트
LOD 단계 전환 시 캐릭터 실루엣 손실을 수치화하고 자동 보정하는 메시 최적화 파이프라인

핵심 요약

LOD 전환으로 인한 캐릭터 실루엣 손실은 기준 메시와 LOD 메시를 같은 카메라·포즈로 렌더링한 뒤 실루엣 마스크의 IoU, 경계 Chamfer 거리, 중요 부위 가중치로 수치화할 수 있습니다. 측정 결과가 임계값을 넘으면 디시메이션 비율을 낮추거나 머리·손·무기·헤어처럼 실루엣에 민감한 영역의 삼각형을 자동 보존해 LOD를 다시 생성합니다.

이 방식은 아티스트의 주관적인 “깨져 보인다”는 판단을 화면 공간 지표로 바꾸고 Unity AssetPostprocessor 또는 Unreal Engine Python·Editor Utility 기반의 검증 파이프라인에 연결할 수 있습니다.

LOD 실루엣 손실은 왜 발생하는가?

LOD는 카메라와의 거리에 따라 메시의 삼각형 수를 줄이는 기술입니다. 하지만 폴리곤 수만 줄이면 다음과 같은 문제가 생깁니다.

  • 코, 턱, 손가락, 팔꿈치처럼 외곽선 변화가 큰 부분이 뭉개집니다.
  • 긴 머리카락이나 장식물이 몸통에 합쳐집니다.
  • 무기와 방패처럼 얇고 긴 부위가 사라집니다.
  • 애니메이션 포즈에 따라 기준 LOD와 다른 실루엣이 나타납니다.
  • 같은 월드 단위 오차라도 화면 해상도와 카메라 거리에 따라 체감이 달라집니다.

따라서 “LOD1은 원본의 40% 삼각형” 같은 기하학 중심 규칙만으로는 충분하지 않습니다. 실제 런타임 화면에서 보이는 외곽선이 얼마나 유지되는지 측정해야 합니다.

원본 메시와 LOD 메시의 캐릭터 실루엣 차이를 비교하는 화면

어떤 지표로 캐릭터 실루엣 손실을 측정할까?

1. 실루엣 IoU

기준 메시의 이진 실루엣 마스크를 MrefM_{ref}, 비교 대상 LOD의 마스크를 MlodM_{lod}라고 하겠습니다. 두 영역의 겹침 정도는 Intersection over Union으로 계산합니다.

IoU=∣Mref∩Mlod∣∣Mref∪Mlod∣IoU = \frac{|M_{ref} \cap M_{lod}|}{|M_{ref} \cup M_{lod}|}

IoU가 1에 가까울수록 두 실루엣이 동일합니다. 다만 얇은 무기나 손가락처럼 면적이 작은 부위의 손실은 전체 캐릭터 면적에 묻힐 수 있습니다.

2. 실루엣 경계 Chamfer 거리

두 실루엣의 경계 픽셀 집합을 각각 BrefB_{ref}와 BlodB_{lod}라고 하면 양방향 평균 경계 거리는 다음과 같이 구할 수 있습니다.

CD(Bref,Blod)=1∣Bref∣+∣Blod∣(∑p∈Brefd(p,Blod)+∑q∈Blodd(q,Bref))CD(B_{ref}, B_{lod}) = \frac{1}{|B_{ref}| + |B_{lod}|} \left(\sum_{p \in B_{ref}} d(p, B_{lod}) + \sum_{q \in B_{lod}} d(q, B_{ref})\right)

이 값은 화면 픽셀 단위로 관리하는 편이 좋습니다. 예를 들어 512×512 마스크에서 평균 경계 거리가 2픽셀을 넘으면 육안 검토 대상으로 분류할 수 있습니다.

3. 중요 부위 가중 실루엣 손실

모든 실루엣 픽셀을 같은 비중으로 처리하면 얼굴과 손 같은 핵심 부위가 충분히 보호되지 않습니다. 영역별 가중치 wiw_i를 적용해 손실을 계산합니다.

Lsilhouette=∑iwi(α(1−IoUi)+βCDiDmax)L_{silhouette} = \sum_i w_i \left(\alpha (1 - IoU_i) + \beta \frac{CD_i}{D_{max}}\right)

실무에서는 다음과 같이 영역을 나누는 것이 유용합니다.

영역권장 가중치이유
얼굴·머리3.0캐릭터 식별성과 표정 인식에 직접 영향
손·발2.5포즈와 행동의 방향성을 전달
무기·방패2.5전투 실루엣과 직업 구분에 영향
헤어·망토2.0외곽선 변화가 크고 얇은 부위가 많음
몸통1.0면적이 커서 일부 오차가 평균화됨
내부 표면0.2외곽선에 직접 기여하지 않음

실루엣 비교용 카메라와 포즈는 어떻게 구성할까?

한 방향의 정면 카메라만 사용하면 측면에서 발생하는 실루엣 손실을 놓칩니다. 카메라와 포즈 샘플을 고정된 테스트 세트로 관리해야 합니다.

카메라 샘플

  • 정면, 후면, 좌우 측면
  • 좌우 45도 사선
  • 상체를 강조하는 3/4 카메라
  • 실제 게임에서 사용하는 대표 FOV와 거리
  • 작은 화면에서의 손실을 보기 위한 저해상도 렌더링

카메라 방향은 균일한 구면 샘플링을 사용하거나 프로젝트의 플레이 비중에 따라 가중치를 줄 수 있습니다. 예를 들어 3인칭 액션 게임이라면 후면과 좌우 3/4 뷰에 더 높은 비중을 줍니다.

애니메이션 포즈 샘플

정지 T-pose만 비교하면 애니메이션 중 팔과 무기가 몸통에 겹치는 문제를 찾기 어렵습니다. 다음 포즈를 최소 세트로 두는 것이 좋습니다.

  1. 기본 대기 포즈
  2. 걷기 또는 달리기 중 외곽선이 가장 크게 벌어지는 프레임
  3. 공격 포즈
  4. 피격 또는 회피 포즈
  5. 무기를 든 상태와 무기를 내린 상태

포즈 샘플은 원본 메시와 모든 LOD에 동일한 스켈레톤과 본 변환을 적용해야 합니다. 스킨 웨이트가 변경된 상태에서 비교하면 메시 최적화 오차와 리깅 오차가 섞일 수 있습니다.

자동 보정 메시 최적화 파이프라인은 어떻게 구현할까?

전체 과정은 다음처럼 구성할 수 있습니다.

flowchart LR
    A[원본 메시와 포즈 세트] --> B[LOD 메시 생성]
    B --> C[동일 카메라로 실루엣 렌더링]
    C --> D[IoU와 경계 거리 계산]
    D --> E{임계값 통과}
    E -->|예| F[LOD 승인 및 리포트 저장]
    E -->|아니오| G[중요 영역 보존 후 재생성]
    G --> B

Step 1. 기준 메시와 LOD 생성 조건을 고정한다

먼저 원본 메시를 기준 자산으로 지정하고 LOD별 목표 삼각형 수 또는 화면 점유율을 정합니다.

LOD주요 사용 거리시작 목표실루엣 손실 허용 기준 예시
LOD0근거리원본IoU 0.98 이상
LOD1중거리원본의 60~75%IoU 0.95 이상
LOD2원거리원본의 30~50%IoU 0.90 이상
LOD3초원거리원본의 10~25%IoU 0.82 이상

이 수치는 프로젝트의 화면 크기와 카메라에 맞춰 조정해야 합니다. 중요한 점은 삼각형 비율을 합격 기준으로 사용하지 않고 실루엣 지표와 함께 사용하는 것입니다.

Step 2. 동일 조건으로 이진 실루엣을 렌더링한다

실루엣 비교에서는 알베도, 노멀, 라이팅 차이를 제거해야 합니다. 다음 조건을 고정합니다.

  • 단색 불투명 머티리얼 사용
  • 안티앨리어싱 설정 고정
  • 동일한 카메라 행렬과 렌더 해상도 사용
  • 동일한 스켈레톤 포즈 적용
  • 백페이스 컬링 정책 고정
  • 무기와 부착물의 포함 여부 고정

Unity에서는 별도 실루엣 셰이더와 RenderTexture를 사용하고 Unreal Engine에서는 SceneCaptureComponent2D와 마스크 전용 머티리얼을 사용할 수 있습니다.

Step 3. 마스크에서 IoU와 경계 거리를 계산한다

아래 예시는 Python, NumPy, OpenCV를 이용해 두 개의 이진 마스크를 비교하는 최소 구현입니다. 실제 파이프라인에서는 엔진이 렌더링한 PNG 또는 EXR 마스크를 입력으로 사용합니다.

import cv2
import numpy as np


def silhouette_metrics(reference_mask, lod_mask):
    ref = (reference_mask > 0).astype(np.uint8)
    lod = (lod_mask > 0).astype(np.uint8)

    intersection = np.logical_and(ref, lod).sum()
    union = np.logical_or(ref, lod).sum()
    iou = float(intersection / union) if union else 1.0

    ref_edge = cv2.Canny(ref * 255, 50, 150) > 0
    lod_edge = cv2.Canny(lod * 255, 50, 150) > 0

    ref_distance = cv2.distanceTransform((~lod_edge).astype(np.uint8), cv2.DIST_L2, 3)
    lod_distance = cv2.distanceTransform((~ref_edge).astype(np.uint8), cv2.DIST_L2, 3)

    ref_to_lod = ref_distance[ref_edge].mean() if ref_edge.any() else 0.0
    lod_to_ref = lod_distance[lod_edge].mean() if lod_edge.any() else 0.0
    chamfer = (ref_to_lod + lod_to_ref) * 0.5

    return {
        'iou': iou,
        'chamfer_pixels': float(chamfer),
        'area_loss': float(1.0 - iou),
    }

실루엣 마스크의 가장자리에 안티앨리어싱이 들어가면 임계값 기준이 흔들릴 수 있습니다. 비교 전에 알파값을 일정 기준으로 이진화하고 모든 LOD 테스트에 동일한 임계값을 적용해야 합니다.

Step 4. 중요 영역을 보존하며 LOD를 다시 생성한다

실루엣 손실이 기준을 넘었다고 해서 전체 메시의 폴리곤을 동일하게 되돌릴 필요는 없습니다. 다음 순서로 자동 보정합니다.

  1. 손실이 발생한 카메라와 포즈를 식별합니다.
  2. 해당 뷰에서 사라진 경계 픽셀을 3D 메시의 본 또는 버텍스 영역으로 역추적합니다.
  3. 얼굴, 손, 무기, 헤어 등 보호 영역의 디시메이션 가중치를 낮춥니다.
  4. 보호 영역 외부에서 삼각형을 추가로 제거합니다.
  5. 새 LOD를 다시 렌더링하고 지표를 재계산합니다.
  6. 최대 반복 횟수 안에 통과하지 못하면 자동 승인 대신 아티스트 검토로 보냅니다.

메시 툴이 영역별 가중치를 지원하지 않는다면 최소한 머티리얼 슬롯, 버텍스 컬러, 본 그룹 또는 별도 서브메시를 보호 마스크로 사용할 수 있습니다. 예를 들어 버텍스 컬러의 R 채널을 실루엣 보호 강도로 정의하고 디시메이션 과정에서 높은 값을 가진 버텍스를 보존하는 방식입니다.

보호 강도 1.0: 얼굴 외곽, 손가락, 무기 끝
보호 강도 0.5: 헤어, 망토, 장식물
보호 강도 0.0: 몸통 내부와 화면에서 거의 보이지 않는 면

Step 5. 결과를 CI와 에셋 리포트에 연결한다

아티스트가 LOD를 수정할 때마다 수동으로 모든 카메라와 포즈를 확인하면 병목이 생깁니다. 다음 결과를 JSON 리포트로 저장하고 에셋 검증 단계에서 실패 여부를 판단합니다.

{
  "asset": "Hero_A",
  "lod": "LOD2",
  "triangle_ratio": 0.42,
  "worst_view": "rear_45_attack",
  "weighted_iou": 0.913,
  "mean_chamfer_pixels": 3.8,
  "status": "review"
}

검증 규칙은 다음처럼 명확하게 구성합니다.

  • weighted_iou가 기준 미만이면 실패
  • mean_chamfer_pixels가 기준 초과이면 검토
  • 특정 보호 영역의 IoU가 개별 기준 미만이면 전체 점수와 관계없이 검토
  • 자동 보정 반복 횟수가 3회를 넘으면 무한 재생성을 중단
  • 기준 메시, 카메라 세트, 렌더 해상도가 변경되면 리포트를 무효화

LOD별 삼각형 수와 실루엣 지표를 보여주는 자동 검증 리포트

IoU만 사용하면 안 되는 이유는 무엇인가?

IoU는 면적 기반 지표이므로 얇은 부위의 손실에 둔감합니다. 캐릭터 전체 실루엣이 10만 픽셀이고 검이 500픽셀이라면 검이 완전히 사라져도 전체 IoU 변화는 작을 수 있습니다.

따라서 다음 조합을 권장합니다.

지표잘 잡아내는 문제한계
전체 IoU큰 실루엣 변화작은 부위 손실에 둔감
영역별 IoU얼굴·손·무기 손실영역 라벨 관리 필요
Chamfer 거리외곽선의 위치 이동노이즈와 안티앨리어싱 영향
Hausdorff 거리최악의 단일 돌출부 오차이상치에 민감
삼각형 비율성능 예산 관리시각 품질을 직접 설명하지 못함

실무에서는 전체 IoU를 기본 합격 조건으로 두고 영역별 IoU와 양방향 평균 Chamfer 거리를 보조 조건으로 사용하는 구성이 균형이 좋습니다. 최악의 단일 외곽선 오차를 제한하려면 평균 Chamfer와 별도로 Hausdorff 거리를 측정합니다.

자동 보정 규칙을 설계할 때 주의할 점

화면 공간 기준을 먼저 정한다

월드 단위의 1cm 오차가 항상 같은 시각적 손실을 의미하지는 않습니다. 카메라에 가까운 캐릭터에서는 작은 오차도 크게 보이고 원거리에서는 같은 오차가 보이지 않을 수 있습니다. 평가 기준은 가능한 한 픽셀 단위 또는 화면 점유율 단위로 정의합니다.

애니메이션 변형을 포함한다

정적 메시에서 통과한 LOD가 스킨 변형 후에는 관절 주변에서 찌그러질 수 있습니다. 특히 어깨, 팔꿈치, 무릎, 망토 본처럼 외곽선이 크게 움직이는 영역은 포즈 샘플에 포함해야 합니다.

백페이스와 투명 재질을 분리한다

머리카락, 속눈썹, 망토처럼 양면 또는 알파 클리핑을 사용하는 자산은 일반 불투명 메시와 같은 기준을 적용하기 어렵습니다. 불투명 실루엣과 알파 실루엣을 별도로 비교하고 투명 재질은 렌더러의 실제 알파 클리핑 설정을 사용해야 합니다.

자동화의 실패 경로를 만든다

모든 문제를 자동 수정하려 하면 메시가 불필요하게 복잡해지거나 UV와 노멀 품질이 훼손될 수 있습니다. 자동 보정은 제한된 반복 횟수와 삼각형 예산 안에서만 수행하고 실패하면 다음 정보를 포함한 리뷰 리포트를 생성합니다.

  • 실패한 LOD와 카메라 방향
  • 실패한 애니메이션 포즈
  • 기준 IoU와 측정 IoU
  • 가장 큰 경계 오차가 발생한 화면 위치
  • 보호 영역별 결과
  • 자동 보정 전후 삼각형 수

Unity와 Unreal Engine에 연결하는 방법

Unity

Unity에서는 AssetPostprocessor 또는 별도 EditorWindow에서 다음 작업을 연결할 수 있습니다.

  1. 모델 임포트 완료 시 LOD 생성
  2. 테스트 포즈를 적용한 임시 프리팹 생성
  3. 실루엣 전용 RenderTexture 캡처
  4. 외부 Python 평가기 또는 C# 이미지 분석기 실행
  5. 결과 JSON 저장과 임포트 실패 표시

런타임 빌드에 평가 코드를 포함하지 않으려면 모든 검증을 에디터 전용 어셈블리로 분리합니다.

Unreal Engine

Unreal Engine에서는 Editor Utility Blueprint, Python API, AssetImportData 또는 커스텀 에디터 플러그인을 조합할 수 있습니다. SkeletalMesh의 LOD 생성 결과를 저장한 뒤 SceneCaptureComponent2D로 기준 메시와 LOD를 동일 조건에서 캡처하면 자동 검증 흐름을 만들 수 있습니다.

Nanite를 사용하는 정적 환경 메시와 달리 스켈레탈 캐릭터는 프로젝트의 스키닝, 애니메이션, 머티리얼 조건을 함께 검토해야 합니다. 따라서 캐릭터 LOD 파이프라인에서는 엔진의 자동 삼각형 감소 결과를 그대로 승인하기보다 실루엣 평가를 별도 게이트로 두는 편이 안전합니다.

자주 묻는 질문 FAQ

Q. 실루엣 비교 해상도는 얼마가 적당한가요?

기본 검증은 256×256 또는 512×512로 시작하고 실제 게임에서 캐릭터가 차지하는 화면 크기에 맞춰 추가 샘플을 두면 됩니다. 중요한 것은 절대 해상도보다 모든 LOD에 같은 해상도와 안티앨리어싱 조건을 적용하는 것입니다.

Q. 기준 IoU는 모든 캐릭터에 동일하게 적용해야 하나요?

권장하지 않습니다. 인간형 캐릭터, 갑옷형 캐릭터, 긴 망토를 가진 캐릭터는 실루엣 민감도가 다릅니다. 공통 최소 기준을 두되 무기·헤어·장식물처럼 중요한 자산 유형에는 별도의 영역별 기준을 추가하는 방식이 적합합니다.

Q. 실루엣 손실이 작으면 삼각형 수를 더 줄여도 되나요?

가능하지만 GPU 비용만으로 결정하면 안 됩니다. 버텍스 셰이더 비용, 스키닝 본 수, 머티리얼 슬롯, 그림자 패스와 함께 확인해야 합니다. 실루엣 점수가 통과하더라도 드로 콜과 스킨닝 비용이 병목이면 다른 최적화가 필요합니다.

정리

캐릭터 LOD 품질은 삼각형 수가 아니라 화면에서 유지되는 형태로 평가해야 합니다. 동일한 카메라와 포즈로 실루엣을 렌더링하고 전체 IoU, 영역별 IoU, 경계 Chamfer 거리를 함께 측정하면 LOD 단계 전환에서 발생하는 시각적 손실을 재현 가능한 수치로 바꿀 수 있습니다.

최종 파이프라인은 LOD 생성 → 마스크 렌더링 → 지표 계산 → 중요 영역 자동 보존 → 재검증 → 리포트 저장의 순서로 구성합니다. 이 검증을 에셋 임포트나 CI 단계에 연결하면 아티스트의 감각을 대체하는 것이 아니라 반복적인 확인 작업을 줄이고 중요한 판단에 집중할 수 있습니다.