[Unity] 실시간 그림자의 계단 현상을 해결하자

PublicMinsu·2024년 1월 3일
0
post-custom-banner

개요


그림자의 계단 현상(Aliasing)이 발생했습니다.

그냥 봐도 그림자가 크래커 과자 같아서 거슬리지만 움직이면 경계면이 춤을 추기에 더 거슬렸습니다.

문제를 해결하고자 방법을 찾았을 때 금방 찾을 순 있었지만 왜 그런 방법을 쓰는지는 몰랐습니다.

그래서 이번 글에서는 제 나름대로 공부한 내용을 바탕으로 글을 적고자 합니다.

출처 : https://www.youtube.com/watch?v=DilZYSNNX6s

오늘 내용은 2022년 11월에 방송을 한 '11월 알쓸유잡 : 우리 인생에는 그림자가 없기를 - 그림자 구현에 대한 이해'를 참고했습니다.

그림자의 구현

그림자는 무엇이라고 할 수 있을까요?
빛이 닿지 않는 영역이라고 할 수 있을 것입니다.

어두운 방이라고 가정해 봅시다.
불을 켜면 빛이 생길 것이고 빛이 닿지 않는 부분이 그림자가 될 것입니다.

그림자의 구현도 마찬가지입니다.

Shadow Mapping

출처 : https://learnopengl.com/Advanced-Lighting/Shadows/Shadow-Mapping

오른쪽 이미지의 점 C와 P를 살펴봅시다.

C는 광원에서 닿은 물체까지의 깊이입니다.
P는 눈(카메라) 기준의 깊이를 광원 기준의 깊이로 변환한 것입니다.
이후 두 값을 비교하여 깊이가 같지 않다면 왼쪽 이미지와 같이 그림자가 형성되게 됩니다.

출처 : https://docs.unity3d.com/kr/2023.2/Manual/shadow-mapping.html

섀도우 맵은 C처럼 광원에서 표면까지의 깊이인 것이고 섀도우 매핑은 C와 P를 활용한 것처럼 섀도우 맵을 활용하여 그림자를 렌더링 하는 것입니다.

그림자의 설정

Shadow Resolution

유니버설 렌더 파이프라인 에셋에는 Shadow Resolution이 존재합니다.

출처 : https://docs.unity3d.com/kr/Packages/com.unity.render-pipelines.universal@15.0/manual/universalrp-asset.html

공식 문서에 따르면 섀도우 맵 텍스처의 크기를 제어하는 속성입니다. 해상도가 높을수록 선명도, 디테일이 좋아진답니다. 하지만 그만큼 메모리, 렌더링 시간을 소모하기에 적절한 해상도를 사용하는 게 좋습니다.

실제로 해당 설정을 수정해 보면 그림자의 퀄리티가 달라지는 걸 확인할 수 있습니다.

Max Distance

지금 그림자의 해상도는 2048입니다.

지금 설정은 기존의 4096보다 좋아 보이는 느낌까지 듭니다.

하지만 사진에서도 보이듯이 그림자가 안 그려진 부분도 존재합니다.

그림자의 퀄리티가 좋아진 이유는 유니버설 렌더 파이프라인 에셋에 존재하는 Max Distance를 수정하였기 때문입니다.

출처 : https://docs.unity3d.com/kr/Packages/com.unity.render-pipelines.universal@15.0/manual/universalrp-asset.html

유니티 공식 문서에 따르면 카메라로부터 그림자를 렌더링 하는 최대 거리를 설정해 주는 것입니다.

렌더링 하는 최대 거리를 줄인다고만 쓰여있지 최대 거리와 그림자 퀄리티가 왜 반비례하는지에 대해서는 안 쓰여있습니다.

제 나름대로 공부하다가 알쓸유잡을 보고 이해했는데 이해한 것을 설명드리자면 최대 거리를 줄이면 그림자를 그려야 하는 범위가 줄어들었기에 그만큼 한정된 해상도에서 디테일하게 그릴 수 있는 범위가 늘어나서 그림자의 퀄리티가 좋아지고 거리를 늘리면 그 반대의 경우기에 퀄리티가 나빠지는 것으로 이해했습니다.

Cascade Count

지금 그림자의 해상도는 몇으로 보이나요? 놀랍게도 512입니다. 이전의 512는 해적이 숨긴 보물 위치처럼 X자였는데 말입니다.

그림자 최대 거리를 줄인 걸까요? 거리는 초반에 사진을 찍을 때 설정한 거리 그대로입니다.

제가 수정한 건 Cascade Count와 범위입니다.

출처 : https://docs.unity3d.com/kr/2023.2/Manual/shadow-cascades.html

가까이 있는 그림자의 픽셀이 비대하고 덩어리져 보이는 이유는 섀도우 맵이 원근에 의해 불균형하게 스케일 되기 때문입니다.

출처 : https://docs.unity3d.com/kr/2023.2/Manual/shadow-cascades.html

섀도우 캐스케이드는 영역별로 섀도우 맵을 사용하는 것입니다.

영역을 나누어서 표현해 주면 가까운 영역일수록 더 정밀하게 표현해 줄 수 있기에 가까운 그림자에 품질 저하 현상을 해결해 주는 것입니다.

프레임 디버거를 확인해 보면 영역별로 섀도우 맵을 사용하기에 Cascade Count만큼으로 Shadows.DrawSRPBatcher의 작업이 늘어난 걸 볼 수 있습니다.

또한 렌더링 통계 창을 확인해 보면 Batches가 늘어난 것을 확인할 수 있습니다.

출처 : https://docs.unity3d.com/kr/2023.2/Manual/shadow-cascades.html

섀도우 캐스케이드는 원근 앨리어싱을 완화시켜주지만 섀도우 맵을 영역별로 사용하기에 드로우콜이 증가합니다.

Soft Shadows

지금 그림자의 해상도는 2048입니다. 이전과 다르게 뾰족하진 않고 흐릿해졌습니다.

Soft Shadows를 사용했기 때문입니다.

출처 : https://docs.unity3d.com/kr/Packages/com.unity.render-pipelines.universal@14.0/manual/universalrp-asset.html

Soft Shadows를 사용하면 필터링을 통해 부드러운 모양으로 만들어줍니다.
Quality에 따라 다른 필터링 방식을 활용합니다.

Soft Shadow는 필터링 과정이 존재하기에 성능 저하를 일으킵니다.

트레이드오프

그림자의 품질이 좋아지는 방법들을 살펴보면 무조건 좋아지는 방법은 없습니다.

품질을 올리는 대가로 무언가를 희생해야 합니다.
무조건 품질을 올리기보단 진행하고 있는 프로젝트에 맞게 설정해 주는 것이 효율적인 선택일 것입니다.

테스트

제 프로젝트는 멀리 있는 그림자가 중요한 요소는 아니기에 Cascade Count를 2로 하고 Max Distance를 줄였습니다.

테스트 결과 초반과 비교하면 확실히 좋아졌습니다.

느낀 점

해결법보단 그 해결법이 통하는 이유에 대해서 궁금했다. 그래서 여러 영상을 찾아보다 알쓸유잡을 보게 됐다.

알쓸유잡이 길이는 길더라도 내용은 괜찮은 내용으로 되어있다. 이전에 진행했던 내용에 관해서도 알쓸유잡을 보고 진행했더라면 더 상세히 적지 않았을까 싶다.

이후 진행할 내용에선 알쓸유잡을 자주 참고할 것 같다.

profile
연락 : publicminsu@naver.com
post-custom-banner

0개의 댓글