렌더링 기법 포워드, 디퍼드

Like Big·2023년 1월 26일
0

원본

  • https://www.youtube.com/watch?v=anz5bHVbeEY

  • 포워드, 디퍼드 렌더링(라이팅, 쉐이딩이라 부르기도함)이란 라이팅을 어떻게 할거냐를 정하는것이다.

  • URP나 HDRP, 빌트인 같이 파이프라인이랑 다른 개념으로 해당 파이프라인에서 포워드 디퍼드를 선택할 수 있다.

  • 빌트인에서, URP에서 포워드 디퍼드를 세팅하는 방법은 UR Data를 만들어
    렌더링 패스를 바꿔주면됨. 그 UR Data는 URP Asset에서 렌더 리스트를
    추가할 수 있다. 카메라에 설정하는 Rendering은 무엇을 의미하는지 찾지 못했다.

포워드 렌더링

  • 리얼타임을 다루는 내용이라 Mixed랑 Baked랑은 관련이 없다. 따라서 성능절약을 위해 라이트맵
    라이트 프로브처럼 먼저 사용할 성능 절약 방법이 있다면 먼저 고려해보는게 좋다.
  • 라이트 프로브는 9개 floating 포인트 값을 가지고 처리
  • 각 오브젝트를 하나씩 하나씩(각 드로우 콜) 그린다. 보통 Z버퍼를 참고하여
    앞에꺼 부터 그리며 뒤 Z값의 오브젝트 부분은 오버드로우를 방지하기 위해 그리지 않는다.
  • 여기서 라이팅 처리가 문제가 생기는데 기존의 빌트인은 아래 사진을
    보면 버텍스 쉐이더에서 라이팅을 처리하기 때문에 여러개의 Light가 사용
    된다면 오브젝트 수 X 라이팅 수 만큼 드로우콜, 오버드로우 발생하며 이것을 멀티 패스라고 한다.
    Flow
  • Light가 여러개일때 포워드는 오버드로우를 하는데 단순히 빛을 쓰기만 하면
    문제가 없는데 기존에 빛이 반영된 프레임 버퍼의 픽셀을 읽어들이는 읽기 작업
    으로 대역폭이 많이 사용하여 큰 문제가 된다.
  • URP는 위 포워드에서 멀티패스의 문제를 해결하기 위해서 Light 카운트만큼
    루프를 돌면서 프레그먼트 쉐이더 내에서 라이트를 모두 처리후 프레임 버퍼에
    적용한다. 그리고 라이팅 카운트 제한도 둘 수 있다.
  • 제일쏀 라이트가 메인라이트가 되며 정하는 방법은 강도가 제일 쎈
    라이트이며 나머지 라이트들은 Addtional Light가 된다.
  • Limit Count로 인해 강도가 쎈 순서대로 또는 멀리떨어진 순서로
    라이트를 버림. 잘리기 싫으면 빌트인 파이프라인으로 성능을 포기하면 됨.

