본문 바로가기

그림자 옵션과 성능 최적화

정적·동적 그림자 옵션과 해상도·거리·캐스케이드 비용을 비교해 공간감과 목표 프레임 사이의 균형을 맞춥니다.

광원을 배치했다면 이제 조명의 완성도를 좌우하는 그림자를 다룰 차례입니다. 그림자는 공간의 깊이와 사실감을 만드는 핵심 요소지만, 동시에 렌더링에서 비용이 큰 항목이기도 합니다. 품질만 높이면 프레임이 무너지고, 성능만 보면 화면이 납작하고 어색해지는 일이 흔합니다.

이 글에서는 그림자가 장면에서 하는 일을 먼저 정리하고, Static, Stationary, Movable 광원의 그림자가 어떻게 만들어지는지 비교합니다. 그다음 그림자 비용을 줄이는 방법을 하나씩 살펴보고, 미리 계산하는 조명을 쓸 때의 라이트 빌드 과정을 정리합니다. 그림자 옵션을 상황에 맞게 고르는 기준을 세우는 것이 목표입니다.


그림자가 하는 일

그림자는 빛이 물체에 가려질 때 생기며, 3D 공간을 알아보는 데 큰 역할을 합니다. 그림자는 물체의 위치와 주변과의 관계를 보여 주어 장면에 깊이감을 줍니다. 물체가 바닥에 닿아 있는지, 공중에 떠 있는지는 그림자를 보고 알 수 있습니다. 또 복잡한 형태를 더 분명하게 드러내고, 실제 세계처럼 빛과 그림자가 함께 있어 장면을 사실적으로 보이게 합니다.

그림자는 플레이에 필요한 단서도 됩니다. 모퉁이 너머의 적이 드리운 그림자로 위협이 다가오는 것을 알리거나, 중요한 물체가 있다는 것을 알려 줄 수 있습니다. 언리얼 엔진은 그림자를 여러 방식으로 만들며, 방식마다 성능과 품질에 주는 영향이 다릅니다.


이동성에 따른 그림자 방식

그림자가 만들어지는 방식은 광원의 이동성과 프로젝트의 그림자 방식(Shadow Map Method)을 함께 봐야 알 수 있습니다. 아래의 미리 굽는 조명 설명은 프로젝트가 정적 조명을 허용하는 경우를 전제로 하며, 루멘 글로벌 일루미네이션을 쓰면 미리 구운 라이트맵은 쓰이지 않습니다. 또 그림자 방식을 가상 섀도 맵(Virtual Shadow Maps, VSM)으로 정하면, 기존의 캐스케이드 섀도 맵(Cascaded Shadow Maps, CSM)과 Stationary 광원의 여러 그림자 방식이 VSM으로 대체됩니다.

Static 광원의 그림자

Static 광원은 빛과 그림자의 정보를 에디터에서 미리 계산해 굽고(bake), 라이트맵(lightmap)이라는 텍스처에 저장합니다. 실행 중에는 이 저장된 정보를 그대로 쓰므로, 실시간으로 빛과 그림자를 계산하는 비용이 줄어듭니다. 다만 라이트맵을 저장하는 메모리와 읽어 오는 비용은 남습니다.

장점은 두 가지입니다. 고정된 조명의 실행 중 계산을 줄일 수 있고, 복잡한 간접광과 부드러운 그림자를 시간을 들여 미리 계산하므로 사실적인 결과를 얻기 쉽습니다. 단점은 구운 조명이 실행 중의 변화에 맞춰 다시 계산되지 않는다는 것입니다. 문이 열리거나 물체가 움직여도 그림자는 굽던 때 그대로 남습니다. 또 조명을 바꿀 때마다 라이트 빌드(light build)를 다시 해야 합니다.

광원 하나가 굽는 결과에 주는 영향은 디테일 패널의 두 항목에서 조절합니다. Light 항목의 Indirect Lighting Intensity는 그 광원이 주는 간접광의 배율이고, 그 아래 Lightmass 항목의 Indirect Lighting Saturation은 라이트매스에서 그 광원이 주는 간접광의 채도입니다. 빛이 몇 번 튕길지를 정하는 반사 횟수는 광원별 속성이 아니라, World Settings의 Lightmass에 있는 Num Indirect Lighting Bounces에서 레벨 전체에 대해 정합니다. Static 광원은 움직이지 않는 건물 안의 고정 조명이나 배경 오브젝트에 씁니다.

