포스트 프로세싱: NaN(Not a Number) 또는 무한 값(Inf Value) 전파
셰이더 연산이 정의되지 않은 결과를 생성할 때 NaN(Not a Number)과 무한(Inf) 값이 발생합니다. 시각적으로 이 둘은 순전히 검은색이나 흰색 픽셀로 나타납니다.
NaN/Inf로 이어질 수 있는 예시 연산은 다음과 같습니다.
- 음수에 대한 제곱근(sqrt)이나 로그(log/log2)를 수행하면 NaN이 생성됩니다.
- 모듈로 연산인 A % B(A는 무한, B는 0일 때)를 수행하면 NaN이 생성됩니다.
- 아무 수나 0으로 나누면 Inf가 생성됩니다(예: 길이가 0인 벡터를 정규화함).
셰이더 연산 외에 초기화되지 않은 메모리도 NaN이나 Inf를 포함/생성할 수 있습니다. 일부 플랫폼에서 새로 생성된 렌더 텍스처의 픽셀 값은 0으로 초기화되지 않습니다. 즉 작성하거나 지우기 전에 새로운 렌더 텍스처에 액세스하는 경우 NaN/Inf가 생성될 수 있습니다. 일반적으로 사용하기 전에 항상 렌더 텍스처를 지우거나 읽기 전에 읽고자 하는 모든 값에 렌더 텍스처를 작성해야 합니다.
NaN/Inf 전파
피연산자로 NaN이나 Inf가 있는 연산도 결과적으로 NaN/Inf를 생성합니다. NaN/Inf 값이 포함되어 있고 고해상도 렌더 파이프라인(HDRP)가 수행하는 필터링이나 블러가 유효하지 않은 값을 더 퍼뜨리기 때문에 HDRP에서 중요합니다.
HDRP에서 일반적으로 보고된 문제는 블룸이 검은색 화면을 일으킨다는 점입니다. 블룸 효과가 직접 NaN/Inf를 생성하지는 않지만 화면 다른 곳에서 생성된 NaN/Inf를 퍼뜨립니다. 이런 문제는 블룸을 계산하려고 HDRP가 씬 컬러를 다운샘플링/필터링하여 원하는 해상도로 다시 업샘플링하기 때문에 발생합니다. 화면에 단일 NaN/Inf가 있는 경우 다운샘플링 프로세스는 전체 텍스처를 다룰 때까지 유효하지 않은 값을 퍼뜨리므로 후속 업샘플링에는 NaN 값만 포함되어 전체 화면이 검은색이 됩니다.
예를 들어 다음 이미지에서 HDRP가 블룸을 계산할 때 머티리얼 이슈로 발생하여 전체 씬에 퍼지는 NaN을 확인할 수 있습니다.
스크린 공간 반사, 스크린 공간 굴절, 왜곡과 같은 기능에 사용하기 위해 HDRP가 컬러 피라미드를 생성할 때 비슷한 문제가 발생합니다.
블룸을 비활성화하고 화면이 검은색으로 멈춘 경우 검은 화면의 원인은 단일 NaN/Inf 픽셀이 존재하지만 실제로는 보이지 않고 블룸이 이를 전체 화면에 전파했기 때문입니다. 블룸이 유효하지 않은 값을 생성했기 때문이 아닙니다.
NaN 및 Inf 수정
블룸 또는 다른 HDRP 기능이 NaN/Inf 값을 전파하지 못하게 하는 가장 좋은 방법은 NaN/Inf 값의 소스를 수정하는 것입니다. 이렇게 하는 방법에 대한 자세한 내용은 NaN 및 Inf 찾기를 참조하십시오.
NaN/Inf 값의 소스를 수정할 수 없는 경우 HDRP 카메라에는 NaN 값과 Inf 값을 검은색 픽셀로 교체하는 기능이 포함되어 있습니다. 이렇게 하면 블룸같은 효과가 NaN/Inf 값을 전파하는 것을 방지하지만 이 프로세스는 리소스를 상당히 소모합니다. 이 기능을 활성화하려면 카메라를 선택하고 인스펙터에서 Stop NaNs 체크박스를 활성화합니다. NaN/Inf 값의 근본 원인을 수정할 수 없는 경우에만 이 기능을 활성화해야 합니다.
NaN 및 Inf 찾기
NaN/Inf의 근본 원인을 찾기 위해 HDRP에는 식별할 수 있는 컬러로 된 NaN/Inf가 들어있는 픽셀이 표시된 디버그 모드가 포함되어 있습니다. 이 디버그 모드를 사용하려면 다음 단계를 따르십시오.
- Render Pipeline Debug 창을 엽니다(메뉴: Window > Render Pipeline > Render Pipeline Debug).
- Rendering으로 이동하여 Fullscreen Debug Mode를 NanTracker로 설정합니다.
이렇게 하면 화면에 실제로 NaN/Inf가 있는지, 어느 머티리얼이 원인인지 확인하는 데 도움이 됩니다. 하지만 어떤 특정 드로우 콜이 문제를 일으키는지와 같은 자세한 정보가 필요한 경우 RenderDoc과 같은 프레임 디버깅 툴을 사용할 수 있습니다. RenderDoc을 사용하여 Unity에서 프레임을 캡처하는 방법에 대한 자세한 내용은 RenderDoc 통합을 참조하십시오.
NaN이 발생하는 일반적인 상황은 메시가 노멀이 영벡터와 같다는 것처럼 잘못 정의된 노멀로 임포트되는 경우입니다. 이러한 노멀을 찾으려면 Render Pipeline Debug 창의 머티리얼 패널에서 노멀 시각화 모드 중 하나를 사용할 수 있습니다.
RenderDoc
프레임을 캡처한 후 RenderDoc은 NaN/Inf 값이 있는 픽셀을 순수 빨간색으로 표시할 수 있으며 이렇게 하면 HDRP가 유효하지 않은 값에 대해 렌더링하는 일반 흰색/검은색 픽셀보다 훨씬 더 눈에 잘 띄기 때문에 NaN/Inf 값을 찾는 데 도움이 됩니다. 이렇게 하려면 Texture Viewer에서 Overlay 드롭다운을 열어 NaN/Inf/-ve Display 옵션을 클릭합니다.
이제 NaN/Inf 값이 잘 보이므로 찾아볼 수 있습니다. 여전히 명확하지 않은 경우 블룸이 NaN/Inf 픽셀을 전파하는 위치를 확인하기 위해 블룸 디스패치를 보면 원인이 되는 픽셀/s를 정확히 찾아낼 수 있습니다. NaN/Inf 전파 섹션의 예시 이미지를 사용하면 소스가 화면 중심에 있는 NaN/Inf 값을 블룸이 구의 머티리얼에 확장하는 방식을 알 수 있습니다.
NaN/Inf를 생성하는 머티리얼/셰이더를 찾은 다음 이를 디버그하여 실제로 어느 연산이 유효하지 않은 값을 일으키는지 알아낼 수 있습니다.