Phase 8: 최적화와 실전 워크플로우 | 예상 학습 시간: 35분


🎯 학습 목표

  • VR/AR이 일반 3D 프로젝트보다 훨씬 엄격한 성능 예산을 요구하는 이유를 설명할 수 있다
  • 타깃 기기별 폴리곤/드로우콜/텍스처 예산을 고려해 3D 에셋을 설계할 수 있다
  • 실제 크기(Real-world Scale)와 콜라이더 설계가 몰입감과 상호작용에 미치는 영향을 이해한다
  • AR 프로젝트에서 Occlusion, Light Estimation 등 3D 모델에 추가로 요구되는 고려사항을 설명할 수 있다

1. VR/AR 3D 에셋이 일반 3D 프로젝트와 다른 이유

지금까지 다룬 최적화(Day 50~53의 배칭, 프로파일링, 모바일 최적화, 텍스처 아틀라스)는 모두 “일반 화면 출력"을 전제로 했습니다. VR/AR은 여기에 훨씬 가혹한 제약이 추가됩니다.

  • 스테레오 렌더링(Stereo Rendering): 양쪽 눈에 각각 다른 시점을 렌더링해야 하므로, 이론적으로는 씬을 2번 그려야 합니다. Unity의 Single Pass Instanced 렌더링으로 드로우콜 자체는 줄일 수 있지만, GPU가 처리해야 하는 최종 픽셀/버텍스 연산량은 여전히 모노 렌더링보다 큽니다.
  • 높은 프레임레이트 요구: 일반 모바일 게임은 3060fps면 충분하지만, VR은 어지러움(멀미)을 막기 위해 최소 72fps(Quest 2), 90120fps(PCVR, Quest 3)를 유지해야 합니다. 프레임이 떨어지면 단순히 “버벅임"이 아니라 사용자가 실제로 메스꺼움을 느끼는 수준의 문제가 됩니다.
  • 독립형(Standalone) 기기의 모바일급 하드웨어: Quest 시리즈처럼 널리 쓰이는 독립형 VR 기기는 내부적으로 모바일 SoC를 사용합니다. Day 52에서 다룬 모바일 최적화 기법(폴리곤 감소, 텍스처 압축, 드로우콜 최소화)이 VR에서는 “선택"이 아니라 “필수"가 됩니다.
  • AR의 실세계 정합(Registration): AR은 3D 모델을 실제 공간의 스케일/조명/그림자와 자연스럽게 어우러지도록 배치해야 하므로, 모델링 단계에서부터 추가 고려사항이 생깁니다.
구분일반 모바일/PC 게임VRAR
목표 프레임레이트30~60fps72~120fps (기기별 고정)30~60fps (기기 카메라 처리 병행)
렌더링 시점 수1개2개(스테레오)1개 + 실세계 합성
프레임 드랍 시 체감화면이 끊김멀미/어지러움 유발트래킹 오차, 몰입감 저하
하드웨어다양(고사양 포함)대부분 모바일급 SoC(Standalone)스마트폰/태블릿 SoC

💡 실무 팁: VR 프로젝트를 시작할 때 가장 먼저 확인해야 할 것은 타깃 기기의 “고정 프레임레이트"입니다. 이 값은 옵션이 아니라 하드웨어/OS 레벨에서 강제되는 경우가 많아서, 이 프레임을 못 맞추면 프레임을 드랍하는 게 아니라 화면 전체가 버벅이는 형태로 나타납니다.


2. 기기별 폴리곤/드로우콜 예산 설계하기

VR/AR 3D 모델링은 “예쁘게 만들고 나중에 최적화"가 아니라, 예산을 먼저 정하고 그 안에서 모델링하는 접근이 필요합니다. Day 27에서 다룬 LOD 개념과 Day 50의 드로우콜 개념을 VR/AR 기준으로 다시 적용해야 합니다.

