• What Is Srp Batcher In Unity

    Unity의 SRP 의 개발과 같이 여러 기능들이 생겨나는 것 같다. 아마도 기존의 Unity 의 렌더링 모듈들을 최대한 개선하려는 시도로 보인다. 이번 년초에 공개된 SRP Batcher 또한 효율을 개선하기 위한 것으로 보인다.

    종종 보이는 용어 batch 라는 용어는 “한꺼번에 처리한다.” 라는 뜻으로 보통 쓰인다. 일반적인 렌더링 시스템에서의 batch 는 최소한의 drawcall-driver overhead- 을 위해 렌더링할 것들의 데이터들을 최대한 묶어주는 시스템의 기능을 말하기 위해 사용되는 것 같다. 그리고 Unity 또한 기존의 built-in batcher 시스템이 존재한다. 근데 이에 성능을 향상시키기 위해 SRP batcher 라는게 만들어 졌다고 한다. 이는 곧 기존의 built-in batcher 시스템에 비효율적인 부분이 존재한다는 것을 알 수 있다.

    Unity를 사용을 하다보면 알 수 있지만, MeshRenderer 컴포넌트의 같은 쉐이더에 다른 파라미터를 가진 Material 을 추가하거나 바꾸게 되면 DrawCall 이 바꾼 Material 의 갯수에 비례해서 올라가는 것을 알 수 있다. 문제는 이게 static batchdynamic batch 든 무조건 일어난다는 것에 문제가 있다. directX 에 직접 맞닿아본 적은 없지만 Unity로 Shader Model 5.0 부터 접한 필자로써는 이해가 잘 되지 않는 상황이였다.

    문제는 Unity Blog의 해당 포스팅을 보면 알 수 있지만(링크), Unity 자체가 dx9 레벨을 지원하면서 만들어졌으며, 여러 API(dx11)를 지원하려 하다보니 해당 API의 특징을 잘 사용하지 못한채 built-in batcher 가 만들어진 듯 했다. 아래에는 built-in batcher 시스템을 나타낸 그림이다.


    built-in batcher

    출처 : Unity Blog : SRP Batcher: Speed up your rendering!


    위와 같은 시스템이라면, 무조건 메터리얼이 바뀌면 이들의 정보를 갱신하기 위해 전체를 다 처리하는 코드로 되어있는 듯 하다. 하지만 여기서 조금 더 생각해보면, Material 과 각 오브젝트들의 Transformation 정보들은 다른 정보라고 할 수 있다. 그렇다면 이들을 한꺼번에 처리하는게 아니라, Material, Transformation 정보를 나누어서 갱신하면 Material 을 바꿀 때, 쉐이더 코드가 바뀌지 않는다면, DrawCall 이 늘어나지 않도록 할 수 있겠다. 문서에는 다른 Material 이지만 Shader 의 갯수가 많지 않은 경우를 타겟으로 했다고 쓰여져 있다. 아래 그림은 SRP Batcher 시스템을 나타내었다.


    SRP batcher

    출처 : Unity Blog : SRP Batcher: Speed up your rendering!


    위에서 언급한 데이터를 나눈 것과 동시에 중요한 것이 하나 더 있는데, 기존의 Material 데이터를 계속 갱신해 주어야 했는데, SRP Batcher 시스템은 데이터의 영속성을 보장한다고 한다. Material 의 데이터를 나누어서 관리하기 때문에 각 오브젝트 당으로 cbuffer 를 데이터를 가질 수 있다고 한다. built-in batcher 시스템에서는 이와 같은 처리를 하기위해 쉐이더 레벨에서 인스턴싱이라는 것을 지원했었는데 SRP 에서는 몇 안되는 Uber 쉐이더를 사용한다고 가정하고, 이를 자동으로 처리해주는 듯 싶다.


    SRP batcher

    출처 : Unity Blog : SRP Batcher: Speed up your rendering!


    위 그림은 batch 처리시 어떤 기준에 따라서 한꺼번에 처리하는지에 대해 알 수 있는 다이어그램이다.

    참조

  • Steradian And Solid Angle

    solid angle 은 우리가 일반적으로 알고있는 angle 과는 다르게 생소할 가능성이 높다. 이의 단위는 steradian(sr) 으로 교과과정에서 많이 보이는 radian 과 이름이 비슷하다.

    먼저 이름이 비슷한 radian 의 정의를 잘 보여주는 아래 이미지를 보자.


    radian_animation

    출처 : Wikipedia : Radian


    주목할 것은 초반에 나오는 1rad 의 호의 길이가 반지름과 같은 것이라 정의한 부분이다. steradian 의 정의도 언급한 radian 의 정의와 비슷하다.


    steradian

    출처 : Wikipedia : Steradian


    solid angle 은 해당 표면의 면적이 반지름의 제곱인 값과 같으면 1 sr 으로 정의된다. 모든 구의 면적을 다 차지할 경우 4π sr 이라고 할 수 있겠다. 또한 아래 그림처럼 표면의 크기에 상관있기 때문에 표면의 모양이 어찌 되었든 상관없다.


    steradian

    출처 : SolitaryRoad.com : Photometry, Steradian, Intensity of a light source, Candlepower, Lumen, Illumination, Photometer


    그리고 면적이 넓은것에 solid angle 이 비례하는 것이 아니라 전체 면적의 비율을 얼마나 차지하느냐에 따라서 solid angle 이 결정된다. 즉 반지름의 크기와는 상관이 없다. 그래서 solid angle 은 다음과 같이 나타낼 수 있다.


    \[\Omega = A / r^2\]

    definition of steradian


    참조

  • Unit Of Light Radiation

    real-time rendering 분야에서 PBR 이 정착하게 되면서, 빛에 대한 측정 기준을 알아야 되게 되었다. 단순하지만 확실하게 정의해놓지 않으면 헷갈리는 개념이기 때문에 정리 해보려 한다.

    Read on →

  • How To Represent Transparency Object

    오래전부터 게임같은 실시간으로 안정적인 성능을 뽑아내야하는 컴퓨터 그래픽에서의 투명한 물체는 항상 골칫거리였다. “투명” 하다보니 일반적으로 사용되는 최적화 방법도 사용할 수 없기 때문에 퍼포먼스의 문제가 있으며, 일반적으로 지원하는 Alpha Blending 을 사용할시에는 물체의 순서를 직접 소팅해주어야 했다. 투명한 물체를 그리는 일반적인 방법의 문제에 대해서 알아보고, 문제를 부분적으로 해결할 수 있는 몇가지 방법들을 적어보겠다.

    Read on →

  • Opaque As Alpha Test

    Shader 에서 샘플링하는 Texutre 에서 Alpha 값을 가지고 있어, Alpha 을 참조해서 실제 픽셀에 출력을 하는지 안하는지를 결정하는 것을 Alpha Test 라고 한다. 이런 Material 이나 TextureCutout 이라고 통칭하는 경우가 많다.

    보통 게임에서의 Alpha Test 를 사용하는 것들은 나무, 풀 같은 식생들(Vegetation)이 있고, 중간에 구멍이 뚫린 펜스같은 것들도 존재한다. 자연을 배경으로하는 게임의 경우에는 식생들이 굉장히 많기 때문에 Alpha Test 를 사용하는 Shader 가 굉장히 많이 사용될 것이다.

    Read on →

  • Ieee 754 Floaing Number

    코딩을 하던 도중, 비트로 나타내어진 2 byte floating number(half-precision) 데이터를 일반적인 4byte floating number(single-precision) 으로 나타내야 할 일이 있었다. 그래서 귀찮아서 알아보지 않았던 컴퓨터의 소수를 표현하는 방법에 대해서 알아보았다. 이 글에서는 간략하게 어떤식으로 표현되는지에 대해서만 적어보기로 하겠다.

    Read on →

  • Anisotropic Filtering

    보통 사용되는 Texture Fltering 들은 Axis Align 된 방향을 기준으로 추가적인 샘플링을 하는 방법들이 대부분이다.(bilinear, bicubic, etc..) 하지만 특이한 것이 하나 있다. 바로 Anisotropic Filtering 이다.

    Read on →

  • Recommandation Of Gpu Skinning In Github

    최근 급하게 어떤 프로젝트에 투입되서 작업을 하고 있다. 다른 회사와 같이 일을 하고 있는데, 다른 회사에서 해놓은 것들이 너무 느려서 최적화를 해야했다. 결국 일반적인 잔머리로는 도저히 해결할 수 없는 상황에 봉착했다. 1년 전의 필자였다면 포기하고 안된다고 했었겠지만 다행히 약간의 노하우를 통해 해결할 수 있었다.

    Read on →

  • Dualized Asset Management Of Unity

    Unity 에서는 모든 사용자의 작업물을 Assets 폴더에 저장한다. 그리고 Assets 폴더안의 파일의 변경이 발생할 시 안의 파일들을 재가공하여 다시 로드한다. 보통 파일의 변경은 assetDatabaseX 바이너리 파일로 들어가게 되며, 스크립트, 바이너리의 변경은 다시 컴파일을 함으로써 현재 변경사항을 프로젝트에 적용시킨다.

    이러한 시스템을 위해 Unity 에서는 모든 파일, 디렉토리에 meta 파일을 생성한다. 파일별 meta 파일에는 해당 파일의 순수한 정보가 아닌 메타 정보가 들어간다. 중요한 정보는 두개로 나뉜다.

    하나는 Unity 프로젝트상에서 파일을 처음 감지했을 때, 파일의 GUID 를 생성한다. GUID 란 고유의 16진수 32글자로 이루어지는 총 512비트로 이루어지는 ID 로써 자동으로 생성되는 알고리즘을 가지고 있으며 겹칠 염려는 거의 없는 ID 알고리즘이다. 그래서 생성된 GUID 는 다른 곳에서 해당 파일을 참조할떄 쓰인다. 즉 파일이 삭제되서 같은 것으로 다시 생성한다고 해도 GUID 가 랜덤으로 결정되기 때문에 다시 연결을 해주어야 한다. 이는 Unity 내부에서 파일 링크를 GUID 로 한다는 추측을 할 수 있게 해준다. 또한 Edit -> Project Setting -> Editor 에서 Asset Serialization 모드가 Force Text 로 되어있을 시에는 meta 파일들을 직접 텍스트 에디터로 확인이 가능하다.

    fileFormatVersion: 2
    guid: 5d44a238286f6904198ab78e914c229d
    MonoImporter:
      serializedVersion: 2
      defaultReferences: []
      executionOrder: 0
      icon: {instanceID: 0}
      userData:
      assetBundleName:
    

    어떤 스크립트에 딸린 meta 파일의 내용이다. 두번째 줄에 생성된 guid 가 존재한다. 이는 Library/metadata 디렉토리에 쓰여진 이름들과 매칭된다.

    두번째는 바로 해당 파일의 Importer 정보가 들어있다. 위의 meta 파일은 스크립트이기 때문에 3번째 줄에 MonoImporter 라고 쓰여져 있으며, 파일의 성질에 따라서 built-in importer 가 달라진다. 바이너리 파일들은 NativeImporter, 텍스쳐 파일들은 TextureImporter, 3D 모델 파일들은 ModelImporter 로 자동으로 매칭된다.

    이러한 Importer 정보들은 보통 해당 Asset 의 옵션을 세팅할 떄 쓰인다. 또한 2017 버젼에서는 파일의 확장자를 사용자가 직접 지정해 Importer 를 사용할 수도 있게 해두었다.(링크)

    Unity 에서는 새로운 파일을 감지했을 때, GUID 를 생성하고 파일의 확장자에 따라 Importer 정보를 갱신한 후, 정보를 Library/metadata 에 갱신하는 것으로 볼 수 있다. Library/metadata 에서는 GUID 로 된 파일과 (해당 GUID).info 로 파일이 구성되어 있다. 각각의 파일은 파일의 유형별로 다른 것으로 보인다.

  • What Is Ddx And Ddy

    HLSL 에는 ddxddy intrisicShader Model 2.0 부터 존재했다. 필자는 이를 이해하기 위해 자료를 찾아보았지만 쉽게 이해되는 것들은 거의 없었다. 이해한 것을 정리하기 위해 이글을 쓴다.

    예전부터 Pixel Shader 를 처리할 때 픽셀 단위로 하나하나 처리하는게 아닌 적어도 2x2 개의 픽셀들을 한꺼번에 처리했다고 한다. 그래서 이러한 아키텍쳐를 이용한 키워드가 ddxddy 다. 기본적으로 쉐이더는 병렬로 처리되기 때문에, 4개의 Pixel Shader 가 한꺼번에 실행되는 것으로 생각할 수 있다. 아래 코드를 보면서 생각해보자.

        half3 dpdx = ddx(position);
        half3 dpdy = ddy(position);
    

    4개의 픽셀 쉐이더가 첫번째 라인을 실행할 때 ddx 는 들어온 파라미터의 x축, 가로의 픽셀들의 파라미터의 차이를 구해 반환한다. 이는 δ/δx 의 의미와 같다. 즉 x 를 기준으로 편미분을 한것이라고 한다. 마찬가지로 ddy 는 y축을 기준으로 차이를 계산해 반환하는 키워드로 생각하면 된다.

    Shader Model 5.0 부터는 ddx_coarse/ddy_coarseddx_fine/ddy_fine 으로 키워드가 나뉜다. 기존의 ddx/ddyddx_coarse/ddy_coarse 와 같다고 한다. finecoarse 의 차이는 간단하다. 4개의 픽셀을 기준으로 각각의 차이를 전부 구하는게 fine, 한쪽의 차이만 구하는게 coarse 라고 한다. 자세한 것은 아래 참조에서 보는 것을 추천한다.

    참조