2015년 3월 10일 화요일

[NGUI] UISprite에 대한 Custom Shader 적용

개요

NGUI에서 UISprite에 대한 Custom Shader의 적용 방법을 정리하고자 한다.
여기서 쉐이더는 일단 desaturate시키는 쉐이더를 예로 들어보도록 하자.

참조

http://www.tasharen.com/forum/index.php?topic=1256.0

설명
우선, NGUI의 Sprite는 1개의 Atlas단위로 쉐이더가 지정되어있다.
참고 링크에서도 이야기가 되고 있지만. 사실 기본적인 의도대로라면 1번의 drawcall에서 shader의 변경이란게 불가능하기 때문에
(정말로? 음... 사실 Sprite에서 임의의 쉐이더를 정의해놓고 drawcall을 쪼개는 한이 있더라도 선택 운용하게 해주면 좋겟다.)
수순대로라면 drawcall을 분리해서 사용해야하는 수순이 된다. 그래서 NGUI에서는 Atlas단위에 있어서 근본적인 설계딴에서 별도의 쉐이더를 분류하고 있지 않다.

자, 우선 여기서 생각해야할 제약조건은

1. Atlas단위로 shader는 고정되어있다.
2. shader를 분리해서 별개의 atlas를 작성해서 이용한다면 일단 렌더링시에 별도의 drawcall로 운용이 된다. 유색 - 무색 - 유색으로 끼게되면 하나의 텍스쳐라도 3번의 드로우콜이 필요하게 될것이다.

그리고 우리가 여기서 생각해야할 부분은

1. 그렇다면 Atlas는 우선적으로 제각각 작성해야할 것이다.
2. 그런데 완전 같은 이미지 소스에 대한 desaturation임에도 불구하고 별도의 texture를 작성할 필요가 있는가?
 -> 흑백 이미지와 컬러 이미지를 따로 작성한다면 유지보수에 있어서도 귀찮아지는 문제점이 발생할것이고, 행여나 실수를 하게되면 리소스가 결여되는 문제가 생길 수 있다.
 -> 심지어 메모리가 2배로 사용된다. 어찌되었든 바람직하진 않다.

여기서 간단히 생각해볼 수 있는것은. NGUI를 확장한다거나 하는 방법이 아닌
1개의 texture를 각각 참조하는 UIAtlas를 2개 작성하는 방법이 그 해결책의 하나가 될 수 있다고 생각한다.

우선 Desaturate를 실시하기 위한 shader에 관해선
아래 링크에 괜찮은 샘플들이 있으니 이 부분은 가져다 쓰도록 하자.

http://forum.unity3d.com/threads/desaturation-grayscale-shader-for-ios.82105/

그리고 문제의 UIAtlas인데 수순은 다음과 같다.

예를들어 UIItem이라는 atlas가 있다고 하자.

그럼 이 atlas의 구성은 다음과 같을 것이다.

UIItem.prefab
UIItem.mat
UIItem.png

우리는 이중에서 UIITem.prefab, UIItem.mat의 2개 파일을 복사할 필요가 있다.
Unity상에서 이 두개의 파일을 선택하여 Ctrl+D / OSX: Command+D 를 눌러서 복제를 하자

아마 UIItem 1과 같은 느낌으로 파일명이 바뀌었을건데, 여기서 양쪽파일명을 Desaturate 아니면 Gray와 같이 1의 부분을 대치하여 파일명을 정리해주자.

이후에 UIItem.prefab의 UIAtlas Component의 Material을 복제된 mat파일을 보도록 다시 링크를 이어주자 (복제했더니 원본을 보고있더라)
그리고 mat쪽에서 상기 링크에 있는 흑백화 쉐이더를 붙여준다.

이후에 UIItem을 이용하고 있던 Sprite에 대해서 이번에 복제 작성한 UIItem???를 연결시켜주면
에디터에서는 여전히 컬러가 들어간 이미지가 표시되지만 게임화면에서는 흑백으로 표시되는것을 알 수 있다.

UIAtlas의 instance자체에서 텍스쳐에 대한 매핑정보를 보존하고 있기 때문에, 한번 갱신을 했다면 이 복제 atlas도 다시 만들어줄 필요가 있다.
이 방법도 다소 귀찮긴 하지만. 적어도 Sprite의 렌더링에 있어서 가장 큰 크기를 차지하는 텍스처가 중복되지 않아도 된다는 장점이 있다.

NGUI에서 공식적으로 서포트 되어주었으면 하지만, 적어도 그때까지는 이런 방법을 강구할 필요가 있을것 같다.
필요에 따라서는 복제 갱신하는 툴이나 배치를 작성해도 되지 않을까

댓글 없음:

댓글 쓰기