디퍼드 렌더링

  • 디퍼드 렌더링은 포워드의 단점을 보완하고자 나옴. 2010년도 본격적으로
    많이쓰임. 디바이스의 발전이 필요했기 때문. Forward 거의 안씀

  • G(Geometry) Buffer 디퓨즈,뎁스, 노멀 등(렌더타겟, 렌더텍스처라 함)
    라이트에 필요한 속성들을 저장하는 버퍼. 나중에 라이트를 계산

  • 오브젝트가 그려질때 각 렌더 타겟이 그려지는데 한번에 3개 이상의 렌더타겟
    에 그리니 렌더 타겟만큼 대역폭(전달해야할 데이터 양)이 더 필요하다.

  • HDRP를 쓸때 라이팅이 하나라도 디퍼드가 더 성능에 유리한가? 상황별 다름
    포워드의 경우 오버드로우가 발생할 수 밖에 없는데 HDRP가 이미 비싼
    쉐이더 일 경우(ex 클리어코트, 스킨메시)가 있어서 그때 오버드로우가 발생시
    성능에 문제가 생기므로 디퍼드가 좋은 해결책이 될 수 있다.

  • G버퍼를 만들고 각 렌더타겟에서 픽셀 정보를 가져와서 빛과 연산함.

  • 뎁스의 경우 저장시 리니어(0~1)하게 저장하는곳도 있고 z/w로 나눠서 저장
    하는 엔진도 있음.

  • 보통 디퍼드는 최소 4개 이상의 렌더타겟을 사용. 대역폭 아끼기 위해
    채널을 따로써 구겨넣음. 유니티의 G버퍼 구성

  • 위 그림에 보면 뎁스 버퍼는 렌더 타겟에 없는데 요즘엔 하드웨어가 뎁스
    버퍼를 읽을수 있게 제공. 예전엔 직접 렌더 타겟으로 만들어야 했다. API로 접근 가능

  • 프레임 디버거로 G버퍼를 확인할 수 있으며 RT0(렌더 타겟0번), Depth 선택해서 표시 가능.

  • 단점은 머티리얼을 다양하게 다루지 못한다. G버퍼는 다양한 데이터를 못
    다루지 못하고 정해진 데이터만 넣을수 있기 떄문이다. 예를들어 클리어코트,
    스킨 쉐이더의 경우 스케틀링이 효과 필요, 헤어같은 경우는 스펙큘러도
    일반 방식과 달라 정포가 더필요. 그래서 포워드에서 다시 그려야하고 특히 반투명도 마찬가지.

  • 이런 다양한 머티리얼을 다룰수 있도록 Light Pre-pass를 도입함.
    라이팅을 처리한 Lit 버퍼만 따로 만들어서 임시로 저장하고 있는 상태에서
    새로 오브젝트를 버텍스, 프래그먼트 쉐이더를 거치면서 그리는데 그때 다양한
    머티리얼을 구현 후 그 결과에 위 Lit 버퍼 결과를 합성을 하면 구현 가능.
    다만 드로우콜이 2배.

  • Inferred Lighing : G버퍼의 사이즈를 줄여서 만든다음 라이팅 처리후
    프레임 버퍼에서는 업스케일을 통하여 필터링 통해서 경계도 이쁘게 하여 보여줌
    다운사이징의 한계가 있어 실제 게임엔진에 도입되지 않음.

  • PC와 모바일의 대역폭 차이는 1/10 정도며 PC도 모니터 해상도가 커지면서
    PC도 대역폭 문제가 됨

TB(D)R Tile-based (Deferred) Rendring

  • PC와 다르게 모바일은 TBDR 사용하며 PC는 사용하지 않는것 같다.
    화면을 타일로 나눠서 GPU가 타일 버퍼를 거쳐 그리고 그걸 프레임 버퍼에 그림.
  • Tile Based Deferred 렌더링이 나와서 포워드 방식을 거의 사용 안함.
  • 타일 버퍼는 S(스태틱 비휘발 성격)RAM으로 굉장히 비싸고 빨라서 CPU 가까이 있는 캐시 메모리로 사용되곤 한다. 용량이
    적으며 비싸고 빠르다. D(다이나믹)RAM은 반대이며, GPU에 SRAM이 있고 GPU와 SRAM사이는 매우 빨라 대역폭 문제가 적음.
  • 여기서 Deferred는 위 디퍼드 렌더링의 디퍼드랑 다른 의미로

    버텍스 쉐이더에서 드로우콜 정보를 모두 Geometry Working Set에
    저장하여 모든 드로우콜이 쌓이면 지연후 프래그먼트 쉐이더를 실행해 타일 복사
    그때 프레임버퍼에 한번에 전 타일 데이터 복사.
  • 그리고 G버퍼가 완성이되어야 라이팅을 하는데 이것을 하나의 패스로 묶는데
    Multy pass rendering으로 처리하여 아래 타일별 #0,#1... 로 하나의
    묶어 패스 처리후 타일을 프레임버퍼로 그리기 가능. 두 번 왔다갔다 하지 않고
    라이팅까지 처리하니 대역폭 줄이기 가능. Open GL ES 안되고 메탈 벌칸만
    가능하며 메탈 벌칸 안되면 fallback 으로 Forward로 동작

  • 이렇게 타일을 빠르게 처리하는것을 가속을 받는다 하는데 가속이 깨지는 조건
    으로 옆의 타일의 데이터가 필요하여 프레임버퍼로 가야 되는 경우가 발생.
    예로 Depth of Field(DOF)심도처리를 위한 블러링, SSAO, 굴절, 반사처리시 화면 두 번 그리는게 반사라하며 렌더 타겟이 바뀌게 될 때 타일을 전부
    내보내야 하는 상황,
  • 타일가속을 위해선 해당 옵션을 켜줘야. Native(벌칸, 메탈의 하드웨어에서 제공하는 렌더패스를 이용하는 것)를 사용하여 G버퍼와 라이팅을 타일안에서
    처리하는 등 위 설명에 처리 방법을 사용할 수 있음. 그렇지 않으면 기존
    빌트인처럼 하드웨어 가속을 못 받음. 가속기능 활용은 유니티 URP에서 지원

    성능 두 배 차이남.(성능 개선 10배 효과없고 그래봤자 디퍼드다?)
  • After Transparents로 해야 성능이 더 좋아지는데 Opaque 그리고
    알파 오브젝트도 그려서 프레임버퍼로 가는데 기본값인 Opaque 설정시
    Opaque만 그리고 프레임 버퍼로 가서 읽어들이고(대역폭문제) 다시 타일의
    알파처리후 또 프레임 버퍼로 가서 성능이 떨어짐.
  • 디퍼드는 MSAA가 불가. MSAA는 하드웨어 가속이라 빠르고 품질도 좋다.
    FXAA나 TAA는 포스트 프로세싱.
  • Transparent도 디퍼드에서 안된다.

