본문으로 바로가기

Unity Texture Arrays

category Technical Report/Graphics Tech Reports 2018. 10. 14. 02:05
반응형


참조링크 : KBench https://kbench.com/?q=node/34856&page=2



CPU에서 진행하는 이 작업이 수 백만에서 한 번으로 줄어든 다는 것은 그만큼 CPU의 부담이 줄어든다는 뜻이다.

 이와 함께 CPU의 의존률을 줄이기 위해서 3가지 새로운 기능이 추가된다. 이것들은 각각


    texture array
    predicated draw
    stream out



이라 불리운다.

 Texture array는 최고 512개까지의 텍스쳐를 저장해 놓은 구조체로써, 여기에는 세이더 프로그램이 texture array 내부에서 동적으로 텍스쳐들을 색인할 수 있는 명령어들도 포함되어 있다. Texture array는 GPU에 의해 컨트롤이 되기 때문에 다량의 텍스쳐, 즉 멀티플 텍스쳐를 관리할 때 CPU의 의존도를 줄이게 된다.

 Predicated draw는 겹쳐지는 오브젝트를 처리할 때 사용하는 기능으로써, 앞쪽에 있는 오브젝트에 가려져 있는 뒤쪽의 오브젝트를 렌더링 하기는 하지만 최종적으로 보여지는 이미지에서는 효과를 제외하고 그려내는 것이다. 즉 불필요한 부분까지 세이더 처리를 하기 때문에 그만큼 자원 낭비가 이루어지는 것을 막아낼 수 있다. 이와같은 기법은 현재에도 사용되고 있지만 여전히 처리하지 말아야 할 부분까지 세이딩을 하게 된다. 이런 것을 occlusion query라 불렀으며 DX9 기반에서는 이를 CPU와 GPU가 담당했지만 DX10에서는 오직 GPU에서만 처리를 하게 된다.

 Stream out은 지오메트리 또는 버텍스 세이더의 결과물을 비디오 메모리로 바로 출력하는 새로운 기능이다. 기존에는 버텍스 -> 지오메트리 -> 픽셀 세이더 파이프 라인 순서를 반드시 거쳐야했지만 stream out을 통하면 픽셀 파이프 라인을 거치지 않고 바로 출력이 가능하게 되는 것이다. 이는 DX10의 통합 세이더 아키텍쳐가 있기에 가능한 것이다.

 이런 기능 등을 이용했을 경우 줄어드는 오버헤드의 양은 다음 그래프를 참조하자



* 모바일에서는 CPU Bound를 줄임으로 얻는 이득이 클 경우에 이러한 기능들을 도입하는게 좋다.



세이더 모델 4.0 (Shader Model 4.0)


DX9에 포함된 세이더 모델 3.0과 DX10에 포함된 세이더 모델 4.0은 구조부터 다르다. DX10에 포함된 세이더 모델 4.0은 통합 세이딩 아키텍쳐(Unified Shading Architecture)라 불리우는 것이 사용되었으며 여기에는 픽셀 세이더, 버텍스 세이더 유닛과 함께 지오메트리 세이더라는 것이 추가되었다. 이로 인해서 세이더 파이프라인은 고정된 것이 아니라 개발자가 직접 프로그래밍할 수 있도록 되어 있다.

 여기에서 세이더 파이프라인의 프로그래밍이란 기존의 프로그래머블 픽셀/버텍스 세이더를 말하는 것이 아니다. 세이더 유닛(스트림 프로세서)의 사용을 프로그래머가 버텍스나 픽셀 세이더로 임의 할당할 수 있다는 뜻이다. 기존에는 하나의 파이프라인에 픽셀/버텍스 세이더 유닛의 수가 고정되어 있었다.

 우선은 세이더 모델 3.0과 세이더 모델 4.0의 차이점을 간단히 표로 정리해 보면,




 한 번의 사이클에 처리할 수 있는 텍스쳐의 수가 DX9에서는 16개이지만 DX10에서는 128개로 늘어났으며, 멀티 렌더링 시 동시에 처리할 수 있는 픽셀 세이더의 수도 4개에서 8개로 늘어났다. 또한 텍스쳐의 크기 역시 기존 4096 x 4096에서 최대 4배가 커진 8192 x 8192까지 지원을 한다.


Unity에서는

#target 2.5(Default)

  • Almost the same as 3.0 target (see below), except still only has 8 interpolators, and does not have explicit LOD texture sampling.
  • Compiles into DX11 feature level 9.3 on Windows Phone.


#target 3.0

DX9 shader model 3.0 : derivative instructions, texture LOD sampling, 10 interpolators, more math/texture instructions allowed.

  • Not supported on DX11 feature level 9.x GPUs (e.g. most Windows Phone devices).
  • Might not be fully supported by some OpenGL ES 2.0 devices, depending on driver extensions present and features used.


