DirectX Graphics 프로그래밍 가이드 고도의 주제 정점 파이프라인 티셀레이션 [목차열람] [주소복사] [슬롯비우기] |
Microsoft DirectX 9.0 |
테설레이션 유니트가 강화되었다. 다음 일이 생기게 되었다.
Microsoft® DirectX® 8. x 로 ORDER 로 불리고 있던 것은, 실제는 차수였다. DirectX 9.0 에서는,D3DDEGREETYPE 를 사용해 차수를 지정한다.
// This used to be D3DORDERTYPE and D3DORDER* typedef enum _D3DDEGREETYPE { D3DDEGREE_LINEAR = 1, D3DDEGREE_QUADRATIC = 2, D3DDEGREE_CUBIC = 3, D3DDEGREE_QUINTIC = 5, D3DDEGREE_FORCE_DWORD = 0x7fffffff, } D3DDEGREETYPE;
차수의 형태의 변경은, 다른 2 개의 구조체에 영향을 주었다.
typedef struct _D3DRECTPATCH_INFO { UINT StartVertexOffsetWidth; UINT StartVertexOffsetHeight; UINT Width; UINT Height; UINT Stride; D3DBASISTYPE Basis; D3DDEGREETYPE Degree; } D3DRECTPATCH_INFO;
typedef struct _D3DTRIPATCH_INFO { UINT StartVertexOffset; UINT NumVertices; D3DBASISTYPE Basis; D3DDEGREETYPE Degree; } D3DTRIPATCH_INFO;
드라이버에서는, 새로운 헤더를 사용해 컴파일 했을 때에 이 변경이 원인으로 발생하는 compile error를 수정할 필요가 있다. 기능을 변경할 필요는 없다.
적응형 테설레이션은, N 패치, 직사각형 패치, 삼각형 패치등의 고차원 원시적으로 적용할 수 있다. D3DRS_ENABLEADAPTIVETESSELLATION 를 사용해 이 기능을 유효하게 하면, 시점 공간내의 제어 정점의 깊이의 값에 근거해, 패치가 적응적으로 테설레이션 된다.
제어 정점 (Vi)의 Z 좌표 (Zi)는, 4 개의 벡터의 내적을 계산하는 것에 의해 시점 공간 (Zieye)에 변환 된다. 이 제어 정점의 Z 좌표를 깊이의 값으로 사용한다. 애플리케이션은, 4 개의 렌더링 스테이트 (D3DRS_ADAPTIVETESS_X, D3DRS_ADAPTIVETESS_Y, D3DRS_ADAPTIVETESS_Z, D3DRS_ADAPTIVETESS_W)를 사용해 4D 벡터 (Mdm)를 지정한다. 이 4D 벡터에는, 연결된 월드 행렬 및 뷰 행렬의 제 3 열등을 지정할 수 있다. 이 벡터를 사용해 Zieye 에 스케일을 적용할 수도 있다.
Zieye 로부터 테설레이션 레벨 Ti 를 계산하는 함수는 (MaxTessellationLevel / Zieye)이라고 가정한다. 이것은, 시점 공간의 Z = 1 에서는 MaxTessellationLevel 와 테설레이션 레벨이 동일한 일을 의미한다. N 패치의 경우, MaxTessellationLevel 는,IDirect3DDevice9::SetNPatchMode 에 의해 설정된 값에 동일하다. RT 패치의 경우는, pNumSegs 에 동일하다. 이 테설레이션 레벨은, 최대 및 최소의 테설레이션 레벨을 정의하는 D3DRS_MINTESSELLATIONLEVEL 및 D3DRS_MAXTESSELLATIONLEVEL 에 의해 정의된 값에 클램프 된다. 패치의 엣지에 따른 각 정점의 Ti 의 평균이 그 엣지의 테설레이션 레벨이 된다. 직사각형 패치, 삼각형 패치, 및 N 패치의 Ti 를 계산하는 알고리즘은, 테설레이션 레벨의 계산에 사용하는 제어 정점이 다르다.
B 스플라인 기본 타입의 직사각형 패치의 경우는, 가장 외측의 4 개의 제어 정점을 사용한다. 예를 들어, D3DORDER_CUBIC 오더타임의 경우, pNumSegs[0] 에는 정점 (1,1) 및 (1, width-2)을 사용해, pNumSegs[1] 에는 정점 (1, width-2) 및 (height-2, height-2)을 사용한다. 또, pNumSegs[2] 에는 정점 (height-2, width-2) 및 (1, width-2)을 사용해, pNumSegs[3] 에는 정점 (2,1) 및 (1,1)을 사용한다.
삼각형 패치의 경우는, 모퉁이의 패치 정점을 사용한다. D3DORDER_CUBIC 오더타임의 경우, pNumSegs[0] 에는 정점 (0) 및 (9)을 사용해, pNumSegs[1] 에는 정점 (9) 및 (6)을 사용해, pNumSegs[3] 에는 정점 (6) 및 (0)을 사용한다.
N 패치의 경우는 삼각형 정점을 사용한다.
베지어(Bezier) 기본 타입의 직사각형 패치 및 삼각형 패치의 경우는, 모퉁이의 제어 정점을 사용한다.
정점마다 테설레이션 레이트 제어. 애플리케이션은, 필요에 따라서, 정점 마다 단일의 정의 부동 소수점값을 제공해, 테설레이션 레이트의 제어에 사용할 수 있다. 이 지정에는 D3DDECLUSAGE_TESSFACTOR 를 사용한다. 다만, 사용법의 인덱스는 0, 입력 타입은 D3DDECLTYPE_FLOAT1 가 아니면 안된다. 이 값이 정점마다 테설레이션 레벨에 적산된다.
엣지 e 의 테설레이션 레벨 (Te)은 2 개의 제어 정점 (Ve1 및 Ve2)에 의해 나타내져 그 계산은 다음과 같이 행해진다.
Vertex Vi: (Xi, Yi, Zi, TFactori (optional)). Ze1eye = Ve1 . Mdm Ze2eye = Ve2 . Mdm Te1 = MaxTessellationLevel * TFactore1 / Ze1eye Te2 = MaxTessellationLevel * TFactore2 / Ze2eye Te = ( Te1 + Te2 ) / 2; if Te > D3DRS_MAXTESSELLATIONLEVEL || Te < 0, then Te = D3DRS_MAXTESSELLATIONLEVEL if Te < D3DRS_MINTESSELLATIONLEVEL, then Te = D3DRS_MINTESSELLATIONLEVEL
D3DRS_ENABLEADAPTIVETESSELLATION 가 TRUE 때, 삼각형 기본도형 (삼각형 리스트, 팬, 스트라이프)는 N 패치로서 드로잉(Drawing) 된다. IDirect3DDevice9::SetNPatchMode 에 의해 1.0 보다 작은 값으로 설정되어 있다.
새로운 렌더링 스테이트:
D3DRS_ENABLEADAPTIVETESSELLATION // BOOL D3DRS_MAXTESSELLATIONLEVEL // Float D3DRS_MINTESSELLATIONLEVEL // Float D3DRS_ADAPTIVETESS_X // Float D3DRS_ADAPTIVETESS_Y // Float D3DRS_ADAPTIVETESS_Z // Float D3DRS_ADAPTIVETESS_W // Float // D3DRS_MINTESSELLATIONLEVEL and D3DRS_MAXTESSELLATIONLEVEL // cannot be less than 1
이러한 디폴트값:
D3DRS_MAXTESSELLATIONLEVEL = 1.0f D3DRS_MINTESSELLATIONLEVEL = 1.0f D3DRS_ADAPTIVETESS_X = 0.0f D3DRS_ADAPTIVETESS_Y = 0.0f D3DRS_ADAPTIVETESS_Z = 1.0f D3DRS_ADAPTIVETESS_W = 0.0f D3DRS_ENABLEADAPTIVETESSELLATION = FALSE
새로운 하드웨어 능력:
D3DDEVCAPS2_ADAPTIVETESSRTPATCH // Can adaptively tessellate RT-patches D3DDEVCAPS2_ADAPTIVETESSNPATCH // Can adaptively tessellate N-patches