Unity Term Book
그래픽 & 이펙트

Culling

Culling은 카메라가 못 보는 것을 그리지 않아 draw call을 줄입니다. Frustum·Occlusion·LOD·Backface와 layerCullDistances를 익히면 실내외 장면에서 배치와 삼각형 수를 통제할 수 있습니다. Unity 렌더링 최적화의 핵심 가이드입니다.

상상해 보세요...

Culling은 똑똑한 무대 감독자와 같습니다. 무대 위 모든 배우에게 조명을 켜지 않고, 객석에서 보이는 배우만 비춥니다. 커튼 뒤? 불 끔. 각도 밖? 불 끔. GPU는 그들에 대해 듣지조차 않습니다 — 매 프레임 수천 draw call을 아낍니다.

개념 자세히

Frustum Culling이 기본입니다 — Unity가 카메라 frustum( FOV·near/far clip의 잘린 피라미드)의 여섯 평면을 각 Renderer의 bounding box와 검사합니다. bounds가 완전히 밖이면 → draw call 스킵. 내장, 항상 켜짐, 설정 불필요.

Occlusion Culling은 다음 단계 — frustum 안이지만 완전히 가려진 오브젝트를 스킵합니다. Unity가 bake로 occlusion 데이터(Umbra)를 미리 계산합니다: Window → Rendering → Occlusion Culling → Bake. Static 드롭다운에서 occluder/occludee를 표시합니다. 실내에 강하고 오픈월드에는 약합니다.

LOD (Level of Detail)는 관련 기법 — 완전히 cull하는 대신 LOD Group이 거리에 따라 메시 복잡도를 낮춥니다. LOD0 = 풀 디테일(가까움), LOD1 = 중간, LOD2 = 단순, LOD3 = billboard, Culled = 숨김. 거리별 품질/성능 트레이드오프.

Backface Culling은 GPU 수준 — 카메라에서 멀어지는 normal을 가진 삼각형을 버립니다. 모든 셰이더에서 기본 켜져 closed mesh의 fragment 작업을 ~50% 절약합니다. Material의 “Two Sided” 또는 ShaderLab의 Cull Off로 끌 수 있습니다.

Culling 유형

📐

Frustum Culling

카메라 시야 밖 오브젝트는 완전히 건너뜁니다. 자동. 설정 불필요. 모든 프로젝트에서 유효.

Camera.layerCullDistances[]

🏗️

Occlusion Culling

벽/건물에 가려진 오브젝트는 건너뜁니다. 베이크 필요 하고 Static으로 표시. 실내 씬에 최적.

Static → Occluder/Occludee

📏

LOD Group

카메라에서 멀면 폴리곤 수를 줄입니다. LOD0→LOD3→Culled. 미리 준비해야 함 여러 메시. 오픈 월드에 적합.

LODGroup component

실습 단계

1

Frustum Culling: Camera Far Clip 줄이기

Camera → Far Clip Plane: 1000에서 200–500으로 낮춰 먼 오브젝트를 cull. 끊김은 fog로 가립니다.

2

Occlusion Culling용 Static 표시

벽/바닥/천장 선택 → Inspector → Static → Occluder Static과 Occludee Static.

3

occlusion 데이터 Bake

Window → Rendering → Occlusion Culling → Bake. Occlusion Area로 bake 볼륨을 제어합니다.

4

LOD Group 추가

Add Component → LOD Group → 각 슬롯에 LOD0/1/2 메시를 넣고 % screen size를 조절합니다.

5

Rendering Statistics로 측정

Game View → Stats: 카메라 이동 시 "Batches"와 "Tris"를 봅니다. Scene view의 Occlusion Culling Visualization.

인터랙티브 시뮬레이터

카메라를 씬 주위로 돌려 frustum-cull과 occlusion-cull되는 오브젝트를 보세요.

Visible: 0

Culled: 0

Visible Frustum Culled Occlusion Culled

코드 예제

기본

레이어별 cull 거리 설정과 renderer 가시성 확인.

using UnityEngine;

public class CullingSetup : MonoBehaviour
{
  void Start()
  {
      Camera cam = Camera.main;

      // Per-layer cull distance
      // 32 entries (32 layers) — 0 = use Far Clip
      float[] distances = new float[32];
      distances[8]  = 50f;   // Layer 8 "SmallProps": cull after 50m
      distances[9]  = 150f;  // Layer 9 "MediumProps": cull after 150m
      distances[10] = 0f;    // Layer 10: use Camera.farClipPlane
      cam.layerCullDistances = distances;

      // Spherical culling: from camera center, not frustum planes
      cam.layerCullSpherical = true;
  }

  // Is this renderer currently visible to a camera?
  void CheckVisibility(Renderer rend)
  {
      if (rend.isVisible)
          Debug.Log(rend.name + " is being rendered");
  }
}

코드 예제

고급

코드로 LOD Group을 구성하고 LOD 레벨을 강제(디버그 / 컷신).

using UnityEngine;

public class DynamicLOD : MonoBehaviour
{
  public Renderer[] lod0, lod1, lod2;
  LODGroup group;

  void Awake()
  {
      group = GetComponent<LODGroup>();
      if (group == null)
          group = gameObject.AddComponent<LODGroup>();

      // Configure LOD levels from code
      LOD[] lods = new LOD[3];
      lods[0] = new LOD(0.5f, lod0);  // 50%+ screen → LOD0
      lods[1] = new LOD(0.15f, lod1); // 15-50% → LOD1
      lods[2] = new LOD(0.03f, lod2); // <3% → LOD2, <0 → culled
      group.SetLODs(lods);
      group.RecalculateBounds();
  }

  // Force a specific LOD (debug or cutscene close-up)
  public void ForceLOD(int level)
  {
      group.ForceLOD(level); // -1 = disable force, use automatic
  }
}

📌 빠른 정리

  • Frustum Culling: 자동, 설정 불필요
  • Occlusion Culling: bake 필요, 실내에 최적
  • LOD Group: 거리에 따라 폴리 수 감소
  • layerCullDistances: 레이어별 cull 범위
  • renderer.isVisible: 렌더 중이면 true

⚠️ 흔한 실수

  • ❌ Occlusion bake했는데 아무것도 cull 안 됨

    Camera → Occlusion Culling = true를 잊음

    ✅ Camera Inspector → Rendering → Occlusion Culling 체크

  • ❌ LOD pop(줌할 때 메시가 확 바뀜)

    LOD 전환이 너무 넓고 LOD Fade 없음

    ✅ LOD Group에서 "Fade Mode = Cross Fade"로 블렌드