본문 바로가기
R&D

Unity, UI Masking 중첩 해결 방안

by Client. DJ 2022. 3. 6.
반응형

MaskTextureMaker.unitypackage
4.21MB
런타임 중, 인스턴스하게 생성된 마스크 이미지

마스크 이미지를 미리 생성해주는 패키지

 마스크 기능이 들어가는 UI의 경우 중첩으로 마스크를 지원해주지 않은 경우가 있습니다. 현재 제가 사용 중인 NGUI의 경우 중첩으로 마스킹 하는 경우 제대로 스텐실 쉐이더가 작동하지 않아 깨집니다. NGUI에 대해서 조금 더 알아보니 중첩 마스킹은 지원하지 않는다고 합니다. NGUI측에서는 셰이더 스텐실 연산이 중첩으로 들어가는 경우가 연산에 문제가 생기는 이슈가 있어서 지원하지 않는다고 하네요.

 

 그러면 개별적으로 마스킹 텍스쳐를 생성하고 받아오면 되지 않을까라는 생각에, 마스킹 이미지를 만들어주는 ScriptableObject를 작성했습니다.

예제

1. SciptableObject Data 생성하기

SciptableObject 생성

2. 텍스처, 마스크, 좌표 설정

3. 스크립트에서 사용하기

public class ExampleMaskedTexure : MonoBehaviour
{
    public MaskTextureData maskTextureData;
    public MeshRenderer meshRenderer;

    public void Start()
    {
        meshRenderer.material = maskTextureData.GetMeterial();
    }
}

4. 결과

Quad에서 텍스쳐를 만들어서 적용해주었다.

사용 목적

기존의 문제점은 리소스가 자꾸 쌓이지만, 런타임 중 마스킹한 이미지를 만드는 방식으로 변경 진행하였다. 새로 텍스처를 생성하는 과정에서 딜레이가 있을 수 있지만, 용량 측면에서 매우 효율적으로 적어진다.

 현재 프로젝트에서 중첩 마스킹이 문제가 되어, '기본 일러스트', '캐릭터 얼굴만 딴 썸네일', '일부 화면에서 마스킹 이미지' 등을 각자 따로 직접 마스크 처럼 만든 이미지를 추가했습니다. 이렇게 지속되다 보니 프로젝트 내부에 용량이 늘어갔습니다. 앞의 이유로, 용량이 아닌 조합으로 사용하면 좋을 것 같아 작업하게 되었습니다.

마무리

 셰이더 프로그래밍을 따로 배워본 적이 없어서 유니티 Document를 최대한 참고하여 짧게 셰이더를 작성했습니다. 작동에는 이상이 없어서 다행이네요.

 

 많은 프로젝트에서 중첩 마스킹에 대한 문제가 생각보다 있을 것으로 예상합니다. 사용 이유와 원리는 어느 정도 이해한 경우 사용하시길 바랍니다.

참고

1. 해당 패키지는 NGUI 예제 및 구성품이 추가되어있습니다. 사용하지 않는 경우 임포트시 체크 해제바랍니다. :)

2. 런타임 중 생성된 마스크 이미지들 디버깅할 수 있습니다. 이는 씬의 'DontDestroyOnLoad'탭에서 'Masked Texture Maker (Instance)'를 찾으시면 됩니다.

업데이트 내역

  •  스케일링 추가 (2022.3.13)
  •  좌우상하 반전 기능 추가 (2022.3.17)
  •  MaskTextureData 인스펙터 GUI 개선 (2022.3.17)
  •  MaskTextueMaker 디버깅 기능 추가 (2022.3.22) (제거됨)
  •  강제 로드 기능 추가, 이 기능은 프레임 단위로 나누지 않고 한 프레임 안에서 한 번에 로드합니다. MaskTextureData의 읽기 속도를 'Force'로 설정하면 됩니다. 또한, NGUI의 UITextureCustom에는 Force Load를 사용하면 옵션과 무관하게 강제로드가 가능합니다. (2022.4.6) (제거됨)
  • 쓰레드(셰마포어 크기 4)로 따로 처리하여 보다 빠른 속도와 프레임 드랍 없이 사용 가능합니다. (2022.5.11)(제거됨)
  • 백그라운드에서 생성이 아닌 셰이더 사용으로 근본적으로 랜더링에 마스킹 작업이 되도록 하였습니다. (2022.6.17)
반응형

댓글