기기(예시)씬 전체 권장 폴리곤(삼각형)드로우콜 예산(씬 전체)비고
Quest 2 (Standalone)50,000 ~ 100,00050~100모바일 SoC, 발열/배터리 제약
Quest 3 (Standalone)150,000 ~ 300,000100~150Quest 2 대비 GPU 성능 향상
PCVR (RTX급 GPU)500,000 이상 가능200~300+스테레오라도 데스크톱 GPU 여유 있음
모바일 AR (스마트폰)50,000 ~ 150,00050~100카메라 패스스루/트래킹 연산과 GPU 자원 공유

이 수치는 절대 기준이 아니라 “이 정도를 넘기면 프로파일링이 필수"라는 경고선으로 이해해야 합니다. Day 51에서 다룬 Profiler의 Rendering 항목으로 실제 기기에서 프레임 타임을 반드시 측정해야 합니다.

// VR/AR에서는 오브젝트별 폴리곤 수를 코드로 미리 점검해두는 것이 유용합니다.
using UnityEngine;

public class PolyBudgetChecker : MonoBehaviour
{
    [SerializeField] private int maxTrianglesPerObject = 5000;

    void Start()
    {
        MeshFilter mf = GetComponent<MeshFilter>();
        if (mf != null && mf.sharedMesh != null)
        {
            int triCount = mf.sharedMesh.triangles.Length / 3;
            if (triCount > maxTrianglesPerObject)
            {
                Debug.LogWarning($"{name}: 삼각형 {triCount}개 — 예산({maxTrianglesPerObject}) 초과");
            }
        }
    }
}

💡 실무 팁: VR 컨트롤러로 직접 손에 쥐는 소품(무기, 도구 등)은 눈앞 가까이서 관찰되므로 배경 오브젝트보다 상대적으로 높은 폴리곤 예산을 배정하고, 반대로 먼 배경/장식용 오브젝트는 과감히 낮춰야 전체 예산을 지킬 수 있습니다.


3. 텍스처와 메모리 — VR/AR 전용 고려사항

Day 52~53에서 다룬 텍스처 압축(ASTC/ETC2)과 아틀라싱은 VR/AR에서 그대로 적용되지만, 몇 가지가 더 추가됩니다.

  • 스테레오 렌더링으로 인한 텍스처 대역폭 2배 부담: 양쪽 눈을 그리는 동안 같은 텍스처를 반복 샘플링하므로, 텍스처 해상도를 무작정 높이면 대역폭 병목이 배로 커집니다. VR용 텍스처는 동일한 시각 품질이라면 일반 모바일 게임보다 한 단계 낮은 해상도(예: 2048 대신 1024)로도 체감 차이가 크지 않은 경우가 많습니다.
  • 밉맵(Mipmap) 필수 적용: VR은 사용자가 머리를 움직이며 다양한 거리에서 오브젝트를 보게 되므로, 밉맵을 끄면 텍스처 앨리어싱(반짝임)이 특히 눈에 띕니다. Import Settings에서 Generate Mip Maps를 반드시 활성화합니다.
  • Fixed Foveated Rendering(FFR) 대응: Quest 등 일부 기기는 화면 중심부만 고해상도로, 주변부는 저해상도로 렌더링하는 FFR을 지원합니다. FFR을 활용하면 같은 텍스처/폴리곤 예산으로도 체감 품질을 높일 수 있으므로, XR 플러그인 설정에서 Foveation Level을 확인해두는 것이 좋습니다.
  • 라이트맵 크기 제한: Day 38에서 다룬 라이트맵 베이킹은 VR Standalone 기기에서 메모리를 크게 잡아먹습니다. 라이트맵 해상도를 낮추고, Day 53의 Memory Profiler로 라이트맵이 차지하는 메모리를 별도로 점검해야 합니다.
