Home 6. Sorting & depth
Post
Cancel

6. Sorting & depth

서론


오늘은 적당히 기술입니다.

저번에 정리하고자 햇던 내용들을 한번 적당히 공부하며 담아보았습니다.

지오메트리 노드


속으면 안됩니다.

지오메트리 노드라고 해서

Untitled

어? 그러면 렌더파이프라인에 있던 그 지오메트리????

아닙니다.

Position Node

Untitled

여기서 object 좌표계(coordination, space) 및 view, world는 알만합니다.

하지만 tangent space는 무엇일까요?

평면을 옆에서 봤을 때 밑면과 이루는 탄젠트 값이 즉 이 평면의 기울기를 결정하기 때문에 tangent space 라고 부른다.

폴리곤의 평면에서 수직인 법선(normal)로 폴리곤의 기울기 값을 만들고,

접선의 나머지 두 축으로 어느방향으로 기울었는지를 나타내어, 이 세개의 축을 가지고 만든 좌표계를 접선 좌표계라고 부르고 이 좌표계가 존재하는 공간을 접선 공간(tangent space)이라고 한다.

결국 텍스쳐 좌표계인 Vector2가 필요하니, 면과 수직인,

텍스쳐에서 존재할 수 없는 벡터를 Normal로,

텍스쳐좌표계에서 사용하는 x와 y를 탄젠트(tangent)와 바이노말(binormal)로

표현한 것이 탄젠트 좌표계(공간)입니다.

아무튼 이 데이터는 어떻게 가져올 수 있는걸까요?

쉐이더를 생성합니다.(버튼 길이 안맞는거 좀 화나요) 쉐이더를 생성합니다.(버튼 길이 안맞는거 좀 화나요)

생성된 쉐이더를 확인해보면 몇가지가 더 추가되었습니다.

Untitled

Object의 Position은 기존에 있는 ObjectSpacePosition을,

나머지 정보들은 각각 버텍스 입력단에서 가져오도록 선언합니다.

‘그곳’ ‘그곳’

UV 채널

Untitled

또 이런 지오메트리 데이터가 무엇이 있는가.

바로 라이트맵 UV입니다.

더미 Box001의 UV. (저는 맥스를 쓸줄 모릅니다) 더미 Box001의 UV. (저는 맥스를 쓸줄 모릅니다)

Untitled

Generate Lightmap UVs를 체크하면 라이트맵용 uv를 자동으로 생성해줍니다.

라이트맵 UV는 서로 픽셀침범이 일어나지 않게 조금씩 떨어져서,

독립적으로 구워지도록 생성해주는데

유니티에서 자동 생성해주는 라이트맵 UV 유니티에서 자동 생성해주는 라이트맵 UV

이를 어딘가에 저장해야합니다.

그렇다면 이 UV정보는 어디에 저장될까요?

Untitled

답은 UV Channel1입니다.

그렇다면 그렇게 얻은 정보를 또 쉐이더에서 작업할 수 있겠죠?

Untitled

UV채널 0과 UV 채널1의 변화를 볼 수 있습니다. UV채널 0과 UV 채널1의 변화를 볼 수 있습니다.

그래서 어? 라이트맵 UV를 가져올 수 있으면 라이트맵 텍스쳐를 가져와서 뭔갈 할 수 있지 않을까?

라는 생각을 했습니다.

Untitled

역시 유니티는 생각이 있었습니다.

Baked GI를 가져올 수 있었습니다.

그래서 static UV는 UV1, 즉 기본적으로 두번째 채널을 쓰고 있다는것을 확인할 수 있죠.

간단한 라이트맵 블렌딩 간단한 라이트맵 블렌딩

만약 이런걸 사용해서 무엇을 할 수 있을지 생각하니,

얼굴을 확대했을때 UV채널과 텍스쳐를 두개 뽑아서 더 디테일한 확대를 구현할 수 있을 것입니다.

저는 맥스에서 UV2개를 뽑는법을 몰라서 못합니다!!

이렇게하면 안되나요?(모름) 이렇게하면 안되나요?(모름)

반투명 오브젝트의 소팅

early depth Test(Early Z rejection)

뎁스테스트는 그러면 어떻게 처리할 수 있을까요?

일단 없으면 그리고, 더 작으면(Less Equal) 그리고, 아니면 파기합니다.

얼마나 비효율적인가요?

그래서 몇몇 Pre-Sample Processing Test를 허용하는 대부분의 GPU에서는

프래그먼트 쉐이더 처리 전, 프래그먼트를 폐기(discard)하는 기능을 지원합니다.

하지만 하드웨어 기반 몇가지 제약이 있습니다.

