tessellation stages
hull shader
tessellator (자동 단계)
domain shader
LOD
거리에 따른 메쉬를 만들어두어 멀어질 수록 버텍스가 적은 메쉬를 가지도록 교체
동적 LOD
렌더링 단계에서 버텍스를 조절
지형 또한 적용 가능
control point
정점들을 생성하기 위한 제어점
patch
제어점들과 제어점들로부터 만들어진 정점들을 통틀어 칭함
control point hull shader
제어점 개수만큼 hull 쉐이더의 함수가 불리게 됨
그러나 같은 패치 내의 제어점 정보들은 같이 받음
constant hull shader
패치 단위로 실행됨
이 함수에서 제어점들에서 정점을 어떻게 늘릴 것인지 결정해야 한다.
삼각형을 예로 들면 삼각형의 변마다 삼각형이 몇개를 만들지 결정
tessellator
삼각형 내부를 hull 쉐이더의 결정에 따라
여러 삼각형으로 쪼개어 표현함 (모두 0일 경우 렌더되지 않음)
=>
거리에 따라 삼각형 개수를 조절
domain shader
tessellator에서 만들어진 정점들의 정보를 포함된 패치를 받게 됨
만들어진 정점들은 제어점의 영향을 받는 비율로 표현됨
쉐이더 파일 추가
[domain("tri")]
[partitioning("integer")]
[outputtopology("triangle_cw")]
[outputcontrolpoints(3)]
[patchconstantfunc("ConstantHS")]
HS_OUT HS_Main(InputPatch<VS_OUT, 3> input, int vertexIdx : SV_OutputControlPointID, int patchID : SV_PrimitiveID)
{
...
output.pos = input[vertexIdx].pos;
output.uv = input[vertexIdx].uv;
return output;
}
함수 위에 tessellation을 위한 정보들을 설정
control point hull shader에서는 받은 정점 정보를 가지고 해당 좌표를 그대로 넘겨줌
struct PatchTess
{
float edgeTess[3] : SV_TessFactor;
float insideTess : SV_InsideTessFactor;
};
PatchTess ConstantHS(InputPatch<VS_OUT, 3> input, int patchID : SV_PrimitiveID)
{
PatchTess output = (PatchTess)0.f;
output.edgeTess[0] = 1;
output.edgeTess[1] = 2;
output.edgeTess[2] = 3;
output.insideTess = 1;
return output;
}
constant hull shader에서 삼각형 변마다 삼각형이 몇 개가 그려질지를 정함
그리고 만들어지는 내부 꼭지점 또한 몇 개로 만들지 정할 수 있음
resources 수정
void Resources::CreateDefaultShader()
{
...
{
ShaderInfo info =
{
SHADER_TYPE::FORWARD,
RASTERIZER_TYPE::WIREFRAME,
DEPTH_STENCIL_TYPE::LESS,
BLEND_TYPE::DEFAULT,
D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST
};
ShaderArg arg =
{
"VS_Main",
"HS_Main",
"DS_Main",
"",
"PS_Main",
};
...
Add<Shader>(L"Tessellation", shader);
}
}
쉐이더 생성 시 raterizer 타입은 RASTERIZER_TYPE::WIREFRAME,
토폴로지는 3개의 제어점을 사용하는
D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST으로 설정