항목일반 모바일 권장VR Standalone 권장
주요 텍스처 해상도1024~2048512~1024
밉맵선택적필수
라이트맵 해상도중간~높음낮음(동적 라이트 병행 고려)
알파 블렌딩(투명) 오브젝트 수제한적 허용최소화(오버드로우가 스테레오로 배가)

💡 실무 팁: 반투명(Alpha Blend) 머티리얼은 일반 프로젝트에서도 오버드로우 비용이 크지만, VR에서는 양쪽 눈 렌더링으로 그 비용이 그대로 두 배가 됩니다. 파티클, 이펙트, UI 배경 등에서 반투명 사용을 최소화하고 가능하면 Cutout(알파 테스트) 방식으로 대체하는 것이 좋습니다.


4. 실제 크기(Real-world Scale)와 상호작용 콜라이더 설계

VR/AR은 일반 화면 게임과 달리 사용자가 실제 물리적 공간감으로 크기를 인식합니다. 이 때문에 모델링/임포트 단계에서의 스케일 정확성이 몰입감에 직접적인 영향을 미칩니다.

  • 1 유닛 = 1미터 원칙 엄수: Day 23에서 다룬 Import Scale 설정이 VR/AR에서는 특히 중요합니다. 문 손잡이가 실제보다 크거나 작게 임포트되면, 사용자가 VR 컨트롤러로 손을 뻗었을 때 손과 오브젝트 크기가 어긋나는 위화감(Uncanny Scale)을 즉시 느낍니다.
  • 손 상호작용을 고려한 콜라이더 단순화: XR Interaction Toolkit 등으로 오브젝트를 잡을 때는 시각 메시(Visual Mesh)를 그대로 Mesh Collider로 쓰지 말고, Day 09에서 다룬 것처럼 Box/Capsule/Convex Mesh Collider로 단순화해야 합니다. 특히 Rigidbody가 붙는 그랩 오브젝트는 Convex 옵션이 꺼진 비-Convex Mesh Collider를 사용할 수 없습니다.
using UnityEngine;

[RequireComponent(typeof(Rigidbody))]
public class VRGrabbable : MonoBehaviour
{
    void Awake()
    {
        MeshCollider mc = GetComponent<MeshCollider>();
        if (mc != null && !mc.convex)
        {
            // Rigidbody + Mesh Collider 조합은 반드시 Convex가 필요합니다.
            Debug.LogWarning($"{name}: Rigidbody와 함께 쓰는 MeshCollider는 Convex여야 합니다.");
        }
    }
}
  • AR에서의 실세계 스케일 매칭: AR Foundation으로 배치되는 3D 모델은 실제 테이블, 바닥 등의 물리적 크기와 맞아야 하므로, 모델링 단계에서부터 실측 치수를 기준으로 작업하는 것이 필수입니다. 스케일이 어긋나면 아무리 텍스처와 라이팅이 훌륭해도 “합성된 느낌"이 강하게 남습니다.
상황권장 콜라이더
정적 배경 오브젝트(벽, 바닥)Mesh Collider(비-Convex 가능, Rigidbody 없음)
손으로 잡는 소품(Rigidbody 있음)Box/Capsule 또는 Convex Mesh Collider
복잡한 형태의 그랩 오브젝트여러 개의 단순 Primitive Collider를 조합(Compound Collider)

💡 실무 팁: VR에서 “손에 쥐는 손맛"은 콜라이더의 정밀도보다 오히려 그립 애니메이션과 햅틱 피드백의 타이밍이 좌우하는 경우가 많습니다. 콜라이더는 상호작용이 자연스럽게 “걸리는” 수준으로 단순화하고, 나머지 디테일은 시각/햅틱 연출로 보완하는 편이 성능과 개발 효율 면에서 유리합니다.


5. AR 특화 고려사항 — Occlusion과 조명 정합

