11. LOD & LandScape

DV·2024년 6월 5일

DirectX_3D

목록 보기
12/13

📒Level Of Detail (LOD)


📌What is Level Of Detail?

: 메시 모델링 데이터의 정밀도를 단계별로 조정하는 기술

  • 가까우면 메시를 세밀하게, 멀면 단순하게 표현
  • 렌더링 속도(Speed)와 질(Quality)의 밸런싱
    • 실시간 렌더링 기술은 어느정도 퀄리티를 타협하더라도 빠른 렌더링이 중요함
    • 가능한 좋은 퀄리티로(즉 타협을 덜 하면서) 빠르게 렌더링하기 위함

[LOD 타입]

  • Static LOD
  • Dynamic LOD
    • 메시 분할
    • 메시 간략화

📌Static LOD

: 여러개의 메시를 준비해 사용

  • 카메라와 물체 간 거리를 측정해서 카메라와 가까운 거리에 있는 물체는 정밀한메시를 사용하고, 거리가 멀어질수록 낮은 단계의 메시를 사용
  • 처음부터 메시의 정밀도가 정해져 있고, 이를 카메라와의 거리에 따라서 단계별로 바꿔가며 사용하는 것
  • 장단
    • 장: 간단하므로 속도가 빠름
    • 단: 메모리 낭비, 거리에 따라서 메시가 급격히 변할 때 튀는 현상(popping) 발생

📌Dynamic LOD

: 카메라와 물체의 거리에 따라서 실시간으로 메시의 정밀도를 변화시킴

  • 메시 분할과 메시 간략화 두 타입으로 나뉨
  • 장단
    • 장: 거리에 따라 LOD가 이루어지므로 튀는 현상(popping) 적음, 메모리 낭비 없음
    • 단:
      • 느린 속도: 메시 분할, 간략화 등에 추가 연산이 필요
      • 잦은 Lock-Unlock: 레벨이 바뀌거나 정점데이터를 갱신할 때 정점 계산을 동적으로 수행

DirectX11과 Tesellation
DirectX 11 버전부터는 GPU가 LOD를 처리해줘서, 따로 구현하지 않아도 된다.

📒Dynamic LOD


📌LOD 계산

(1) 거리기반 LOD
: 시점 위치와 오브젝트의 거리를 이용해 단계 값을 구하는 방법

  • 구현이 간단하고 부하가 적음
  • 필요없는 부분이 세밀하게 보이거나 세밀하게 보여야 하는 부분이 단순하게 보일 수 있음

(2) 면적기반 LOD
: 오브젝트의 투영 면적에 따른 단계값을 구하는 방법

  • 자연스럽게 표현됨
  • 많은 CPU 연산량: 투영 면적이 달라질 때마다 다시 계산

📌(방법1) 메시 간략화

: 폴리곤의 수를 줄이는 방법

  • 간략화할 기준을 세우고 모양을 최대한 유지한 상태에서 폴리곤의 수 제거
  • 간략화 기준: 어느 폴리곤의 어느 꼭지점을 먼저 제거할 것인가 등
  • 간략화 방법:
    • 점 제거(Vertex Decimation)
    • 점 합치기(Vertex Clustering)
    • 면 줄이기(Edege Colapse)

📌(방법2) 메시 분할

: 하나 폴리곤을 여러 개의 폴리곤으로 분할하는 방법

📌균열 현상 (Crack)


하나의 단일 메시 속에 여러 단계의 패치가 존재할 때, 인접한 패치 간 분할 단계의 차이가 존재하는 경우 발생

  • 패치 단위로 분할 level을 잡는다면 level이 변하는 경계면에선 틈이 생김 (들림)

[Crack이 생기지 않게 하기]

  • 방법1: 인접한 두 패치 가 서로 level이 다르더라도, 더 낮은 level의 패치쪽에선 맞닿는 면의 레벨을 높여줘야(맞춰줘야) 함
  • 방법2: 패치 단위가 아닌, 거리에 따라 분할 level을 잡으면 자연스럽게 mapping 가능

