For me
[DirectX12] 23) Tesellation 본문
- Tessellation : 새로운 정점 생성 , 지형 과 같은 거시적인 단위
- Hull Shader
- Tessllator
- Domain Shader
VertexShader 이후에 진행되는 과정
Tesellation 이란?
Option 의 일부로 안해도 문제는 발생하지 않음.
Geometry Shader와 비슷하게 정점을 추가하는 과정
Gemoetry Shader은 작은 규모의 용도
Tesellation은 큰 규모의 용도
동적 LOD(Level Of Detail)
Mesh를 여러개 준비해 바꾸는 방법으로, 카메라에 멀어질 수록 LOD에 따라 Polygon 개수를 줄여 최적화 하는 기법
Terrain 에 적용하면 좋음!
개발자가 설정 해놓는 것 - Hull Shader, Domain Shader
Control Point - 제어점을 만들어 이용하여 중간에 있는 다른 중점들을 생성하는 방법
Hull Shader
두개의 함수가 필요하며, 병렬로 함께 실행됨
Vertex Shader에서 넘겨준 인자를 InputPatch를 통해 Input을 설정하게됨.
Patch Constant HS
Patch 단위로 실행됨
ouput을 PatchTess로 하나씩 지정함
edgeTess[0] = 1 을 한다면 안나누고,
edgeTess[1] = 2 을 한다면 두개의 삼각형으로 나누고,
edgeTess[2] = 3 을 한다면 세개의 삼각형으로 나누게 됨
struct PatchTess
{
float edgeTess[3] : SV_TessFactor;
float insideTess : SV_InsideTessFactor;
};
struct HS_OUT
{
float3 pos : POSITION;
float2 uv : TEXCOORD;
};
// Constant HS
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;
}
Control Point HS
Control Point들을 받아주고 이를 합쳐 Patch를 이룸
Patch 단위가 아닌, Control Point 개수만큼 호출이 됨
struct VS_IN
{
float3 pos : POSITION;
float2 uv : TEXCOORD;
};
struct VS_OUT
{
float3 pos : POSITION;
float2 uv : TEXCOORD;
};
VS_OUT VS_Main(VS_IN input)
{
VS_OUT output = input;
return output;
}
// Control Point HS
[domain("tri")] // 패치의 종류 (tri, quad, isoline)
[partitioning("integer")] // subdivision mode (integer 소수점 무시, fractional_even, fractional_odd)
[outputtopology("triangle_cw")] // (triangle_cw, triangle_ccw, line)
[outputcontrolpoints(3)] // 하나의 입력 패치에 대해, HS가 출력할 제어점 개수
[patchconstantfunc("ConstantHS")] // ConstantHS 함수 이름
HS_OUT HS_Main(InputPatch<VS_OUT, 3> input, int vertexIdx : SV_OutputControlPointID, int patchID : SV_PrimitiveID)
{
HS_OUT output = (HS_OUT)0.f;
output.pos = input[vertexIdx].pos;
output.uv = input[vertexIdx].uv;
return output;
}
Domain Shader
Hull Shader 에서 Setting을 하게되면 Tessellation을 지나 Domain Shader로 넘어옴.
기준점 뿐만 아니라 새로 만들어진 정점들 대상으로도 함께 들어옴
Patch 정보와 Location 정보가 넘어와 local 좌표와, uv좌표를 추출함
struct DS_OUT
{
float4 pos : SV_Position;
float2 uv : TEXCOORD;
};
[domain("tri")]
DS_OUT DS_Main(const OutputPatch<HS_OUT, 3> input, float3 location : SV_DomainLocation, PatchTess patch)
{
DS_OUT output = (DS_OUT)0.f;
float3 localPos = input[0].pos * location[0] + input[1].pos * location[1] + input[2].pos * location[2];
float2 uv = input[0].uv * location[0] + input[1].uv * location[1] + input[2].uv * location[2];
output.pos = mul(float4(localPos, 1.f), g_matWVP);
output.uv = uv;
return output;
}
Resource.cpp
// Tessellation Shader
{
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",
};
shared_ptr<Shader> shader = make_shared<Shader>();
shader->CreateGraphicsShader(L"..\\Resources\\Shader\\tessellation.fx", info, arg);
Add<Shader>(L"Tessellation", shader);
}
// Tessellation Material
{
shared_ptr<Shader> shader = GET_SINGLE(Resources)->Get<Shader>(L"Tessellation");
shared_ptr<Material> material = make_shared<Material>();
material->SetShader(shader);
Add<Material>(L"Tessellation", material);
}
'DirectX12' 카테고리의 다른 글
[DirectX12] 25) Picking (0) | 2023.01.20 |
---|---|
[DirectX12] 24) Terrain (0) | 2023.01.20 |
[DirectX12] 22) Instancing (0) | 2023.01.20 |
[DirectX12] 21) Particle System (0) | 2023.01.19 |
[DirectX12] 20) Compute Shader (0) | 2023.01.19 |