Tessellation

이승덱·2021년 8월 19일
0

Graphics&DirectX

목록 보기
34/37

Tessellation

  • Geometry Shader와 마찬가지로 정점을 추가하는 기능

  • Geometry shader보다 큰 규모의 정점을 추가하는 기능을 함

  • 즉 동적으로 정점의 개수를 조정하는 기능이다.

  • LOD(Level Of Detail)

    • 거리에 따라 폴리곤 숫자를 줄여 물체를 간략하게 표현
    • 카메라와 거리가 먼 Object에 적용
  • ex) Terrain

  • Hull Shader

    • 각 Patch의 Control Point를 사용하여 조정한다.
    • Control Point를 기준으로 설정된 값에 따라 폴리곤을 적절하게 쪼개어 표현
  • Domain Shader

    • Hull Shader에서 추가된 정점의 비율을 통해 Local Position과 uv를 계산.
#ifndef _TESSELLATION_FX_
#define _TESSELLATION_FX_

#include "params.fx"

// --------------
// Vertex Shader
// --------------

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;
}

// --------------
// Hull Shader
// --------------

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
[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
// --------------

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;
}

// --------------
// Pixel Shader
// --------------

float4 PS_Main(DS_OUT input) : SV_Target
{
    return float4(1.f, 0.f, 0.f, 1.f);
}

#endif
결과

    output.edgeTess[0] = 1;
    output.edgeTess[1] = 2;
    output.edgeTess[2] = 3;
    output.insideTess = 1;

    output.edgeTess[0] = 3;
    output.edgeTess[1] = 3;
    output.edgeTess[2] = 3;
    output.insideTess = 1;
  • Shader 코드에 설정한 값에 따라 삼각형들이 나눠지고 있다.
profile
공부 기록용 블로그입니다

0개의 댓글