조명과 그림자의 디버깅
그림자 깨짐·빛샘·과다 노출 같은 조명 문제를 뷰포트 시각화와 콘솔 명령으로 재현하고 원인을 좁힙니다.
광원과 그림자, 간접광, 반사까지 적용했다면 이제 실제로 자주 만나는 문제를 해결할 차례입니다. 조명 시스템은 설정 항목이 많아서 값 하나만 어긋나도 그림자가 깨지거나, 빛이 새거나, 화면이 하얗게 날아가거나, 이유 없이 어두운 곳이 생깁니다. 문제는 이런 증상이 화면에서는 비슷하게 보여도 원인이 전혀 다르다는 점입니다. 화면만 보고 짐작으로 값을 바꾸다 보면 레벨의 품질과 작업 속도가 함께 떨어집니다.
이 글에서는 조명과 그림자 문제의 흔한 유형을 먼저 나누고, 뷰포트의 시각화 모드와 콘솔 명령으로 원인을 좁히는 방법을 익힙니다. 마지막으로 문제를 진단하고 고치는 순서를 정리합니다. 목표는 증상을 원인의 후보로 바꾸고, 한 번에 하나씩 확인하는 습관을 들이는 것입니다.
자주 만나는 문제의 유형
조명과 그림자 문제는 어떤 계산에서 생겼느냐에 따라 네 갈래로 나눌 수 있습니다.
첫째는 라이트맵 문제입니다. 물체나 일부 영역이 새까맣게 보인다면 라이트맵 UV가 겹쳤거나, 라이트맵 해상도가 너무 낮거나, 라이트 빌드에 실패했을 수 있습니다. 벽과 바닥 사이로 빛이 새어 들어오는 빛샘(light leak)은 물체 사이에 틈이 있거나 라이트매스의 샘플링이 부족할 때 생깁니다. 그림자 가장자리가 매끄럽지 않고 계단처럼 끊겨 보이는 계단 현상은 라이트맵 해상도나 그림자 설정의 문제일 수 있고, 라이트매스 설정이나 메시 자체의 문제로 그림자가 부자연스럽게 깨지기도 합니다.
둘째는 실시간 그림자 문제입니다. 그림자가 얼룩덜룩하거나 깜빡인다면 그림자 해상도가 낮거나 캐스케이드 섀도 맵 설정이 알맞지 않을 수 있습니다. 그림자가 물체에서 떨어져 떠 있는 것처럼 보이는 현상은 피터 패닝(Peter Panning)이라고 부릅니다. 그림자 바이어스가 지나치게 큰 것이 흔한 원인이지만, 메시의 형태와 실제로 쓰는 그림자 방식도 함께 확인해야 합니다.
셋째는 간접광 문제입니다. 간접광이 지나치거나 모자라다면 스카이 라이트의 강도나 라이트매스 설정이 알맞지 않을 수 있습니다. 특정 색의 물체가 주변에 색을 지나치게 비추는 색 번짐(color bleeding)도 이 갈래에 속합니다.
넷째는 노출 문제입니다. 장면 전체가 너무 밝거나 어둡다면 후처리 볼륨의 노출 설정이 알맞지 않거나, 조명의 강도가 잘못되었을 수 있습니다.
뷰포트 시각화 모드로 나눠 보기
언리얼 에디터의 뷰포트는 여러 시각화 모드를 제공해서, 조명과 그림자 문제를 눈으로 나눠 볼 수 있게 합니다. 뷰포트 툴바의 뷰 모드 메뉴를 엽니다. 기본값은 Lit입니다.
조명을 나눠 보는 모드
Lit은 모든 조명과 재질, 텍스처, 후처리가 적용된 최종 화면입니다. 가장 많이 쓰지만, 모든 것이 섞여 있어 문제의 원인을 가르기는 어렵습니다.
Lighting Only는 재질의 색과 텍스처를 빼고 빛과 그림자만으로 레벨을 보여 줍니다. 어떤 물체가 예상보다 어둡거나 밝은지, 그림자가 제대로 드리워지는지를 빠르게 볼 수 있습니다. 어두운 것이 빛 때문인지 재질의 색 때문인지를 가르는 첫 단계로 쓰기 좋습니다.
Detail Lighting은 Lighting Only와 비슷하지만 재질의 노멀 맵은 살려서 보여 주고, 재질의 기본 색은 회색으로 통일합니다. 노멀 맵이 빛에 어떻게 반응하는지, 작은 그림자들이 제대로 표현되는지 확인하기 좋습니다.
라이트맵 밀도
Lightmap Density는 미리 굽는 조명의 문제를 진단할 때 쓰는 모드로, 물체에 적용된 라이트맵의 밀도를 색으로 보여 줍니다. 초록색은 프로젝트에서 정한 이상적인 밀도(Ideal Density)에 가깝다는 뜻이고, 빨간색은 정해 둔 최대 밀도 이상, 파란색은 기준보다 낮은 밀도라는 뜻입니다. 이 색은 기준과의 비교일 뿐이라, 색만으로 품질이나 GPU 병목이 확정되지는 않습니다.
파란색으로 보이는 물체는 라이트맵 해상도를 높이거나 라이트맵 UV가 알맞은지 확인하고, 빨간색은 해상도를 낮춥니다. 메시 에셋의 기본값을 바꾸려면 스태틱 메시 에디터의 Light Map Resolution을 조절하고, 레벨에 놓인 특정 메시 하나만 바꾸려면 그 인스턴스의 Overridden Light Map Res를 씁니다.
최적화 뷰 모드
Light Complexity는 각 영역에 영향을 주는 정적이지 않은 광원의 수를 색으로 보여 주며, 몇 개의 광원이 겹치는지는 색 범례에서 확인합니다. 빨간 영역이 많다면 그곳의 Stationary나 Movable 광원 수를 줄이거나 Attenuation Radius를 줄여 겹침을 줄입니다.
Shader Complexity는 재질 셰이더가 얼마나 복잡한지를 색으로 보여 주며, 초록색은 낮고 빨간색으로 갈수록 높습니다. 빨간 영역이 많다면 그 재질의 셰이더 노드를 줄이거나 더 간단한 재질로 바꾸는 것을 검토합니다.
콘솔 명령으로 확인하기
콘솔 명령은 실행 중에 렌더링 옵션을 바꿔 보며 문제를 진단할 때 쓸모가 있습니다. 콘솔은 보통 백틱(`)이나 물결표(~) 위치의 키로 열지만, 키보드 배열과 프로젝트의 Console Keys 설정에 따라 달라집니다. 작은따옴표(') 키는 일반적으로 게임플레이 디버거(Gameplay Debugger)를 여는 키이므로 콘솔과 구분합니다.
기존 섀도 맵 방식의 그림자 명령
다음 명령은 기존 섀도 맵 방식의 캐스케이드 섀도 맵에 관한 것이라, 가상 섀도 맵의 품질 설정을 대신하지 않습니다. 지금 값과 기본값은 엔진 버전과 스케일러빌리티 설정에 따라 다르므로, 콘솔의 자동 완성과 도움말로 확인합니다.
| 명령이나 설정 | 하는 일 |
|---|---|
r.Shadow.DistanceScale [값] | 실시간 그림자를 그리는 최대 거리의 배율입니다. 줄이면 그림자가 더 가까이에서 끊겨 성능이 좋아지지만 품질이 떨어질 수 있습니다. |
r.Shadow.MaxCSMResolution [값] | 캐스케이드 섀도 맵의 최대 해상도입니다. 낮출수록 성능이 좋아지지만 그림자 품질이 떨어집니다. |
r.Shadow.CSM.MaxCascades [값] | 캐스케이드 수입니다. 많을수록 먼 그림자의 품질이 좋지만 부담이 커집니다. |
광원의 Shadow Bias | 자기 그림자 얼룩과 그림자 분리를 비교할 때 조절합니다. 낮으면 물체 표면에 자기 그림자 얼룩이, 높으면 그림자가 물체에서 떨어지는 피터 패닝이 생길 수 있으므로 작은 폭으로 바꿉니다. |
조명과 효과를 하나씩 끄는 방법
라이트 함수(Light Function)가 화면에 주는 영향은 뷰포트 Show 메뉴의 Light Functions 항목을 껐다 켜며 비교합니다. 노출이 문제인지 보려면 후처리 볼륨의 노출을 수동(Manual)으로 고정하거나, 뷰포트의 EV100 오버라이드로 자동 노출의 영향을 떼어 내 봅니다. 이때 에디터 뷰포트의 오버라이드와 게임 카메라의 설정은 서로 다른 것이므로 혼동하지 않습니다.
효과를 하나씩 끄는 명령도 있습니다. ShowFlag.AmbientOcclusion 0은 앰비언트 오클루전을, ShowFlag.ReflectionEnvironment 0은 반사 캡처의 반사 환경을 끄며, 1을 넣으면 다시 켭니다.
성능을 보는 명령
Stat FPS는 지금의 초당 프레임 수를 보여 줍니다. Stat Unit은 게임 스레드와 렌더 스레드, GPU의 시간을 나눠 보여 주므로, 조명이 병목인지 가늠하는 데 쓸모가 있습니다. ProfileGPU는 GPU가 한 프레임을 그리는 동안 어느 단계에 시간을 많이 썼는지 자세히 보여 줍니다.
문제를 고치는 순서
조명 문제를 고칠 때는 다음 순서로 원인을 좁혀 갑니다.
먼저 문제를 진단합니다. 라이트맵, 실시간 그림자, 간접광, 노출 가운데 어떤 유형인지, 특정 물체에만 생기는지 레벨 전체에 생기는지, Static 광원에서 생기는지 Movable 광원에서 생기는지를 적습니다. 그다음 Lightmap Density나 Light Complexity 같은 시각화 모드로 원인의 후보를 눈으로 확인합니다.
후보가 정해졌다면 그에 맞는 설정을 조정합니다. 라이트맵 문제라면 그 스태틱 메시의 라이트맵 해상도를 조정하고, 라이트맵 UV가 겹치지 않는지 확인하고, 필요하면 World Settings의 Lightmass 품질을 높인 뒤 반드시 라이트 빌드를 다시 합니다. 실시간 그림자 문제라면 먼저 지금의 Shadow Map Method를 확인합니다. 기존 섀도 맵 방식이라면 광원의 Dynamic Shadow Distance와 Num Dynamic Shadow Cascades, Shadow Bias를 조절하고, 가상 섀도 맵을 쓴다면 그 방식의 시각화와 품질, 캐시 설정을 확인하며 CSM 옵션을 같은 해결책으로 적용하지 않습니다.
간접광 문제라면 스카이 라이트의 강도와 World Settings의 Lightmass 설정, 예를 들어 Num Indirect Lighting Bounces와 품질을 조정하고 라이트 빌드를 다시 합니다. 루멘을 쓴다면 후처리 볼륨의 루멘 설정을 확인합니다. 노출 문제라면 후처리 볼륨의 Exposure 설정을 조정합니다.
설정을 바꿀 때마다 레벨을 플레이하거나 다시 빌드해서 변경이 문제 해결에 도움이 되었는지 확인하고, 성능의 변화도 함께 봅니다. 미세 조정이나 빠른 시험에는 앞에서 본 콘솔 명령을 씁니다. 바꾸기 전과 후의 화면은 같은 카메라와 노출, 스케일러빌리티 조건에서 저장해 둡니다. 색으로 보여 주는 시각화는 원인 후보를 좁히는 도구이고, 비용이 얼마인지는 실제 프레임 시간으로 확인합니다.
시각화 결과를 성급하게 일반화하지 않기
라이트맵 밀도가 파란색인 메시 하나를 발견했다고 해서 곧바로 모든 메시의 해상도를 높이지는 않습니다. 먼저 그 레벨이 미리 굽는 조명을 쓰는지 확인하고, 그 메시의 라이트맵 UV를 봅니다. 그다음 그 인스턴스의 해상도만 바꿔 다시 빌드하고, 화면이 얼마나 좋아졌는지와 늘어난 저장 비용을 비교합니다. 라이트맵 UV가 처음부터 겹쳐 있었다면, 해상도만 높여서는 겹침 자체가 해결되지 않습니다.
Light Complexity의 빨간색도 마찬가지입니다. 빨간색은 그곳에 광원이 많이 겹친다는 단서일 뿐, 특정 GPU 시간을 잰 값이 아닙니다. 그래서 광원을 줄인 뒤에는 실제 프레임 시간을 다시 측정해 효과를 확인합니다.
정리
- 조명 문제는 라이트맵, 실시간 그림자, 간접광, 노출의 네 갈래로 나눠 원인 후보를 찾습니다.
- Lighting Only와 Detail Lighting은 재질의 색을 빼고 빛만 보게 해 주어, 어둠이 빛 때문인지 재질 때문인지 가릅니다.
- Lightmap Density는 기준 밀도와 비교한 색으로 라이트맵 해상도를 보여 주며, 에셋 기본값은 Light Map Resolution, 인스턴스별 값은 Overridden Light Map Res로 바꿉니다.
- Light Complexity는 겹치는 비정적 광원의 수를, Shader Complexity는 셰이더의 복잡도를 보여 주지만, 둘 다 GPU 시간을 잰 값은 아닙니다.
- 콘솔은 보통 백틱이나 물결표 키로 열고, CSM 관련 명령은 기존 섀도 맵 방식에만 해당하며, Stat Unit과 ProfileGPU로 실제 비용을 봅니다.
- 피터 패닝은 지나친 그림자 바이어스가 흔한 원인이고, 바이어스가 너무 낮으면 자기 그림자 얼룩이 생깁니다.
- 같은 조건에서 한 항목씩 바꾸고, 미리 굽는 조명이라면 바꿀 때마다 다시 빌드해 확인합니다.
연습 문제
1. 떠 있는 그림자
캐릭터의 발밑 그림자가 발에서 조금 떨어져 공중에 뜬 것처럼 보입니다. 이 현상의 이름은 무엇이고, 무엇을 먼저 확인해야 할까요? 그 값을 너무 많이 바꾸면 어떤 문제가 생길 수 있을까요?
해설 보기
피터 패닝이라는 현상입니다. 기존 섀도 맵 방식을 쓴다면 먼저 광원의 Shadow Bias가 지나치게 크지 않은지 확인합니다. 그림자 방식이 무엇인지와 메시의 형태도 함께 봅니다.
바이어스를 너무 많이 낮추면 반대로 물체 표면에 자기 그림자 얼룩이 생길 수 있습니다. 그래서 작은 폭으로 바꿔 가며 두 현상이 모두 눈에 띄지 않는 값을 찾습니다.
2. 파란색 메시 하나
Lightmap Density 모드에서 벽 메시 하나가 파란색으로 보이고, 그 벽에 얼룩진 그림자가 있습니다. 팀원이 프로젝트의 모든 메시 해상도를 두 배로 올리자고 합니다. 어떻게 진행하는 것이 좋을까요?
해설 보기
모든 메시의 해상도를 올리면 문제가 없는 메시까지 라이트맵 메모리와 빌드 시간이 늘어납니다. 먼저 이 레벨이 미리 굽는 조명을 쓰는지 확인하고, 그 벽 메시의 라이트맵 UV가 겹치지 않는지 봅니다.
UV가 괜찮다면 그 벽 인스턴스의 Overridden Light Map Res만 높이고 다시 빌드해, 얼룩이 개선되었는지와 늘어난 저장 비용을 비교합니다. UV가 겹쳐 있다면 해상도를 높여도 해결되지 않으므로 UV부터 고칩니다.
3. 어두운 방의 원인 가르기
실내 방 하나가 지나치게 어둡게 보입니다. 원인이 재질의 색인지, 빛이 부족한 것인지, 노출 때문인지를 어떤 순서로 가를 수 있을까요?
해설 보기
먼저 Lighting Only 모드로 바꿔 재질의 색을 빼고 봅니다. 여기서도 어둡다면 빛이 부족한 것이고, 여기서는 밝다면 재질의 색이 어두운 것입니다.
빛이 부족하다면 광원과 스카이 라이트, 간접광 설정을 확인합니다. 그다음 후처리 볼륨의 노출을 수동으로 고정하거나 뷰포트의 EV100 오버라이드로 자동 노출의 영향을 떼어 내, 노출이 장면을 어둡게 만들고 있는지 확인합니다. 한 번에 하나씩 바꾸고 같은 카메라 위치에서 비교합니다.
뷰포트의 시각화 모드는 Epic의 뷰 모드 안내에서 확인할 수 있습니다.
다음 글 실시간 조명 및 사전 계산 조명에서는 실시간 조명과 미리 계산하는 조명의 차이를 정리하고, 프로젝트에 맞게 둘을 고르거나 섞어 쓰는 기준을 다룹니다.