#target 3.5

  • OpenGL ES 3.0 capabilities (DX10 SM4.0 on D3D platforms, just without geometry shaders).
  • Not supported on DX11 9.x (WinPhone), OpenGL ES 2.0.
  • Supported on DX11+, OpenGL 3.2+, OpenGL ES 3+, Metal, Vulkan, PS4/XB1 consoles.
  • Native integer operations in shaders, texture arrays, etc


#target 4.0

  • DX11 shader model 4.0.
  • Not supported on DX11 9.x (WinPhone), OpenGL ES 2.0/3.0/3.1, Metal.
  • Supported on DX11+, OpenGL 3.2+, OpenGL ES 3.1+AEP, Vulkan, PS4/XB1 consoles.
  • Has geometry shaders and everything that es3.0 target has.


즉 모바일에서 쓰려면 target 3.5 이상, OpenGL ES 3.0 이상이 되어야 한다.


텍스처 어레이(Texture arrays)

일반 2D 텍스처(셰이더의 Texture2D 클래스, sampler2D), 큐브 맵(셰이더의 Cubemap 클래스, samplerCUBE), 3D 텍스처(셰이더의 Texture3D 클래스, sampler3D)와 유사하게 Unity 는 2D 텍스처 어레이도 지원.

텍스처 배열은 GPU 에 단일 오브젝트처럼 보이는 같은 크기/형식/플래그 2D 텍스처의 컬렉션이며 텍스처 요소 인덱스를 사용하여 셰이더에서 샘플링할 수 있다. 텍스처 배열은 커스텀 터레인 렌더링 시스템 또는 기타 크기와 형식이 같은 많은 텍스트처에 효율적으로 액세스하는 방법이 필요한 특수 이펙트를 구현하는 데 유용하다.


텍스처 배열은 기본 그래픽스 API 및 GPU 의 지원을 받아야 하며, 다음에서 사용할 수 있다.

    Direct3D 11/12(Windows, Xbox One)
    OpenGL Core(Mac OS X, Linux)
    Metal(iOS, Mac OS X)
    OpenGL ES 3.0(Android, iOS, WebGL 2.0)
    PlayStation 4

텍스처 배열을 위한 텍스처 임포트 파이프라인은 별도로 제공되지 않으므로 스크립트로 작성해야 한다.

링크 : Unity API : Texture2DArray


일반적으로 텍스처 배열은 GPU 메모리 내에서만 사용되지만 Graphics.CopyTexture, Texture2DArray.GetPixels 및 Texture2DArray.SetPixels를 사용하여 시스템 메모리와의 사이에 픽셀을 이동할 수 있다.


텍스처 배열을 지원하는 최소 셰이더 모델 컴파일 대상은 3.5이며 기능 이름은 2darray 이다.


텍스처 배열을 선언하고 샘플링하려면 다음 매크로를 사용해야 한다.


    UNITY_DECLARE_TEX2DARRAY(name)는 HLSL 코드 내에 텍스처 배열 샘플러 변수를 선언.

    UNITY_SAMPLE_TEX2DARRAY(name,uv)는 float3 UV 가 있는 텍스처 배열을 샘플링. 좌표의 z 컴포넌트는 배열 요소 인덱스.

    UNITY_SAMPLE_TEX2DARRAY_LOD(name,uv,lod)는 명시적 밉맵 레벨이 있는 텍스처 배열을 샘플링.



Shader "Example/Sample2DArrayTexture"
{


    Properties
    {
        _MyArr ("Tex", 2DArray) = "" {}
        _SliceRange ("Slices", Range(0,16)) = 6
        _UVScale ("UVScale", Float) = 1.0
    }


    SubShader
    {
        Pass


        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag


            // texture arrays are not available everywhere,
            // only compile shader on platforms where they are


            #pragma require 2darray

            #include "UnityCG.cginc"

            struct v2f
            {
                float3 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            float _SliceRange;
            float _UVScale;

            v2f vert (float4 vertex : POSITION)


            {
                v2f o;
                o.vertex = mul(UNITY_MATRIX_MVP, vertex);
                o.uv.xy = (vertex.xy + 0.5) * _UVScale;
                o.uv.z = (vertex.z + 0.5) * _SliceRange;
                return o;
            }



            UNITY_DECLARE_TEX2DARRAY(_MyArr);

            half4 frag (v2f i) : SV_Target
    

          {
                return UNITY_SAMPLE_TEX2DARRAY(_MyArr, i.uv);
            }


            ENDCG
        }
    }
}



반응형