AnyPortrait > 메뉴얼 > 클리핑 메시가 렌더링되지 않는 문제
저희 팀이 사용자들로부터 많이 받았던 문의 내용 중의 하나는 클리핑 메시가 정상적으로 렌더링되지 않는다는 것입니다.
렌더링 문제는 겉보기에 동일한 문제라 하더라도 서로 다른 원인에 의한 것일 수 있기 때문에 해결하기가 쉽지 않습니다.
클리핑 메시에 관한 문제의 경우도, 서로 다른 원인이 동일한 문제를 야기시킬 수 있습니다.
이 페이지에서는 사용자들의 피드백을 바탕으로 대표적인 원인들과 그 해결법을 소개합니다.
클리핑 메시 외에도 "마스크" 기능(관련 페이지)도 같은 방식으로 동작하기 때문에, 이 페이지에서 원인을 찾을 수 있습니다.
이 페이지의 일부 내용은 "마스크" 기능에서의 문제와 해결 방법을 다룹니다.
이 경우는 주로 URP를 사용했거나, 또는 기본(Built-In) 렌더 파이프라인으로 복구했을 때 겪을 수 있습니다.
이 페이지에서 사용되는 캐릭터입니다.
눈과 입의 메시들이 클리핑 메시로 설정되어 있습니다.
유니티 에디터에서 Project Settings > Graphics > Scriptable Render Pipeline Settings에서 URP로 설정한 상태입니다.
URP로 설정한 후 재질 라이브러리를 이용해서 URP용 재질을 적용까지 합니다. (관련 페이지)
Bake를 하고 게임을 실행했는데 클리핑 메시가 렌더링이 되지 않습니다.
이 경우는 렌더 파이프라인 설정이 현재 프로젝트 설정과 맞지 않아서 발생했을 가능성이 높습니다.
(1) AnyPortrait 에디터에서 Bake 버튼을 누릅니다.
(2) Setting 탭을 선택합니다.
(3) Render Pipeline 설정을 현재 프로젝트의 설정에 맞는지 확인합니다.
URP의 경우엔 Scriptable Render Pipeline로 설정해야 하고, 기본 렌더 파이프라인을 사용한다면 Default로 설정해야 합니다.
Bake를 하고 게임을 실행하면 클리핑 메시가 정상적으로 렌더링되는 것을 볼 수 있습니다.
(1) 씬에 캐릭터를 렌더링하는 카메라가 2개 이상이 되도록 만들었습니다.
위와 같이 2개의 카메라에 의해서 한개의 캐릭터가 2번 렌더링되는 것을 볼 수 있습니다.
이 상태로 게임을 실행하면, 하나의 카메라를 제외한 나머지 카메라들에서는 클리핑 메시가 정상적으로 렌더링되지 않습니다.
AnyPortrait의 클리핑 렌더링은 카메라를 참조하여 동작합니다.
카메라에 커맨드 버퍼를 등록하여 렌더링을 하거나, "View Matrix"를 활용하여 마스크 품질을 최적화하기 위함입니다.
그런데 AnyPortrait의 기본 설정은 1개의 카메라만 참조합니다.
따라서 2개 이상의 카메라가 캐릭터를 렌더링하는 경우, 이 기본 설정을 바꾸지 않는다면 클리핑 렌더링이 제대로 동작하지 않습니다.
(1) Bake 다이얼로그를 엽니다.
(2) Setting 탭을 선택합니다.
(3) VR / Multi-Camera 옵션의 값을 Multiple Cameras로 변경합니다.
이제 Bake를 실행하면 문제가 해결됩니다.
하지만 이 상태에서는 안타깝게도 클리핑 메시의 최적화 기능이 비활성화됩니다.
따라서 낮은 해상도의 클리핑 마스크에 의해 렌더링 퀄리티가 낮아지는 문제가 발생합니다.
(1) 메시 그룹을 선택합니다.
(2) 클리핑 마스크가 되는 메시를 선택합니다.
(3) Mask Texture Size 속성의 값을 변경해서 클리핑 마스크의 해상도를 증가시킵니다.
보여지는 메시의 크기와 품질에 따라 결정해야하는데, 최적화 기능이 꺼진 경우엔 512나 1024를 사용하는 것이 퀄리티 측면에서 좋습니다.
Bake를 하고 게임을 실행하면 클리핑 메시가 제대로 동작하는 것을 볼 수 있습니다.
다중 카메라를 배치한 상태이거나 Render Texture를 대상으로 렌더링을 하는 경우엔 부차적인 이슈들이 더 있습니다.
다음의 메뉴얼들이 도움이 될 것입니다.
- 여러 개의 카메라로 렌더링하기
- 렌더 텍스쳐로 렌더링하기
- VR로 빌드하기
다중 카메라 이슈와 비슷한 맥락에서, 카메라를 참조하는 과정에서 문제가 발생하는 다른 원인은 "레이어"입니다.
카메라는 "Culling Mask"에 포함된 "레이어 (Layer)"가 설정된 GameObject만 렌더링을 합니다.
이를 이용하여, AnyPortrait의 메인 스크립트인 apPortrait는 본인의 "레이어"를 대상으로 렌더링을 할 수 있는 카메라를 찾아서 클리핑 렌더링을 위한 연결을 시도합니다.
이 연결이 완료되어야만 커맨드 버퍼 등이 생성되어 클리핑 렌더링을 수행할 수 있습니다.
그런데 만약 apPortrait의 레이어가 이상하게 설정된 경우, 클리핑 렌더링을 위한 준비 작업이 실패될 수 있습니다.
2개의 메시를 가진 예제입니다.
별모양 메시가 아래의 원형 메시에 의해 클리핑이 되고 있습니다.
Bake를 하고 유니티 씬을 엽니다.
(1) 이 예제의 씬에는 1개의 카메라가 있습니다.
(2) 이 카메라의 "Culling Mask"의 값은 "Default" 레이어만 포함하고 있습니다.
문제를 재현해봅시다.
(1) 캐릭터의 루트 객체, 즉 "apPortrait"를 가진 "GameObject"를 선택합니다.
(2) 이 객체의 레이어를 "UI"로 변경합니다.
(1) 이 상태에서 실제 메시를 가진 자식 오브젝트들을 선택합니다.
(2) 자식 오브젝트들의 레이어가 "Default" 되도록 설정합니다.
게임을 실행하면 메시들이 렌더링되기는 하지만 클리핑 렌더링이 동작하지 않는 것을 볼 수 있습니다.
자식 메시들의 레이어가 "Default" 이므로 "Culling Mask"의 값과 동일하기 때문에 렌더링 자체는 제대로 수행됩니다.
하지만 카메라를 찾아서 연결을 수행하는 "apPortrait"의 레이어는 "Culling Mask"에 포함되지 않은 "UI"입니다.
이 경우, 실제 메시 렌더링 여부와 상관없이, "apPortrait"는 "이 캐릭터를 렌더링 하는 카메라가 없다"라고 잘못 판단해버리는 것입니다.
문제를 수정하기 위해서는 "apPortrait의 레이어를 수정하는 방법" 또는 "카메라의 Culling Mask"를 수정하는 방법"이 고려될 수 있습니다.
만약 apPortrait의 레이어를 변경해야하는 이유가 있다면 카메라의 Culling Mask를 변경하는 것이 맞을 수도 있지만, 이 예제에서는 apPortrait의 레이어를 변경하는 것이 더 적합해보입니다.
(1) 다시, apPortrait를 가진 GameObject를 선택합니다.
(2) 레이어를 "Default"로 바꾸어 실제 메시들의 레이어와 동일하게 설정합니다.
(3) 게임을 실행하면 클리핑 문제가 해결된 것을 볼 수 있습니다.
AnyPortrait의 클리핑 마스크는 업데이트 루틴 과정에서 어떻게 그려질지 계산됩니다.
그 계산은 카메라와 캐릭터의 위치, 속성 등을 참조합니다.
만약 업데이트에서 마스크 관련 계산을 할 때와 실제로 렌더링이 될 때의 관련 요소들의 상태가 일치하지 않는다면, 클리핑 마스크 및 메시가 정상적으로 렌더링되지 않을 가능성이 있습니다.
많은 사용자들이 Cinemachine, UniTask, Naninovel 등을 사용하다 이 문제를 겪곤 합니다.
이 문제를 다루는 메뉴얼이 별도로 있으므로, 그것을 참조하면 되겠습니다.
- 다른 에셋과 연동시 실행 순서 문제
AnyPortrait v1.6.0에서 추가된 "마스크(Mask)" 기능은 여러개의 마스크 메시를 대상 메시에 전달하여 복합적으로 마스킹을 할 수 있습니다.
이 기능을 쉐이더에서 구현하기 위해서, AnyPortrait v1.6.0에는 기존의 쉐이더들을 업그레이드했습니다.
만약 이전의 쉐이더를 그대로 사용하고 있다면 마스크 기능은 동작하지 않을 것입니다.
(1) 2개의 메시가 1개의 메시("Star Mesh")로 마스크를 전달하여 클리핑 렌더링을 구현한 예제입니다.
(2) 마스크 기능에 따라서, 붉은색 별 메시("Star Mesh")는 아래의 두개의 사각형 메시에 의해 클리핑이 되어 렌더링됩니다.
문제를 재현하기 위해서, 마스크를 지원하지 않는 쉐이더를 적용해봅시다.
(1) "재질 라이브러리"에서 마스크를 지원하지 않는 기존의 재질 프리셋들은 "Legacy"의 하위 메뉴로 이동했습니다. 여기서 현재 렌더 파이프라인에 맞는 재질 프리셋을 선택하여 설치합니다.
(2) 기존 버전의 재질 프리셋 기반으로 새로운 재질 세트를 생성합니다.
(3) 기존 버전의 경우 재질 세트의 "Description" 항목에 마스크와 관련된 키워드가 없습니다.
이 상태에서 Bake를 하고 게임을 실행하면 위와 같이 마스크가 동작하지 않는 것을 볼 수 있습니다.
문제를 해결하기 위해서는 마스크를 지원하는 최신 버전의 재질 프리셋을 이용해야합니다.
(1) "Legacy"가 아닌 최신 버전의 재질 프리셋을 설치합니다.
(2) 마스크를 지원하는 재질 프리셋으로부터 재질 세트를 생성합니다.
(3) "Description" 항목에 "Multi-Masks"라는 키워드가 추가된 것을 볼 수 있습니다. 이 키워드는 재질 세트는 다중 채널 마스크를 지원한다는 뜻이며, 이 키워드가 있어야 마스크 기능이 제대로 동작합니다.
참고
마스크 기능에서 커스텀 프로퍼티를 이용하는 경우, 재질 라이브러리를 통해서 해당 프로퍼티를 가진 쉐이더를 캐릭터에 적용해야 합니다.
적절한 재질 세트가 설정된 상태에서 다시 Bake를 하고 게임을 실행해봅시다.
클리핑이 정상적으로 동작하는 것을 볼 수 있습니다.
AnyPotrait의 클리핑 렌더링은 "커맨드 버퍼"와 "렌더 텍스쳐"를 이용합니다.
만약 클리핑 문제가 발생했다면, 일단 이 두가지 요소들이 정상적으로 생성되어 동작하는지 확인하면 문제의 원인을 더 쉽게 찾을 수 있을 것입니다.
이때, 렌더링의 각 과정을 분석하는 "프레임 디버거 (Frame Debugger)"를 이용하면 편리합니다.
유니티 에디터의 메뉴에서 "Window > Analysis > Frame Debugger"를 실행합니다.
(유니티의 버전에 따라서 메뉴 경로는 다를 수 있습니다.)
(1) 게임을 실행합니다.
(2) 렌더링을 분석하고자 하는 순간에 (3) 프레임 디버거의 Enable 버튼을 누릅니다.
이제 게임이 정지되고, 렌더링의 각 세부 단계들을 순서대로 볼 수 있습니다.
(1) 실제로 메시들을 렌더링하기 전에 "AP.."라는 이름의 렌더링 단계가 있음을 볼 수 있습니다. 이것이 AnyPortrait의 클리핑 레이어나 마스크 시스템에 의해서 생성된 커맨드 버퍼입니다.
(2) 이 커맨드 버퍼의 렌더링 단계에서는 기본적으로 흑백의 마스크가 생성됩니다. 마스크는 "Render Texture" 타입으로 저장되며, 크기나 렌더링 비율 등은 카메라의 속성과 AnyPortrait의 설정에 따라서 결정됩니다.
(1) 이제 마스크를 받아서 클리핑이 되는 메시가 렌더링되는 단계를 선택해봅시다.
(2) 앞서 커맨드 버퍼에서 생성된 마스크 이미지가 "_MaskTex"와 같은 프로퍼티에 입력되는 것을 볼 수 있습니다.
(3) 클리핑 렌더링이 정상적으로 동작되는 것을 볼 수 있습니다.
위와 같이, 클리핑 렌더링의 과정을 프레임 디버거로 볼 수 있으며, 이를 바탕으로 문제 발생시 원인을 추측해볼 수 있습니다.
1. 커맨드 버퍼가 생성되지 않았거나 카메라 숫자만큼 생성되지 않은 경우
: apPortrait가 카메라를 찾아서 연결하는 과정이 실패했을 수 있습니다.
다중 카메라 이슈나 레이어 불일치, 렌더 파이프라인 설정 등을 검토해보세요.
2. Render Texture 타입의 마스크 이미지가 제대로 생성되지 않은 경우
: 재질 라이브러리에서 "Alpha Mask" 쉐이더가 제대로 동작하지 않았을 가능성이 있습니다.
또는 모디파이어에 의해서 마스크 메시가 "숨겨진 상태 (Hidden)"라면 마스크 이미지가 생성되지 않을 수 있습니다.
3. 마스크 이미지가 클리핑 되는 메시의 프로퍼티에 입력이 되지 않은 경우
: 클리핑용 쉐이더에 적절한 프로퍼티가 없거나, 마스크 기능에서 대상 프로퍼티를 잘못 지정했을 수 있습니다.
4. 클리핑 렌더링만 수행되지 않은 경우
: 앞의 과정이 모두 정상적이었다면, 클리핑용 쉐이더가 제대로 동작하지 않았을 수 있습니다.
쉐이더 코드를 검토해보세요.
렌더링 문제는 다양한 원인에 의해서 발생합니다.
저희는 사용자들로부터 다른 에셋이나 "Renderer Feature" 등과의 호환성 문제, 스크립트에서 캐릭터를 로드할 때의 에러, 카메라 조작과 관련된 문제 등에 의해서도 렌더링 문제가 발생할 수 있음을 보고받았습니다.
이 페이지에서 소개하는 내용으로도 문제가 해결되지 않는다면 저희에게 연락을 주세요!