ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [번역] SV_Barycentrics
    Graphics/번역 2023. 7. 22. 13:12

    개인 공부용으로 번역한 거라 잘못 번역된 내용이 있을 수 있습니다.
    또한 원작자의 동의 없이 올려서 언제든 글이 내려갈 수 있습니다.
    출처 : https://github.com/microsoft/DirectXShaderCompiler/wiki/SV_Barycentrics

     

     

    Barycentric coordinates(무게중심좌표계) 는 삼각형이나 직선(line) 같은 geometric primitive 범위 내에서 위치를 정의하는 일반적인 방법입니다. 이 문서는 Primitive에 포함된 현재 픽셀의 Barycentric coordinates 를 읽기 위한 픽셀 쉐이더의 매커니즘을 설명합니다. 그런 뒤 high-order interpolation schemes, creative attribute unpacking 또는 vertex 당 atrribute 를 지정하고 서로 다른 정밀도로 보간하는 것을 허용하는 커스텀 attribute 보간에 사용할 수 있습니다. Barycentric coordinates 는 Primitive가 레스터라이즈 되는 위치에 현재 픽셀을 매핑하는 프로세스와 그 위치에서 attribute 를 보간하기 위한 고정함수 관련 로직을 효과적으로 완전히 분리합니다. 이것들은 쉐이더 프로세서에서 수행될 수 있습니다. 우리는 이것이 미래의 그래픽스 파이프라인의 발전을 위한 중요한 방향이라고 생각합니다. 여기서는 상대적으로 교차하는 다음의 두 가지 매커니즘인, berycentric weights 에 접근하는 것과 이 weight 로 보간되어진 primitive vertices 의 attribues 접근을 설명합니다.

     

    System Generated Barycentric coordinates

    픽셀 쉐이더는 SV_Barycentrics semantic 시스템 값을 통해 그들의 입력 attribute 선언을 사용해 barycentric weight 에 접근할 수 있습니다. 아래는 표준 attribute 선언 구문 입니다:

    float4 PSMain(float3 baryWeights : SV_Barycentrics) : SV_Target {
       ...
    }

    시스템에서 생성된 값인 SV_Barycentrics 으로 선언된 Attributes 는 32bit floating point 3개인 벡터여야만 합니다, 벡터는 클리핑 하기전 원본 API primitive 의 vertices 에 대한 현재 픽셀의 barycentric weight 를 표현합니다 (see later re. interactions with clipping).

    3 개의 값을 더했을 때 정확히 1.0 이 된다는 보장이 없습니다. 만약 픽셀 쉐이더에서 weights 가 이런 속성을 보장하기를 바란다면, 1.0 에서 다른 2개의 합을 빼는 방식으로 매 프래그먼트 마다 3번째 좌표를 복원할 수 있습니다.

    또한 참고로 개별의 barycentric weights 는 임의의 큰거나 작은 값을 가질 수 있으며, [0…1] 범위로 반드시 제한되지는 않습니다 - screen-space(non-perspective-correct) barycentric 보간, screen-space quad 또는 삼각형 외부에서 이런일이 발생할 수 있습니다. 삼각형 Primitive에 대해서, 모든 3개의 weight 는 일반적으로 0 이 아닌 값을 가질 것입니다, 그러나 Line primitive 세번째 barycentric weight 는 (예, myBaryWeights.z) 정확히 0.0이 되도록 보장됩니다. 이런 정의에서, 픽셀 쉐이더는 레스터라이즈 되어지는 Primitive 타입에 구애받지 않습니다 (예, 삼각형 그리고 line 둘다에 대한 모든 3개의 barycentric weights 를 사용한 barycentric 의 합을 평가할 수 있습니다).

    구현자 참고사항: barycentrics 으로 선언된 attributes 는 픽셀 쉐이더 signature storage 에 공간이 예약되지 않을 것입니다.

     

    Barycentric Coordinate Interpolation Types

    대부분의 경우, Barycentric coordinates 는 다른 일반 attribute 와 같이 행동합니다, 이것은 affine (screen-space) 또는 perspective-correct 보간 그리고 optional centroid adjustment 를 허용한다는 의미에서의 이야기입니다. 보간 타입은 기존 syntax 를 사용하여 지정됩니다. 예제는 아래와 같습니다:

    // perspective-correct barycentrics: (default)
    linear float3 BaryLinear : SV_Barycentrics;
    
    // centroid-adjusted affine (screen-space) barycentrics:
    centroid noperspective float3 BaryAffine : SV_Barycentrics;
    
    // force shader to run at supersampling rate (one invocation per MSAA sample)
    sample noperspective float3 BaryAffineSample : SV_Barycentrics;

    nointerpolation 보간 modifier 는 barycentric attribute 를 허용하지 않습니다. 현재 attribute 지정 규칙의 예외로, 픽셀 쉐이더가 SV_Barycentrics 시스템 semantics 로 최대 2개의 input attributes 를 선언하는 것을 허용합니다. 하나는 perspective-correct 보간 타입을 사용한 선언이고, 다른 하나는 nonperspective(affine, screen-space) 보간 타입을 사용한 것입니다. 이런 두 시스템 sematics 은 0 또는 1 을 사용하여 서로 다른 인덱스를 가져야만 합니다, 아래의 코드는 올바른 attribute syntax 입니다:

    float4 PSMain(float3 PerspectiveBaryWeights : SV_Barycentrics,
       noperspective float3 NoPerspectiveBaryWeights : SV_Barycentrics1) : SV_Target

    이것은 픽셀 쉐이더가 perspective-correct 와 affine 버전의 Barycentric coordinates 에 접근할 수 있게 허용합니다.

     

    Barycentric Coordinate Ordering

    픽셀 쉐이더의 관점에서 Barycentric coordinates 의 순서(ordering)는 원본 API stream 에서 레스터라이즈화 되어지는 Primitive의 Vertex 순서와 일치합니다. 예를들어, 만약 삼각형 ABC 가 A, B, C 순서로 되어있을 때, 픽셀 쉐이더가 SV_Barycentric 벡터의 x 컴포넌트에서 vertex A 에 연관된 barycentric weight 를 얻을 것이고 vertex B 와 C 와 연관된 barycentric weight 는 벡터의 y 와 z 컴포넌트에서 찾을 수 있을 것입니다. 참고로 이런 정의는 현재 Primitive의 Provking vertex(역주: D3D 에서는 삼각형이나 Line 의 첫번째 vertex 를 의미하며, flat shading 하는 경우 color attribute 를 선택할 때 이 Provoking vertex 를 사용한다고 함. 출처 : 레퍼런스1) 하는 것과 barycentic weight 를 SV_Barycentrics 벡터의 x 컴포넌트에서 항상 발견할 수 있다는 것을 암시합니다. 위의 규칙에서 한가지 중요한 예외는 triangle strip 입니다: triangle strip 이 지정된 방식 때문에 barycentric weight 의 order는 모든 삼각형들이 서로 뒤집어져 있습니다. 픽셀 쉐이더가 strip 의 모든 삼각형에 대해 vertex 를 감는 방향(winding)을 일관되게 볼 수 있게 보장하는 것이 필요합니다. 더 구체적으로 확인하기 위해서 아래의 triangle strip 이 주어집니다:

    첫 두개의 삼각형은 그들의 barycentric weights 를 아래의 순서로(SV_Barycentric 벡터의 x, y, z 컴포넌트와 일치하는) 명시합니다:

    Triangle 0: [x:0, y:1, z:2], 0 은 provoking vertex

    Triangle 1: [x:1, y:3, z:2], 1 은 provoking vertex

    어떻게 두번째 삼각형의 vertices 2 그리고 3 에 대응하는 barycentric weight 이 그들의 API 스펙 순서와 비교해서 뒤집혔는지 참고해주세요.

     

    Per-Vertex Attributes

    픽셀 쉐이더가 시스템에서 생성된 barycentric weights 를 사용하여 attribute 보간을 수행하기 위해서, vertices 의 attributes 값은 반드시 제공되어야 합니다. nointerpolation attribute 를 선언하고 3 개의 vertices 에서 그 값을 읽기 위한 새 instrinsics 을 사용하여 접근할 수 있습니다. nointerpolation 으로 선언된 Attributes 는 Clipping 과 Interpolation setup 단계에 참여하지 않고 Vertex 마다 가지는 값이 그대로 픽셀 쉐이더에 제공됩니다. VS/DS/GS to PS 인터페이를 통해 이런 attribute 이진 표현에서 모든 비트를 보존하기 위해서는 구현이 필요합니다 - 어플리케이션은 어플리케이션별 해석으로 그들을 본질적으로 32-bit bitfield 세트로 다룰 수 있습니다. 위의 barycentric weight를 attribute 보간에 사용하기 위해, vertices 의 attribute 의 값은 아래의 루틴에 따라 제공됩니다:

    <attributeType> GetAttributeAtVertex( nointerpolation <attributeType> attribute,
                                                                      uint VertexID );

    여기서 VertexID 범위가 0..2 이고 attributeTypenointerpolation 으로 선언된 attribute 입니다.

    이 루틴은 아래의 방법으로 사용될 수 있습니다:

    // enum available in HLSL 2017
    enum VertexID { 
        FIRST = 0,
        SECOND = 1,
        THIRD = 2
    };
    
    // Linear perspective-correct interpolation of the COLOR attribute
    float3 main( float3 vBaryWeights : SV_Barycentrics,
    	 nointerpolation float3 Color : COLOR ) : SV_Target
    {
        float3 vColor;
        . . .
    
        float3 vColor0 = GetAttributeAtVertex( Color, VertexID::FIRST );  // color at provoking vertex
        float3 vColor1 = GetAttributeAtVertex( Color, VertexID::SECOND ); // color at 2nd vertex
        float3 vColor2 = GetAttributeAtVertex( Color, VertexID::THIRD );  // color at last vertex
    
        vColor = vBaryWeights.x*vColor0 + vBaryWeights.y*vColor1 + vBaryWeights.z*vColor2;
    
        return vColor;
    }

    삼각형 indices 는 API stream 에서 설정된 것 같이 원본 삼각형 vertices 의 순서에 따라 지정됩니다, (strip 의 특성을 고려하세요). 이것은 또한 픽셀 쉐이더가 언제나 VertexID=0 가 SV_Barycentrics 벡터의 x 컴포넌트에 있는 barycentric weight 에 대응된다고 가정할 수 있게 하기 위해 barycentric weights 의 순서와 per-vertex attribute 의 순서는 항상 일치한다는 의미입니다. 이것은 또한 VertexID 0 의 버택스 당 값은 항상 “Provoking vertex” 의 값에 대응된다는 것을 의미합니다.

    결과적으로, 픽셀 쉐이더가 vertex buffer 로 부터 attribute 를 바로 읽을 수 있어야만하고 고정함수 보간자(fixed-function interpolator) 로 일관된 방법으로 그들을 보간해야만 합니다.

    항상 그렇듯이, 같은 파라메터에서 nointerpolation 모드를 centroid 또는 sample specifier 와 함께 조합하는 것은 허용하지 않습니다.

     

    Interactions with Clipping

    지오메트리 파이프라인(DS, VS or GS) 의 마지막 쉐이더에 의해 출력된 값에 픽셀 쉐이더가 접근하기 위해서 Per-vertex attribute 는 결코 클리핑 되지 않고 항상 수정되지 않은 상태로 전달됩니다. 이것은 또한 현재 Primitive에 어떤 종류의 클리핑 상황이 일어나는지에 관계없이, 프러스텀 외부에 있는 Vertices 또는 Clip-space 에서 W=0 평면 뒤에 있는 Vertices 에서도 true 입니다.

     

    Wireframe mode

    Wireframe rasterizer mode 로 Primitive를 그릴때 (즉, D3D12_FILL_MODE_WIREFRAME), barycentric coordinates 는 input vertices 와 같은 순서를 따릅니다. 이것은 예를 들어 삼각형 Primitive를 그릴 때, writeframe 에서의 barycentric coordinate 는 1개의 0 컴포넌트와 0 이 아닌것 2개를 갖는 경향이 있습니다. 이 경우 3번째 컴포넌트는 반드시 0일 필요가 없습니다.

     

    레퍼런스

    1. https://www.slideshare.net/Mark_Kilgard/opengl-32-and-more

     

    댓글

Designed by Tistory & scahp.