GitHub : https://github.com/developeSHG/DirectX12-Terrain/commits/01.Tessellation
Tessellation 단계 - [홀 쉐이더 스테이, 테셀레이션 스테이지, 도메인 쉐이더 스테이지]
Tessellation 자체도 지오메트리 쉐이더랑 비슷하게 정점을 추가하는 개념이다.
테셀레이션은 옵션단게였다. 여태까지 vertext shader 다음에 테셀레이션 단계를 옵션으로 사용하지 않아 뛰어넘고, 사실상 레스터라이즈 단계로 가서 pixel shader를 했었다.
LOD는 Level Of Design의 약자로, 버텍스의 수를 조절해 퀄리티를 바꾸는 최적화 기법이다.
동적 LOD - 렌더링 단계에서 동적으로 버텍스를 변화시키는 것.(카메라와의 거리에 따라 변화시킴)
(메쉬같은 경우는 바꿔치기 그냥 버텍스의 수가 적은걸로 바꿔치기하는 방법도 있다.)
Terrain과 Mesh의 동적 LOD 단계에서 Tessellation을 이용할 수 있다.
Hull Shdaer와 Domain Shader를 작업하는거고, 중간에 있는 Tessellator는 건드리지 않는다.
Hull Shdaer와 Domain Shader를 설정해놓게 되면, 하드웨어 자에서 자동적으로 실행된다.
기본적으로 테셀레이션이 들어가게 되면 달라지는 점이 topology를 triangle type이나 완성된 물체를 넘겨줬지만,
테셀레이션이 개입을 하는 순간, 사진에서와 같이 1번에서 32번까지 control point patchlist에서 하나를 선택해줘야 한다.
control point와 patch란 용어가 반복해서 등장할텐데,
control point는 제어점을 의미한다. 삼각형을 넘겨준다고 가정할 때, 각 정점에 해당하는 점을 말한다. 내부를 제어하는 점.
그 세개가 모여서 set 자체가 patch를 의미한다. patch는 control point의 그룹.
왜 vertex란 용어를 안쓰고 control point라고 할까?
control point 같은 경우 제어를 한다는 뉘앙스가 강하다. 위 사진은 베지어 곡선이다.
베지어 곡선을 그릴 때, 샘플이 되는 그런 기준점을 찍게 된다. (p1, p2, p3, p4) 점을 어떻게 위치시키느냐에 따라 굴곡이 변한다.
말 그대로 제어를 하는 점인 의미에서 control point다. 테셀레이션 단계에서 제어점이라고 부르는 이유도 그러한 이유다.
자체가 그려질수도 있겠지만, 제어점을 이용해서 중간에 있는 다른 정점을 생성하기위한 기준점이 된다고 볼 수 있다.
테셀레이션은 옵션단게라고 했었다. 여태까지 vertext shader 다음에 테셀레이션 단계를 옵션으로 사용하지 않아 뛰어넘고, 사실상 레스터라이즈 단계로 가서 pixel shader를 했었다.
테셀레이션을 사용하면 달라줘야 하는 부분이 있다. vertex shader에서 원래 wvp 행렬을 곱해줘서 사실상 투영좌표계로 넘겨주기 위한 사전 작업을 다 해놨었다.
그런데 테셀레이션을 적용시키게 되면 테셀레이션 단계에서 정점을 추가해 그곳에서 조작할 것이기 때문에 vertex shader에선 별다른 작업을 하지 않고, 자기가 받은 로컬 좌표를 그대로 토스를 해주게 될것이다.
Hull Shader의 큰 특징은 edge에 숫자를 정해줘서 각 변에 대해 몇 번을 쪼갤 것인지 정해주는 것이다. 코드에서 보는 바와 같이 0번은 1번, 1번은 2번, 2번은 3번 정해줘서 오른쪽 사진처럼 쪼개져서 삼각형이 늘어날 걸 볼 수 있다.
InsideTess도 1이 아닌 큰 수로 잡게되면 세분화되서 안에서도 삼각형이 늘어날 수 있다.
이걸 응용하게 되면 LOD에서 만약에 카메라가 어느정도 가까워졌다하면, edgeTess를 늘려서 삼각형을 작게 쪼개서 표현할 수 있고, 멀리 떨어져있으면 0로 가깝게 만들어 삼각형 한 개 짜리로 표현할 수는 효과로 볼 수 있을 것이다.
Domain Shader에서는 기준점이 되는 제어점뿐만이 아니라, Hull Shader에서 만들어줬던 새로운 정점들 대상으로도 다 같이 들어오게 된다.
테셀레이터 1단계인 Hull Shader에서 정점을 추가했으면, 모든 정점들을 대상으로 Domain Shader를 호출하게 된다. 사실상 vertex shader에서 wvp 행렬을 곱해줬던 부분이 domain shader에서 해준다.
또 patch 정보와 location 정보를 넘겨주는데, patch 정보는 당연히 제어점 삼총사의 patch를 말하는 것이고, 삼총사를 기준으로 한 각각의 비율을 location이란 걸로 전달해주게 된다. 비율이란 것은 제어점을 기준으로 어느정도의 비율을 차지하고 있는지를 말한다.
(0번이 1, 1,2번이 0이라 한다면 그 점 자체가 0번점)
(만약에 중간쯤에 위치한 점이라 한다면, 0번 1번 2번 중간에 위치하고 있으니 비율이 3분의 1씩해서 0.33이라 볼 수 있다)
domain shader 단계에서 어떤 정점의 좌표를 알고싶다하면 3개 제어점의 비율을 섞어서 알수있게 된다는 것이다.
domain shader는 localposition 이랑 uv 를 추출할 때, 기준점이 되는 control point 정점 세개를 기준으로 한 비율로 넘겨받는다란 방식이 나머지 쉐이더 단계랑 다른 부분이다. 그 외에는 다른 부분이 딱히 없다.
이렇게까지 테셀레이션을 사용하는 기본적인 방법이였다. 개념적으론 그렇지만, 사용 방법이 기존과 조금 다르다는 점.
edgeTess를 이용해서 결국에는 Terrain 만들때도 Level Of Detail에 따라서 edgeTess에 넣어주는 숫자로 더 상세하게 표현될지 아니면 투박하게 표현이 될지 조절할 수가 있다. (Terrain의 원리이자, 동적 LOD를 늘려주는 방법임.)
실습해보니 알고보면 Tessellation이 그렇게 복잡한 방법은 아니다. 1단계, 2단계, 3단계가 있어서 굉장히 많은 역활을 하는 것 같았지만, 의외로 어려운 부분은 다 하드웨어 쪽에서 해주는 것이고, 개발자는 세부적으로 정보 몇 개만 설정해주면 됐다.
'DirectX 12 > Terrain' 카테고리의 다른 글
[DirectX12 - Terrain] Chapter 03. Picking (0) | 2023.07.07 |
---|---|
[DirectX12 - Terrain] Chapter 02. Terrain (0) | 2023.07.07 |
댓글