예를 들어

  • 알파테스트-(deprecated) alpha test-가 활성화 된 경우, early depth test를 하지 않습니다.
  • 혹은 fragment에서의 Depth Write(gl, gl_FragDepth)가 켜져있을 경우 early depth Test를 진행하지않고 Late depth test를 진행합니다.
  • 또한 fragment shader에서 discard를 사용할 경우 일부기기에서 early depth test를 비활성화합니다. (https://www.khronos.org/opengl/wiki/Fragment_Shader#Special_operations, discard의 경우 depth write등을 무시하는데, 그런데도 불구하고 왜 비활성화되는지는 잘 모르겠습니다.)

(프래그먼트 쉐이더 처리도중 뎁스값이 변화될 수 있기 때문이라고 추측합니다)

하지만 요즘도 그런지는 더 자세한 개념을 알아봐야 알 수 있습니다.

Tiling Architecture

The OpenGL virtual pipeline requires a large amount of bandwidth. For a fairly typical use-case, each pixel will require a read from the depth/stencil buffer, a write back to the depth/stencil buffer, and a write to the color buffer, say 12 bytes of traffic, assuming no overdraw, no blending, no multipass algorithms, and no multisampling. With all the bells and whistles, one can easily generate over 100 bytes of memory traffic for each displayed pixel. Since at most 4 bytes of data are needed per displayed pixel, this is an excessive use of bandwidth and hence power. In reality, desktop GPUs use compression techniques to reduce the bandwidth, but it is still significant.

To reduce this enormous bandwidth demand, many mobile GPUs use tile-based rendering. At the most basic level, these GPUs move the framebuffer, including the depth buffer, multisample buffers, etc., out of main memory and into high-speed on-chip memory. Since this memory is on-chip, and close to where the computations occur, far less power is required to access it. If it were possible to place a large framebuffer in on-chip memory, that would be the end of the story; but unfortunately, that would take far too much silicon. The size of the on-chip framebuffer, or tile buffer, varies between GPUs but can be as small as 16 × 16 pixels

in OpenGL Insights

과거에 주력으로 하던 렌더링 방식,Immediate Mode은 최근 자주 사용하지 않습니다.

요즘에는 Tiling Architechure (Tiled Rendering)을 많이 사용하는데,

스마트폰에 들어가는 snapDragon 시리즈의 GPU, adreno나

nVidia의 Maxwell 아키텍처 GPU, AMD의 Vega(GCN5) 아키텍처,

intel의 11세대 gpu들이 이를 사용합니다.

자세히 들어가봅시다.

(https://developer.arm.com/solutions/graphics-and-gaming/developer-guides/learn-the-basics/tile-based-rendering/single-page)

Untitled

기존 방식의 렌더링은 각 픽셀마다 32비트, 깊이/스텐실에 32비트를 사용하였습니다.

그렇다면 해상도가 1440p라면 총 30MB의 메모리를 필요로하며, 이는 고해상도에서 대역폭 부하가 커질 수 있음을 말합니다.

따라서 타일 기반 렌더링에서는 이를 적정사이즈로 잘라서, 메모리를 적게 쓰니 뎁스와 스텐실 정보까지 고속으로 접근하여 처리하도록 꾀하였습니다.

하지만 문제가 있습니다.

in OpenGL Insights in OpenGL Insights

플러시를 사용하거나 오클루전 컬링를 하거나, 렌더텍스쳐를 사용하게 될 경우

프레임버퍼 내용을 모두 최신화 하기 때문에, 성능적으로 문제가 발생될 수 있습니다.

그래서 이게 무슨말이냐

간단하게 멀티샘플링 같은 경우에서 문제가 발생할 수 있다는 이야기입니다.

왜냐하면 DRAM에 작성한 다음, 다시 GPU에 읽어야해서 제한된 대역폭에서 문제가 생길 수 있기 때문입니다.

Untitled

Untitled

Unity Depth prepass (urp 12)

2021.2버전을 이번년도에 처음쓰다보니 이건 처음봤습니다.

Untitled

위(대과거)에서 말했던 early depth test를 unity에서 구현한 내용입니다.

In general, external DDR bandwidth costs 100mW per GB/s. Therefore, in our example, this overhead uses 790mW of our total 2.5 watt device power budget just to write the framebuffer.

auto로 설정하면 위에서 설명한 Tiling Architecture 에서 MSAA와 혼합하여 사용하였을 때의 성능이슈 및 대역폭사용량으로 인한 전력 사용량을 고려하는 기기에서(안드로이드, ios 등) 사용하지 않게 됩니다. (추측)

URP 실습

일단 다 transparent로 해서 다 뿌셔봅시다.

잘- 부셔진 뎁스

잘- 부셔진 뎁스

이를 렌더 프로파일링 도구에서 확인하면

Untitled

2번째 output인 _CameraDepthAttachment에 뎁스를 기록하지 않는 것을 볼 수 있습니다

렌더링 설정에서 Transparent를 렌더링하기 전,

Transparent Queue에 해당되는 오브젝트를 한번 렌더링하여 깊이를 그립니다.

Untitled

그렇다면

Untitled

제대로 그려지고, 뎁스정보도 그리는것을 볼 수 있습니다.

짜잔

GIF 2022-04-13 오후 10-42-56.gif

추가적으로 alpha clipping 된 depth 정보 몇개 던져놓고 이만 말을 줄이겠습니다.

그린 : Opaque Alpha clipping, 레드 : Transparent 그린 : Opaque Alpha clipping, 레드 : Transparent

Untitled

Untitled

Transparent Depth Test(Write)

이경우는 정확히는 Late depth test라고 볼 수 있을 것 같습니다.

기술 참조


OpenGL Insights

타일 기반 렌더링 : https://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-TileBasedArchitectures.pdf

크로노스 - OpenGL Wiki

early fragement test : https://www.khronos.org/opengl/wiki/Early_Fragment_Test

discard : https://www.khronos.org/opengl/wiki/Fragment_Shader#Special_operations

퀄퀌

아드레노 타일기반 렌더링 : https://developer.qualcomm.com/sites/default/files/docs/adreno-gpu/developer-guide/gpu/best_practices_tiling.html#avoid-gmem-loads

arm

타일기반 렌더링 : https://developer.arm.com/solutions/graphics-and-gaming/developer-guides/learn-the-basics/tile-based-rendering/single-page

멀티샘플링 안티앨러싱 : https://developer.arm.com/documentation/102479/0100/Multi-sample-anti-aliasing

Mali 프로세서:

https://developer.arm.com/Processors/Mali-450

맺으며


교수님이 말씀해주신 ‘제가 궁금할만한 문서’를 토대로

기술문서를 분석하면서 공부하니 시간도 오래걸리고 재미있었습니다.

렌더독도 써보고 라이트맵도 나눠보고 재미있는게 많았습니다.

This post is licensed under CC BY 4.0 by the author.
Contents