Stationary 광원의 그림자

Stationary 광원은 간접광은 미리 굽고, 직접광은 실시간으로 계산합니다. 기존 섀도 맵 방식에서는 움직이지 않는 물체의 그림자는 미리 계산해 두고, 움직이는 물체의 그림자는 실시간으로 만들어 둘을 합칩니다. 그래서 태양 같은 주 광원 아래에서 캐릭터가 움직여도 그림자가 자연스럽게 따라가면서, 구운 간접광의 효율도 함께 얻을 수 있습니다.

다만 한 지오메트리에 겹쳐 영향을 주는 Stationary 광원은 정적 그림자를 저장하는 채널 수 때문에 최대 4개로 제한될 수 있습니다. 이것은 광원 하나가 그림자를 네 개만 만든다는 뜻이 아니라, 한 곳에 동시에 겹치는 Stationary 광원의 수에 대한 제한입니다. 또 Static 광원만 쓴 장면에 실시간 직접광과 그림자를 더하는 만큼 비용이 늘 수 있고, 여전히 라이트 빌드가 필요합니다. 실제 비용은 광원의 범위와 캐시, 그림자 방식에 따라 다르므로, Static과 Stationary라는 이름만 보고 전체 프레임의 순위를 정하지는 않습니다.

디렉셔널 라이트를 Stationary로 쓸 때는 캐스케이드 섀도 맵 설정이 중요합니다. 캐스케이드 섀도 맵은 카메라에서 가까운 곳부터 먼 곳까지를 여러 단계(cascade)로 나누고, 가까운 단계일수록 촘촘한 그림자 맵을 쓰는 방식입니다. Dynamic Shadow Distance Movable Light와 Dynamic Shadow Distance Stationary Light는 실시간 그림자를 그릴 최대 거리로, 멀수록 비용이 커집니다. Num Dynamic Shadow Cascades는 몇 단계로 나눌지이고, Distribution Exponent는 단계 사이의 거리를 어떻게 나눌지입니다. 이 설정들은 아래의 최적화에서 다시 봅니다. Stationary 광원은 야외의 태양이나 실내의 주요 천장 조명처럼 레벨의 주요 광원에 씁니다.

Movable 광원의 그림자

Movable 광원은 모든 빛과 그림자를 실시간으로 계산하므로 빌드 과정이 필요 없습니다. 가장 유연한 방식이라 움직이는 물체와 움직이는 광원에 모두 대응하지만, 고른 그림자 방식의 해상도와 캐시, 필터링의 한계는 그대로 남습니다.

그림자를 만드는 Movable 광원이 넓게 겹치면 비용이 크게 늘 수 있습니다. 그렇다고 이동성의 이름만으로 실제 프레임 비용의 순위를 정할 수는 없습니다. 또 정교한 간접광을 표현하기 어렵거나, 표현하려면 루멘 같은 추가 비용이 듭니다. Movable 광원에는 Lightmass 설정이 없고, 기존 섀도 맵 방식의 Shadow Bias나 Shadow Filter Sharpen 같은 옵션과 VSM 전용 설정은 서로 다른 것이므로 구분해서 봅니다. Movable 광원은 플레이어의 손전등, 차량 전조등, 폭발 효과, 낮과 밤이 바뀌는 시스템의 태양과 달처럼 실행 중의 움직임이 꼭 필요한 곳에 씁니다.

더 깊이: 가상 섀도 맵은 높은 해상도를 어떻게 감당하나

가상 섀도 맵 문서는 VSM을 개념적으로 아주 높은 해상도의 섀도 맵이라고 설명합니다. 현재 구현의 가상 해상도는 16k × 16k 픽셀이고, 디렉셔널 라이트에는 클립맵(clipmap)을 더해 해상도를 더 높입니다. 이 크기를 통째로 그리지 않도록 VSM은 섀도 맵을 128 × 128 크기의 페이지(page)로 나누고, 깊이 버퍼를 분석해 화면에 보이는 픽셀의 그림자에 필요한 페이지만 할당해 그립니다. 그린 페이지는 다음 프레임에도 캐시해 다시 쓰며, 물체나 광원이 움직이면 그 페이지가 무효화됩니다.