[발생한 Crack을 매꾸기]
: 추가 삼각형을 발생한 Crack에 끼워넣기

  • 뗌질 삼각형을 LOD단계가 달라지는 모든 노드에 해서 상하좌우 네 가지 방향으로 만들어줌

📌poppiong 현상

: 거리에 따라 폴리곤 수가 갑작스럽게 줄어들거나 늘어나면 그래픽이 튀어보이는 현상

  • 정적LOD사용시 급격한 레벨의 차이로 모양이 바뀌어 튀어보이는 현상
  • 해결: 보간
    • 낮은 레벨에서 높은 레벨로 갈 때 사라지는 정점의 위치값을 level 간 차이에 대한 보간값 t를 구해 보간
    • 정적LOD에서의 해결 : 실시간으로 데이터를 계산할때 t값을 구하고, 그에 따라 보간
    • 동적LOD에서의 해결 : 두 level에서의 버텍스 버퍼를 모두 stream source로 보내고, t값을 세팅하여 버텍스 셰이더에서 두 버텍스를 보간

[보간 예시]

: level0 (0, 0), (10, 15), (20, 5)과 level1(0, 0), (20, 5)으로 구성된 직선이 있을 때
level1에서 존재하지 않는 점 (10, 15)를 level1에서의 가상의점 (10, 2.5)와 보간해야 함

현재 level이 0이고 보간값 t가 0.5라면
중간점은 0.5 (10, 15) + 0.5 (10, 2.5) = (10, 8.75)

📒Tesellation과 Height map


: Height map을 참고해서 추가적으로 만든 정점들의 높이를 변경

  • ex 지형텍스처가 표현하려고 했던 고해상도 지형 적용

📌Displacement Mapping

  • nomal mapping: 근본적으로 geometry를 조작하지 못함
  • tesellation: surfaces를 쪼개 만든 정점의 위치를 조작할 수 있음

📌Setting

[Mesh]
: Tesellation level의 차이를 주려면 patch를 필요한 값으로 세팅해줘야 함
즉, mesh를 새로 만들어 써야 함

  • Face: 기본적으로 mesh를 쪼개는(patch) 줄 수

  • UV

    • Mesh의 사각형 하나(patch 2개) 당 0~1
    • 전체를 0~1로 보지 않음 주의
    • 즉 왼쪽 위가 0,0, 오른쪽 아래가 Face,Face
  • 렌더링 시점: deferred rendering

[height map]

  • 픽셀 포맷: R32
    • r: height
    • 흑백으로만 표현됨
  • shader
    • UV: 전체 기준
    • normal: shader에서 재계산 필요

📌normal 재계산

: height map을 그대로 적용시키면 height는 적용되지만,
모든 vertex의 normal은 여전히 같은 방향이므로 명암의 차이가 존재하지 않음

[Normal 구하기]

  • 바로 주변 정점의 높이를 통해 현재 접하는 면의 Tangent와 Binormal을 도출 가능
  • 이를 통해 Normal 구함

[변화량 도출]

  • 정점 간 간격 변화량
    • Inside Level로 정점 간 이동 간격 추측
    • 정점 간 간격 변화량 = 1 / pathLevel.Inside
  • 정점 간 UV 변화량
    • UV 간 변화량 = 1 / FaceXY * 정점 간 간격
  • 계산 좌표계
    • world에서 scale이 적용되면 높이가 변하므로, world 좌표계에서 계산해야 함
    • (주의) 계산 후 WV matrix 곱하는 것과 결과 다름!!

📌LandScape

: height map으로 적용시킬 texture를 실시간으로 수정해서, 지형을 만드는 것

  • height tex 수정
  • albedo tex 수정

References
[1] LOD: https://blog.naver.com/ssod015/220272372528
[2] Height Map: https://victorbush.com/2015/01/tessellated-terrain/
[3] LandScape: https://victorbush.com/2015/01/tessellated-terrain/

0개의 댓글