AR은 VR과 달리 실제 카메라 영상 위에 3D 모델을 합성하기 때문에, 3D 모델 자체의 품질과 별개로 “실세계와 얼마나 자연스럽게 섞이는가"가 중요합니다.

  • Occlusion(가려짐) 처리: 실제 사물(사람의 손, 가구 등)이 AR 오브젝트 앞을 지나갈 때 자연스럽게 가려져야 합니다. AR Foundation의 AROcclusionManager를 사용하면 기기의 깊이 센서/ML 기반 깊이 추정값을 활용해 실세계 깊이와 3D 모델의 깊이를 비교, 자동으로 가려짐을 처리할 수 있습니다.
  • Light Estimation(조명 추정): 실제 환경의 밝기/색온도를 추정해 3D 모델의 라이팅에 실시간으로 반영해야 위화감이 줄어듭니다. ARCameraManager.frameReceived 이벤트로 밝기 정보를 받아 씬의 Directional Light 강도를 동적으로 조정하는 방식이 흔히 쓰입니다.
  • 그림자 정합: AR 모델이 바닥에 그림자를 드리우지 않으면 공중에 떠 있는 듯한 위화감이 생깁니다. Shadow-only 머티리얼(오브젝트 자체는 투명하고 그림자만 렌더링)을 바닥 평면에 적용하는 기법이 자주 사용됩니다.
  • Plane Detection과 모델 스케일 검증: ARPlaneManager로 감지된 실제 평면 크기에 맞춰 모델이 배치되는지 런타임에 검증하는 것이 좋습니다.
using UnityEngine;
using UnityEngine.XR.ARFoundation;

public class ARLightSync : MonoBehaviour
{
    [SerializeField] private ARCameraManager cameraManager;
    [SerializeField] private Light directionalLight;

    void OnEnable() => cameraManager.frameReceived += OnFrameReceived;
    void OnDisable() => cameraManager.frameReceived -= OnFrameReceived;

    void OnFrameReceived(ARCameraFrameEventArgs args)
    {
        if (args.lightEstimation.averageBrightness.HasValue)
        {
            directionalLight.intensity = args.lightEstimation.averageBrightness.Value;
        }
        if (args.lightEstimation.colorCorrection.HasValue)
        {
            directionalLight.color = args.lightEstimation.colorCorrection.Value;
        }
    }
}

💡 실무 팁: AR에서는 3D 모델의 폴리곤/텍스처 품질을 아무리 높여도, Occlusion과 그림자가 빠지면 “합성 스티커"처럼 보입니다. 리소스가 제한적이라면 고품질 모델링보다 Occlusion/그림자 정합에 우선 투자하는 것이 체감 품질 향상에 더 효과적입니다.


📝 핵심 요약

  1. VR은 스테레오 렌더링과 고정 프레임레이트(72~120fps) 요구로 인해 일반 모바일 게임보다 훨씬 엄격한 폴리곤/드로우콜 예산이 필요하다
  2. 기기별(Quest 2/3, PCVR, 모바일 AR) 폴리곤·드로우콜 예산을 먼저 정하고 그 안에서 모델링해야 하며, 손에 쥐는 오브젝트는 상대적으로 높은 예산을 배정한다
  3. VR용 텍스처는 스테레오 대역폭 부담을 고려해 해상도를 낮추고 밉맵을 필수로 적용하며, 반투명 오브젝트는 최소화해야 한다
  4. 1 유닛 = 1미터 원칙과 콜라이더 단순화(Convex Mesh Collider 등)는 VR의 몰입감과 상호작용 품질에 직접적인 영향을 준다
  5. AR은 Occlusion, Light Estimation, 그림자 정합처럼 3D 모델 자체보다 “실세계와의 정합"이 체감 품질을 좌우하는 경우가 많다

🔗 참고 자료


⬅️ 이전: Day 53 — 텍스처 아틀라스와 메모리 최적화 | 다음: Day 55 — 에셋 파이프라인 자동화 (네이밍 규칙, 임포트 프리셋) ➡️