이 캐시 구조 때문에 VSM의 비용은 장면이 얼마나 움직이는지에 크게 좌우됩니다. 예를 들어 낮과 밤을 표현하려고 디렉셔널 라이트를 매 프레임 돌리면, 광원이 움직였으므로 캐시된 페이지를 그대로 다시 쓰기 어렵습니다. 또 문서는 VSM이 나나이트와 함께 쓰도록 설계되었으므로, 대상 플랫폼이나 프로젝트가 나나이트를 쓰지 않는다면 VSM이 잘 맞지 않을 수 있다고 설명합니다. 반대로 나나이트를 쓰는 프로젝트라면 Stationary 광원과 기존 섀도 맵의 조합이 지원되지 않으므로, Movable 광원을 쓰거나 VSM을 써야 합니다.


그림자 비용 줄이기

그림자는 성능 병목의 주요 원인 가운데 하나라서, 어디서 비용을 줄일지 차례대로 정해 두면 좋습니다. 아래 순서는 화면에서 잃는 것이 적은 방법부터입니다. 먼저 눈에 띄지 않는 그림자를 끄고 그림자 계산에 들어가는 범위를 줄인 뒤, 그래도 부족할 때 디렉셔널 라이트의 캐스케이드와 그림자 해상도를 조절합니다. 해상도를 먼저 낮추면 중요한 그림자까지 함께 흐려지지만, 앞의 두 방법은 보이지 않거나 필요 없는 계산만 덜어 내기 때문입니다.

필요 없는 그림자 끄기

너무 작아서 그림자가 거의 보이지 않거나, 중요한 시각 정보를 주지 않는 오브젝트는 그림자를 드리우지 않게 합니다. 액터를 선택하고 디테일 패널의 Rendering 항목에서 Cast Shadows를 끄면, 그림자를 그리는 단계에서 그 오브젝트가 빠지므로 그리기 호출이 줄고 그림자 렌더링 부담도 줄어듭니다.

Cast Shadows는 메시 컴포넌트와 광원 양쪽에 있다는 점에 주의합니다. 메시에서 끄면 그 메시가 만드는 그림자만 없어지고, 광원에서 끄면 그 광원이 만드는 그림자가 모두 없어집니다. 어느 쪽을 끄느냐에 따라 사라지는 범위가 다르므로, 한 항목씩 바꿔 비교합니다.

감쇠 반경 줄이기

포인트 라이트와 스포트 라이트의 Attenuation Radius는 필요한 만큼만 작게 정합니다. 빛의 영향 범위가 넓을수록 더 많은 오브젝트가 그림자 계산에 들어가 비용이 커지기 때문입니다. 시각적으로 의미 있는 범위 안에서 반경을 제한하면 쓸데없는 계산이 줄어듭니다.

캐스케이드 섀도 맵 조절하기

다음 설정은 기존 섀도 맵 방식에서 Stationary나 Movable 디렉셔널 라이트에 적용됩니다. VSM을 쓰는 프로젝트라면 그림자 품질 문제를 이 설정으로 고치려 해서는 안 됩니다.

먼저 Dynamic Shadow Distance Movable Light와 Dynamic Shadow Distance Stationary Light로 실시간 그림자를 그릴 최대 거리를 정합니다. 플레이어가 멀리 있는 그림자까지 볼 필요가 없다면 이 값을 줄여 성능을 확보합니다.

다음은 Num Dynamic Shadow Cascades입니다. 단계가 많을수록 멀리까지 그림자 품질이 좋아지지만 비용도 늘어납니다. 지원하는 단계 수와 예산은 플랫폼과 렌더링 경로에 따라 다르므로, 가까운 그림자와 먼 그림자가 바뀌는 지점도 함께 봅니다.

Distribution Exponent는 단계들을 거리에 어떻게 나눠 줄지 정합니다. 값이 1이면 각 단계의 해상도에 비례하는 거리에서 단계가 바뀌고, 1보다 크게 하면 단계가 바뀌는 지점이 카메라 쪽으로 당겨져 가까운 영역에 해상도가 더 모입니다. 이 값을 조절하면 가까운 그림자의 품질을 지키면서 먼 그림자의 비용을 줄일 수 있습니다.

