1. Direct3D Tesselation
1.1 Tesselation
1.1.1 Tesselation Stage
- 주어진 기하구조를 더 작은 삼각형들로 분할, 새로 생긴 정점들의 위치를 적절한 방법으로 조정
- GPU상의 동적 LOD, 메시의 세부수준을 카메라와의 거리나 기타 요인에 따라 동적으로 조정
- 효율적인 물리 및 애니메이션 계산, 물리와 애니메이션을 저다각형 메시에 대해 수행
- 저다각형 메시를 테셀레이션해서 고다각형 버전으로 만듦, 낮은 주파수에서 수행함으로 계산량을 줄일 수 있음
- 메모리에는 저다각형 버전을 담아두고, GPU에서 테셀레이션을 통해 즉석으로 고다각형 버전을 생성, 메모리 절약
- 테셀레이션을 사용하는 경우 응용 프로그램은 입력 조립기 단계에서 삼각형들을 제출하지 않음
- 제어점들로 이루어진 패치를 제출, 최대 32개
- 삼각혀은 제어점이 세 개인 패치 기본도형, 보통 삼각형 메시도 테셀레이션을 위해 제출 가능
- 제어점이 5개 이상인 경우 특정 종류의 수학적 곡선과 곡선의 구축에 비롯
- 제어점이 많을수록 패치의 형태를 더욱 자유롭게 제어, 곡면을 지원
D3D11_PRIMITIVE_1 ~ 32_CONTROL_POINT_PATCH = 8 ~ 39;
1.1.2 Hull Shader
1.1.2.1 Constant Hull Shader
- 각 패치마다 실행되는 하나의 셰이더 함수, 메시의 소위 테셀레이션 계수들을 출력
- 테셀레이션 계수는 테셀레이터 단계가 주어진 패치를 얼마나 세분할 것인지 결정
- 밑의 코드는 제어점이 4개인 사각형 패치를 균등하게 3회 테셀레이션하도록 하는 상수 덮개 셰이더의 예
struct PatchTess { float EdgeTess[4] : SV_TessFactor; float InsideTess[2] : SV_InsideTessFactor; };
- 각 변에 따른 세분 정도를 제어하는 변 테셀레이션 계수
- 사각형 패치 내부의 세분 정도를 제어하는 내부 테셀레이션 계수
PatchTess ConstantHS(InputPatch<VertexOut, 4> patch, uint patchID : SV_PrimitiveID)
{
PatchTess pt;
pt.EdgeTess[0] = 3; pt.EdgeTess[1] = 3; pt.EdgeTess[2] = 3; pt.EdgeTess[3] = 3;
pt.InsideTess[0] = 3; pt.InsideTess[1] = 3;
return pt;
}
- 카메라와의 거리, 화면 영역 포괄도, 방향, 표면의 거친 정도에 따라 저다각형 버전으로 렌더링 가능
- 가까워짐에 따라 테셀레이션 정도를 높이면 됨
1.1.2.2 ControlPoint Hull Shader
- 다수의 제어점들을 변경하거나 추가하는 역할 수행, 출력할 제어점마다 한 번씩 호출
- 표면의 표현을 변경하는 것, 보통의 삼각형을 삼차 베지에 삼각형 패치로 변경
- 그래픽 자산 파이프라인을 수정하지 않고 기존 삼각형 메시를 그대로 테셀레이션에 사용할 수 있음
struct HullOut { float3 PosL : POSITION; };
[domain("quad")] /* 패치의 종류, (tri, quad, isoline) */
[partitioning("integer")] /* 테셀레이션 세분 모드 지정 (integer, fractional_even, odd) */
[outputtopology("triangle_cw")] /* 세분에 의해 만들어진 삼각형들의 정점 감김 순서 (triangle_cw, ccw, line) */
[outputcontrolpoints(4)] /* 덮개 셰이더가 출력할 제어점의 개수 */
[patchconstantfunc("ConstantHS")] /* 상수 덮개 셰이더로 쓰일 함수의 이름 */
[maxtessfactor(64.0f)] /* 셰이더가 사용할 테셀레이션 계수의 최댓값을 구동기에 귀띔해 주는 역할 */
HullOut HS(InputPatch<VertexOut, 4> p,
uint i : SV_OutputControlPointID,
uint patchId : SV_PrimitiveID)
{
HullOut hout;
hout.PosL = p[i].PosL;
return hout;
}
1.1.3 Domain Shader
- 테셀레이터 단계가 출력한 각 정점마다 호출, 본질적으로 테셀레이션된 패치에 대한 정점 셰이더로 작용
- 테셀레이션된 패치의 정점들을 동차 절단 공간으로 변환하는 장소
- 사각형 패치의 경우 테셀레이션 계수들과 테셀레이션된 정점 위치의 매개변수화된 좌표, 제어점 덮개 셰이더가 출력한 모든 출력 패치 제어점을 입력 받음
- 테셀레이션된 실제 정점 위치를 입력받는 것은 아님을 주의, 패치 영역 공간 안에서의 그 점의 매개변수 좌표를 받음
- 매개변수 좌표와 제어점들로부터 실제의 3차원 정점 위치를 유도하는 것은 영역 셰이더 프로그램의 몫
- 선형 필터링과 같은 방식인 겹선형 보간을 이용하여 실제 정점 위치를 유도
[domain("quad")]
DomainOut DS(PatchTess patchTess,
float2 uv : SV_DomainLocation,
const OutputPatch<HullOut, 4> quad)
{
DomainOut dout;
float3 v1 = lerp(quad[0].PosL, quad[1].PosL, uv.x);
float3 v2 = lerp(quad[2].PosL, quad[3].PosL, uv.x);
float3 p = lerp(v1, v2, uv.y);
dout.PosH = mul(float4(p, 1.0f), gWorldViewProj);
return dout;
}
'C++ Algorithm & Study > Game Math & DirectX 11' 카테고리의 다른 글
[Direct11] 32. 3D Direct Application - Camera (0) | 2023.06.26 |
---|---|
[Direct11] 31. EX App Program - Quad Tesselation (0) | 2023.06.22 |
[Direct11] 29. EX App Program - Blur System (0) | 2023.06.21 |
[Direct11] 28. Direct3D Compute Shader - Blur System (0) | 2023.06.21 |
[Direct11] 27. Direct3D Compute Shader - I/O Resource (0) | 2023.06.21 |