Encoding

8 분 소요

Real Representaion

Scaled and Biased UNorm

  • 1/2(r+1) 같은 식을 사용해 [-1, 1] 범위를 [0, 1] 로 쉐이더에서 변환해 저장하는 방식.
  • 0.5 는 Unorm 이 정수를 실수로 변환할 때 2^b-1 를 나눈다는 걸 생각하면 표현 불가능이다. 따라서 원래 값 0 은 표현할 수 없는 치명적인 단점이 있다.

SNorm

  • 위 방식의 단점이 사라지고 대신 자리수 비트를 사용하여 표현가능한 절댓값의 크기가 줄어든다. UNorm 처럼 GPU 에서 Fixed-Function Hardware 로 구현되어 Runtime Cost 가 매우매우 작다.

Unit Vector Representation

Unit Vector 를 저장하는 것은 단순 벡터를 저장하는 것과는 다르게 최적화할 여지가 크다.

예를들어 Unit Vector 를 Float 단위로 저장하면 Unit Sphere 를 넘어서는 위치를 가르켜 낭비다. 이에 대해선 Unit Sphere 의 표면에 저장할 모든 비트를 Mapping 하는 것이 최적임을 쉽게 알 수 있다.

이를 위해 다양한 Encoding 방법이 있다. 여기1 에서 나온 여러 방법을 개인적으로 분류하면 다음과 같다.

  • Floatx3, SNormx3, Spherical(Coord) 같이 좌표계를 저장.
  • Cube, Latlong(Sphere Index), Octaheral 같이 기하학적인 성질을 사용해 저장.
  • Stereographic, Lambert Equal Area 같은 classic cartographic projections(지도에서 쓰이는 것)

각 방법은 Encoding/Decoding 속도나 저장용량에 따른 성능차이가 있다. 예를들어 극좌표를 쓰면 XYZ 를 저장하는 대신 theta, pi 만 저장하면 되어 메모리를 효율적으로 사용할 수 있다. 결과도 나쁘지 않은데 극점에 분포가 몰리는 단점이 있다. 이를 해결하기 위해 Latlong 같은 Encoding 방법을 쓸 수도 있지만 속도나 구현에 필요한 메모리 등에서 손해를 보게 된다.

Octaheral Encoding 방식이 여러면에서 좋은 성능을 보이고1 실제로도 많이 사용된다.

Octaheral

// Returns ±1
    vec2 signNotZero(vec2 v) {
        return vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);
    }

    // Assume normalized input. Output is on [-1, 1] for each component.
    vec2 float32x3_to_oct(in vec3 v) {
        // Project the sphere onto the octahedron, and then onto the xy plane
        vec2 p = v.xy * (1.0 / (abs(v.x) + abs(v.y) + abs(v.z)));
        // Reflect the folds of the lower hemisphere over the diagonals
        return (v.z <= 0.0) ? ((1.0 - abs(p.yx)) * signNotZero(p)) : p;
    }

    vec3 oct_to_float32x3(vec2 e) {
        vec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));
        if (v.z < 0) v.xy = (1.0 - abs(v.yx)) * signNotZero(v.xy);
        return normalize(v);
    }

위는 여기1에서 긁어온 코드로 \(\mathbb{R}^3 \Leftrightarrow \mathbb{R}^2\) 로 Encoding, Decoding 하는 함수를 정의한다.

왜 Octrahedrom 이냐면 Distance 에 대한 정의를 \(\mathrm{L}^2\) 가 아니라 \(\mathrm{L}^1\) 로 바꾸었기 때문이다. 3차원에서 Unit L2 Norm 으로는 Sphere 가 만들어지고, Unit L2 Norm 으로는 Octrahedron 이 만들어진다.

L2 Norm 보다 L1 Norm 이 계산이 더 쉽고 벡터 분포도 괜찮아서 성능이 괜찮다고 분석된다.

Encoding 함수는 이러한 L1 Norm 을 생각하면 쉽게 이해할 수 있다. z <= 0 의 경우 매핑되는 사각형의 구석으로 넣는다. 보간이 불가능한 점은 아래쪽 Hemi-Octahedrom 의 가장 밑 꼭짓점 뿐이다.

참고자료

댓글남기기