그림자 해상도 조절하기

기존 섀도 맵 방식에서는 광원의 Shadow Resolution Scale처럼 그 방식이 지원하는 옵션으로 해상도를 정합니다. 주요 광원에는 높은 해상도를, 보조 광원이나 작고 덜 중요한 광원에는 낮은 해상도를 씁니다. VSM은 그림자를 작은 페이지 단위로 나눠 필요한 곳만 갱신하므로, 해상도와 페이지 비용은 VSM 전용 시각화와 설정으로 따로 확인합니다.

비용이 드는 시점 구분하기

그림자를 만드는 방법마다 비용이 드는 시점이 다릅니다. 라이트매스(Lightmass) 품질은 주로 굽는 시간과 저장되는 결과에 영향을 주고, 하드웨어 레이 트레이싱 그림자는 실행 중의 GPU 비용에 영향을 줍니다. 서로 다른 때에 드는 비용이므로, 하나의 성능 옵션처럼 취급하지 않습니다.


라이트 빌드 실행하기

미리 계산하는 조명을 쓰는 레벨에서는 바뀐 조명 정보를 반영하려면 라이트 빌드를 다시 해야 합니다. 루멘 글로벌 일루미네이션의 동적 결과를 만드는 데 필요한 단계는 아닙니다.

위쪽의 Build 메뉴를 열고 Build Lighting Only를 고르면 빌드가 시작됩니다. 같은 메뉴의 Lighting Quality에서 Preview, Medium, High, Production 같은 빌드 품질을 고를 수 있는데, 품질이 높을수록 결과가 좋지만 빌드 시간도 길어집니다. 빌드가 끝나면 그림자가 레벨에 제대로 적용되었는지 확인합니다. 작은 변경은 Preview 품질로 빠르게 확인하고, 최종 빌드에서만 Production 품질을 쓰면 시간을 아낄 수 있습니다.

라이트맵을 만드는 빌더에는 CPU로 계산하는 CPU 라이트매스와 GPU로 계산하는 GPU 라이트매스가 있습니다. 둘은 쓰는 자원과 지원하는 설정이 다르므로, 프로젝트가 어느 빌더를 쓰는지 확인합니다.


품질을 낮추기 전에 정할 것

그림자 품질을 낮추기 전에는 먼저 지켜야 할 그림자를 정합니다. 캐릭터가 바닥에 닿아 있다는 느낌을 주는 그림자나, 점프할 거리를 가늠하게 하는 그림자처럼 플레이에 필요한 것들입니다. 그다음 필요 없는 그림자를 만드는 오브젝트, 광원의 반경, 쓰는 그림자 방식의 거리와 해상도 순서로 하나씩 바꾸고, 같은 카메라 경로에서 비교합니다.

메시의 설정과 광원의 설정이 어떻게 다른지는 작은 실험으로 확인할 수 있습니다. 큐브 A와 B를 포인트 라이트 하나 아래에 두고, 먼저 A의 메시 컴포넌트에서만 Cast Shadows를 끈 뒤 비교합니다. A의 그림자는 사라지지만 B의 그림자는 그대로 남고, A의 표면도 여전히 빛을 받아 밝게 보입니다. 원래 값으로 되돌린 다음 이번에는 광원의 Cast Shadows를 끄면, 그 광원이 만드는 A와 B의 그림자가 모두 사라집니다. 즉 메시가 그림자를 만드는지와 표면이 빛을 받는지는 서로 다른 설정입니다.


정리

  • 그림자는 깊이감과 형태, 사실감, 플레이의 단서를 만들며, 그림자 방식은 광원의 이동성과 프로젝트의 Shadow Map Method를 함께 봐야 정해집니다.
  • Static 광원은 그림자를 라이트맵에 미리 구워 실행 중 계산을 줄이지만 실행 중의 변화를 반영하지 못하고, 반사 횟수는 World Settings에서 정합니다.
  • Stationary 광원은 간접광을 굽고 직접광을 실시간으로 계산하며, 기존 섀도 맵 방식에서는 한 곳에 겹치는 수가 4개로 제한될 수 있습니다.
  • Movable 광원은 모든 것을 실시간으로 계산해 빌드가 필요 없지만, 넓게 겹치면 비용이 커질 수 있습니다.
  • VSM을 쓰면 기존 CSM이 대체되므로, CSM의 거리와 단계 수, Distribution Exponent는 기존 섀도 맵 방식에서만 조절합니다.
  • 필요 없는 그림자를 끄고 감쇠 반경을 줄이는 것부터 시작하며, 메시의 Cast Shadows와 광원의 Cast Shadows는 사라지는 범위가 다릅니다.
  • 미리 계산하는 조명은 Build Lighting Only로 다시 빌드하고, 작은 변경은 Preview, 최종 빌드는 Production 품질로 합니다.

