Tessellation
Tessellation은 예전부터 존재하던 개념이지만 CPU/GPU의 요구사항이 너무 높았기 때문에 사용되지 못했지만 점차 개개인의 컴퓨터 성능이 올라가면서 DX11에서 정식 채택이 된것이다. 테셀레이션의 역할은 폴리곤의 면적을 잘게 쪼개어 더 많은 버텍스를 갖게 해주는 것이다. 이러한 역할은 Terrain을 만들때나 Displacement map과 사용하는 데에 진가를 발휘한다. Terrain에서 Tessellation을 유용하게 사용할수 있는 부분은 LOD(Level of Detail)이다. LOD는 거리에 따라 디테일을 변경하는 기술이며 이로 인한 랜더링 비용의 절약을 목적으로 이용된다.
Tessellation의 구조
Tessellation은 VS단계 다음에 위치하는 Hull/Tessellation/Domain의 3단계를 통칭하는 단계이다.
Tessellation을 사용하게 되면 VS단계를 사용하지 않게되며,(VS에서 설정하는 것들을 Tessellation에서 설정하기 때문에) 사각형으로 되어 있는 단계는 프로그래머가 임의로 수정할 수 없는 단계이다.(아이러니 하게도 Tessellation단계에서 Tessellation 외의 Hull-Shader와 Domain-Shader를 수정해야된다.)
Hull Shader 단계
먼저 Hull Shader에서는 Constant-Hull와 Controller Point-Hull 두 종류의 처리를 지원한다.
Controller Point Hull
Controller Point Hull에서는 다수의 설정을 변경하거나 추가하는 것을 담당한다.
struct HullOut
{
float3 PosL : POSITION;
};
[domain("quad")]
[partitioning("integer")]
[outputtopology("triangle_cw")]
[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;
}
domain:패치의 종류이며, 유효한 인수는 tri나 quad, isoline이다.
partitioning:세분화를 설정하는 단계이며,integer/Fractional_(even/odd)가 있다.
outputtopology: 삼각형의 랜더링 방향을 정하는 단계이다. 좌/우/line(선)을 정할수 있다.
outputcontrolpoints: 하나 의 입력 패치에 대한 Controller Point Hull의 실행 횟수를 정하는 단계이다.
patchconstantfunc: Constant Hull로 쓰일 함수의 이름을 지정하는 단계이다.
maxtessfactor:최대 Tessellation 갯수를 정하는 단계이다. 최대값은 64이다.
Constant Hull
Constant에서는 각 patch마다 실행되는 하나의 쉐이더 함수로써, Tessellation Factor를 출력한다. Tessellation Factor는 패치를 얼마나 세분할 것인지 정할때 사용된다. 여기서 Tessellation Factor가 0이하 이면 패치를 컬링되었다 판단한다.
IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST);
이러한 세분화 설정은 아래의 EdgeTess와 InsideTess의 수치에 의해 결정된다.
struct PatchTess
{
float EdgeTess[4] : SV_TessFactor;
float InsideTess[2] : SV_InsideTessFactor;
};
기본적으로 Tessellation은 사각형을 토대로 계산이 되기 때문에 path로 건네 받는 vertex가 4개인것을 확인할수있다.
PatchTess ConstantHS(InputPatch<VertexOut, 4> patch, uint patchID : SV_PrimitiveID)
{
PatchTess pt;
다음으로 앞서 다루었던 EdgeTess를 설정하는 것을 볼수 있는데, EdgeTess는 도형 변을 세분화를 담당한다.
pt.EdgeTess[0] = tess;//도형의 변을 세분화
pt.EdgeTess[1] = tess;
pt.EdgeTess[2] = tess;
pt.EdgeTess[3] = tess;
다음으로 InsideTess는 UV축을 세분화 하는 설정을 담당하고 있다.
pt.InsideTess[0] = tess;//UV축으로 세분화
pt.InsideTess[1] = tess;
return pt;
}
Tessellator 단계
Tessellator단계에서는 프로그래머가 제어할수 있는 단계가 아니며, 하드웨어가 제어한다.
Domain 단계
Domain단계에서는 새로이 생성된 삼각형들을 출력하는 단계이다. Tessellation을 사용하지 않을 경우 VS단계에서 정점들을 그리는데 반해 Tessellation을 사용할 경우 Domain단계에서 정점들을 그리기 때문에 Vs단계에서 별도의 처리를 하지 않는다.
[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;
}
'게임엔진 > DirectX' 카테고리의 다른 글
DX) 4. IA(InputAssembler) (0) | 2023.03.03 |
---|---|
DX)3.Device (0) | 2023.03.03 |
DX)2.렌더링파이프라인 가이드 (0) | 2023.03.03 |
DX)1.렌더링 파이프라인 (0) | 2023.02.11 |
DirectX) 프로젝트 설정 (0) | 2022.02.26 |
댓글