336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.


쉐이더를 작성하다보면 텍스쳐를 많이 사용하는 기능을 만들 때도 있습니다. 대표적인게 바로 지형 스플래팅이죠. (유니티의 터레인은 아무도 쓰지 않는다는 슬픈 전설이...) 스플래팅의 개념을 모르시는 분든을 위해서 간략히 설명 드리자면, 스플래팅은 여러 텍스쳐를 서로 블렌딩해서 표현해주는 방식을 뜻합니다. 이렇게 하게 되면 작은 크기의 텍스쳐들을 가지고도 넓은 지역을 표현해줄 수가 있어서 텍스쳐 메모리를 상당히 절약할 수 있게 됩니다. 

이미지 출처 : http://blog.naver.com/sorkelf/40151055590

예전에 GPU의 쉐이더 성능이 좋지 않은 시절에는 이러한 스플래팅을 처리하기위해 여러번 덧그리는 멀티 패스로 구현해야만 했습니다. 하지만 요즘은 쉐이더에서 여러장의 텍스쳐를 한번에 읽어서 싱글 패스로 처리할 수가 있습니다. 하지만 문제는 쉐이더에서 한번에 읽을 수 있는 텍스쳐의 갯수가 제한 되어 있다는 것입니다. 만일 쉐이더에서 너무 많은 쉐이더를 샘플링 하면 원하는대로 작동하지 않게 됩니다. 근데, 이 현상이 인지하기 쉽지도 않습니다. 쉐이더 컴파일 오류가 나는 것 도 아니고 오브젝트가 보라색으로 칠해지는 것 도 아니도 그냥 몇 개의 텍스쳐가 읽히지 않고 무시되어 버립니다. 이러한 현상은 OpenGL에서 제한하는 텍스쳐 수가 다르기 때문입니다. OpenGL 공식 스펙에 이러한 숫자가 정해져 있긴 하지만 디바이스마다도 또한 차이가 발생합니다. 때문에컴파일 단계에서 이러한 제한을 탐지할 방법이 없습니다. 그러다보니 실제 렌더링 과정에서 텍스쳐 샘플링 갯수 제한을 넘게 되면 더 이상의 텍스쳐 샘플링은 무시가 되고 렌더링이 되는 것입니다.

OpenGL에서 쉐이더에서 한번에 샘플링 할 수 있는 텍스쳐 갯수는 MAX_TEXTURE_IMAGE_UNITS로 정의 되어 있습니다. (유니티에서 확인해볼 수 있는 수치는 아닙니다.)이를 문서에서 확인해보면 ES2는 8, ES3에서는 16으로 나옵니다. 즉, OpenGL ES2에서는 쉐이더에서 한번에 최대 8개의 텍스쳐를 사용할 수 있고, OpenGL ES3에서는 쉐이더에서 한번에 최대 16개의 텍스쳐를 샘플링 할 수 있다는 말이 됩니다. (물론 이 값은 특정 디바이스에서는 다른 값일 수도 있습니다.)

이미지 출처 : iOS 개발자 라이브러리

그렇다고 쉐이더이 인스펙터에 텍스쳐 슬롯을 8개 만들면 정상적으로 쓸 수 있다는 말은 또 아닙니다. 유니티는 서피스 쉐이더로 작성하고나면 유니티는 자동적으로 추가적인 정보들을 처리해줍니다. 그러는 과정에서 유니티에서 사용하는 텍스쳐가 추가적으로 쓰일 수 있습니다. 이는 쉐이더의 variant에 따라서 다르므로 완성된 코드를 확인하여야 합니다. 쉐이터를 선택 후 인스펙터에서 Compile and show code를 선택합니다. 

그러면 유니티가 서피스 쉐이더를 기반으로 추가적인 코드들과 variant들을 만들어내어 완성한 후 최종 컴파일에 사용한 코드를 보여줍니다. 코드를 확인해보면 각각의 variant에 따른 사용 텍스쳐 갯수를 주석으로 확인해볼 수 있습니다. 이 예시의 쉐이더는 서피스 쉐이더에서 8개의 텍스쳐를 사용하고 있었고 인스펙터에서 설정하고 있는 텍스쳐도 8개뿐이지만 실제로 생성된 결과물을 보면 조건에 따라 10개의 텍스쳐를 사용하고 있음을 알 수 있습니다. 

이러한 경우에는 ES 2.0에서의 한계치인 8을 넘어버리기 때문에 원하는 모습대로 렌더링이 되지 않을 수 있습니다. 때문에, 작성하고 있는 쉐이더에서 텍스쳐를 6개 이상 사용할 경우에는 variant에 따른 실제 텍스쳐 사용 갯수를 확인하여야 합니다.

맺음말 적당한게 생각 안나네요. 걍 끘! 안녕~



Posted by ozlael
,