연습 문제

1. 메시의 그림자만 껐을 때

큐브 A와 B가 포인트 라이트 하나 아래에 있습니다. A의 메시 컴포넌트에서 Cast Shadows를 끄면 A와 B의 그림자, 그리고 A의 표면 밝기는 어떻게 될까요? 광원의 Cast Shadows를 끄면 무엇이 달라질까요?

해설 보기

A의 메시에서 Cast Shadows를 끄면 A가 만드는 그림자만 사라지고 B의 그림자는 남습니다. A의 표면은 여전히 빛을 받으므로 밝게 보입니다. 메시의 이 설정은 그림자를 만들지 여부만 정할 뿐, 빛을 받는지와는 상관이 없습니다.

광원의 Cast Shadows를 끄면 그 광원이 만드는 그림자가 모두 사라지므로, A와 B의 그림자가 함께 없어집니다. 두 설정은 사라지는 범위가 다르므로 한 항목씩 비교합니다.

2. VSM 프로젝트의 흐릿한 그림자

가상 섀도 맵을 쓰는 프로젝트에서 먼 곳의 그림자가 흐릿합니다. 팀원이 디렉셔널 라이트의 Num Dynamic Shadow Cascades를 늘리자고 제안합니다. 이 방법이 효과가 있을까요?

해설 보기

효과를 기대하기 어렵습니다. VSM을 쓰면 기존의 캐스케이드 섀도 맵이 VSM으로 대체되므로, Num Dynamic Shadow Cascades 같은 CSM 설정은 그림자 품질을 정하지 않습니다.

VSM의 품질과 비용은 VSM 전용 설정과 시각화로 확인해야 합니다. 그림자가 흐릿한 원인을 찾을 때도 지금 프로젝트의 Shadow Map Method가 무엇인지부터 확인합니다.

3. 문이 열려도 남는 그림자

미리 굽는 조명을 쓰는 방에서, 천장의 Static 포인트 라이트 아래에 있는 문을 열었는데 바닥에는 닫힌 문의 그림자가 그대로 남아 있습니다. 왜 그럴까요? 어떻게 바꿀 수 있을까요?

해설 보기

Static 광원의 그림자는 라이트 빌드 때 라이트맵에 구워진 것이라, 실행 중에는 다시 계산되지 않습니다. 바닥에 남은 닫힌 문의 그림자는 문이 Static이던 때의 빌드에서 구워진 것입니다. 실행 중에 문을 열려면 문 메시가 Movable이어야 하는데, Movable 메시는 라이트맵에 그림자를 굽지 않고 Static 광원 아래에서는 실시간 그림자도 만들지 않습니다.

문의 그림자가 따라가야 한다면, 문 메시를 Movable로 둔 채 그 광원을 Stationary로 바꿔 움직이는 물체의 그림자를 실시간으로 만들게 하거나, 필요하다면 광원을 Movable로 바꿉니다. 이동성을 바꾼 뒤에는 라이트 빌드를 다시 해 예전에 구운 닫힌 문의 그림자를 지우고, 늘어난 실시간 그림자 비용도 측정합니다.

가상 섀도 맵이 어떤 기존 그림자 방식을 대체하는지는 Epic의 가상 섀도 맵 안내에서, 광원별 그림자 동작은 Epic의 광원 종류와 이동성 안내에서 확인할 수 있습니다.

다음 글 글로벌 일루미네이션과 반사 설정에서는 빛이 표면에 튕겨 주변을 밝히는 간접광과 반사를 루멘과 다른 방식으로 설정하는 방법을 다룹니다.