포워드플러스 렌더링(또는 Tiled 포워드 쉐이딩)

  • 포워드+ 렌더링이 URP 14버전(유니티 2022.2)부터 가능. (현재 베타)
  • TBDR은 프레임 버퍼를 쪼개서 여러개 타일만들고 하드웨어 지원이라면 여기
    타일은 화면은 나누긴하는데 라이트만 타일로 나눠서 관리하는 개념.
  • Global Light 리스트는 씬의 라이트들중 컬링되지 않은 라이트이며
    Tile Light Index는 라이트가 조합되는 리스트들을 나타낸다.
  • forward+는 매 프레임마다 위 타일 정보들을 만들고 갱신하며 그 데이터를
    프레그먼트 쉐이더로 가져와서 처리.
  • 라이트 컬링시 프로스텀 컬링뿐만아니라 오브젝트에 가려져서 안보이는 라이트
    , 오브젝트에 비춰지지 않은 라이트들도 컬링된다.
  • 위 컬링이 연산이 많아서 GP(General Purpose)GPU를 사용을 많이함.
    범용목적으로 사용하는 GPU. 컴퓨터 쉐이더를 이용하여 타일 연산을 많이 함.
  • SIMD(Single Instruction Multi Data) 아키텍처(멀티 인스트럭션을
    한꺼번에 처리) 나 Multi-Core (사용하여 최신 모바일에서 지원) 이용하여
    유니티에서는 라이트 컬링을 이걸 이용하여 효율적으로 처리 가능.
  • URP 의 Forward+는 타일연산에 컴퓨터 쉐이더 덜 범용적이라 유니티는
    채택하지 않고를 사용하지 않고(현재는), Job & Burst로 SIMD와
    Multi-Core를 활용한다.
  • 라이트 컬링에 256(모바일은 32)개의 라이트까지만 지원.(현재는, 개선여지)
  • MSAA 사용가능, VR은 현재까지는 미지원(VR은 카메라가 두 벌이라
    오버헤드 있어서 현재는 미지원, 개선여지), OpenGL ES2 미지원
  • per vertex로 라이팅을 선택하여 연산을 절약할 수 있다.

기타

  • 2D의 오더인레이어(렌더링 순서를 조작할 수 있는 기능?) 뎁스 버퍼를 쓰지 않는다.
    뎁스 퍼버는 불투명만 가능하며 2D 스프라이트는 모두 투명 오브젝트이며 투명은 맨뒤부터 앞의 오브젝트로 그린다.
  • 더블버퍼링 : 랜더링 되고있는 버퍼가 있고 그뒤에 준비된 화면에 보이지 않는 백버퍼가 준비된다.
    그것이 교환되면서 보여진다. 트리플 버퍼링은 3개로 미리 미리 준비해서 프레임이 준비되지 않아서
    생기는 프레임 드랍을 방지한다. 엔비디아 설정에 삼중버퍼링 설정이 있음. 높은 프레임이 요구될때 사용한다.
  • 포인트라이트가 유니티에서는 스피어지만, 엔진마다 사각형 또는 육각형이
    될 수 있다. 라이트도 여러 개를 한번에 그리는 배칭이 일어날 수 있다.
    그런데 구형의 경우 버텍스가 많아 배칭하는데 비효율적일 수 있어 그렇다.
  • 클리어 코트는 Complex Lit 쉐이더로 처리
profile
개고운(개발,고양이,운동)

0개의 댓글