티스토리 뷰

Unity/Shader Graph

Orthographic Depth

연홍 2021. 1. 19. 10:38
728x90

PERSPECTIVE

Perspective 카메라 투영에서 깊이 텍스처를 샘플링하면 (Scene Depth가 Raw모드로 설정 됨) 0~1사이의 값을 반환하여 근거리에서 원거리 카메라 클리핑 평면에서 깊이를 인코딩합니다 (또는 플랫폼이 반전 된 깊이 버퍼를 사용하는 경우 그 반대도 마찬가지입니다). 값은 비선형입니다. 이는 0.5 값이 두 클리핑 평면 사이의 중간에 있지 않음을 의미합니다. (이것은 정밀도를 높이기위해)

 

대부분의 효과에 대해 이 값을 Linear01Depth 및 LinearEyeDepth 함수 (또는 Linear01 또는 Eye 모드로 설정된 Scene Depth)를 사용하여 수행되는 linear01 또는 linear-eye 값으로 변환하려고합니다. 이러한 기능/모드는 플랫폼 차이 (역방향 깊이 버퍼)를 처리하므로 출력은 모든 플랫폼에서 동일해야합니다.

ORTHOGRAPHIC

그러나 직교 투영에서 깊이 텍스처를 샘플링하면 (Scene Depth가 Raw 모드로 설정 됨) 이미 선형적인 0~1 값이 반환됩니다. 변환하고 싶지 않다면 반드시 Raw 모드를 사용해야합니다!

 

그러나 앞에서 언급했듯이 깊이 버퍼는 대상 플랫폼에 따라 반전 될 수도 있으므로 값을 사용하기 전에 이를 고려해야합니다. 이는 카메라 노드 (일명 _ProjectionParams.x)에서 출력 된 Z 버퍼 사인을 사용하여 수행되며, 깊이가 반전되면 -1을 반환하고 그렇지 않으면 1을 반환합니다. 우리는 이것을 Branch에서 비교할 수 있고, 반대로 뒤집 으면 깊이 출력에 One Minus 노드를 다음과 같이 사용하고 싶습니다.

이 출력은 이제 0과 1 사이이며 대상 플랫폼에 관계없이 근거리에서 원거리 클립 평면에 도달합니다.

 

대부분의 효과의 경우 뷰 공간 단위의 깊이를 갖기 위해 근거리 및 원거리 클립 평면으로 Lerp해야 할 수도 있습니다.

(이는 원근 투영에 대한 LinearEyeDepth / Eye 모드 출력에서 ​​제공하는 결과와 유사해야합니다. 카메라 / 눈 공간이라고도합니다. 기본적으로 월드 공간의 회전 / 오프셋 버전이므로 카메라가 음의 z 축을 내려다 보는 원점에 있습니다. 단위 배율은 게임 오브젝트의 inspector 값)

 

다양한 셰이더 분석에서 "Depth Difference"및 "Reconstructing World Position from Depth"기술을 사용했습니다. 둘 다 Fog Plane Shader Breakdown에 나와 있습니다. 아래에서는 이러한 기술에 해당하는 Orthographic을 나열하고, 다시 모든 플랫폼 차이를 고려하여 Direct3D와 OpenGL과 같은 플랫폼 모두에서 작동합니다. 플랫폼 (예 : 모바일)에 따라 먼 클리핑 평면이 너무 멀리 떨어져 있으면 정밀도 문제가 발생할 수 있습니다 (깊이 결과에 밴딩이 표시 될 수 있음).

Depth Difference

이 기술은 두 깊이 값 (뷰 / 눈 공간)의 차이를 사용하여 장면의 오브젝트가 셰이더가있는 오브젝트 (이 경우 평면 / 표면)와 교차하는 그라데이션을 얻습니다.

 

perspective에서 우리는 prejection 행렬에 의해 생성되는 원시 화면 위치 알파(/w) 구성요소를 사용합니다. normalised device coordinates (NDC)로 변환하는 데 사용됩니다. 정점 셰이더와 조각 셰이더 사이에서 클립 공간 좌표를이 알파 (/ w) 구성 요소 (원근 분할이라고 함)로 나누지만 fragment의 뷰 스페이스 깊이이기도 합니다. 그러나 직교 투영에서는이 값이 1에 불과하므로 클립 공간이 이미 정규화되었음을 의미합니다. 이 경우 깊이를 얻기 위해 B/Z 값을 사용해야합니다 (플랫폼에 따라 -1과 1 또는 1과 0 사이). (제가 배운 지식을 바탕으로이 내용을 상당히 요약했습니다. 다른 좌표 공간에 대해 더 많이 읽고 싶다면 이 기사가 매우 유익합니다).

 

아래 그래프는 플랫폼 차이 (예 : 반전 된 깊이 버퍼 및 일부 클립 공간 차이)를 고려하여 직교 투영에서 어떻게 작동하는지 보여줍니다. 마스터 노드도 투명으로 설정되어 깊이 버퍼에 자체 깊이를 쓰지 않습니다.

Custom Function 노드는 다음과 같이 Body와 함께 String 유형을 사용합니다.

Out = float2(
  UNITY_NEAR_CLIP_VALUE,
  UNITY_RAW_FAR_CLIP_VALUE
  );

함수 이름은 중요하지 않지만 GetClipValues로 설정했습니다. 입력은 없지만 하나의 출력(Vector2)이 있습니다. 이 함수의 목적은 근거리 및 클립 평면 "값"을 얻는 것입니다 (실제 클립 평면 거리 인 카메라 노드 출력과는 다릅니다). 이 값을 사용하여 클립 공간 z/depth range를 0~1범위로 다시 매핑합니다.

Direct3D와 유사한 플랫폼 (Direct3D, Metal 및 콘솔)의 경우 다음과 같습니다.

NEAR = 1, FAR = 0

OpenGL과 유사한 플랫폼 (OpenGL 및 OpenGL ES2 / 3)의 경우 다음과 같습니다.

NEAR = -1, FAR = 1

Reconstructing World Position from Depth

Scene 깊이에서 World Space Position를 얻을 수 있다는 것은 매우 유용합니다. (직교 투영을 위해 얻는 것은 원근법보다 더 복잡합니다). Water Shader Breakdown에서 화선 효과를 위한 원근 투영과 앞서 언급 한 안개 효과에도 비슷한 것을 사용했습니다. 아래 그래프는 플랫폼 차이 (역 깊이 버퍼)를 고려하여 직교 투영에서 어떻게 작동하는지 보여줍니다. 마스터 노드도 투명으로 설정되어 깊이 버퍼에 자체 깊이를 쓰지 않습니다.

결과는 Scene Depth에서 재구성 된 월드 위치를 보여 주며 Fraction 노드를 통해 각 유닛을 시각화하는 데 도움이됩니다.

 

'Unity > Shader Graph' 카테고리의 다른 글

UV-Based Nodes  (3) 2021.01.18
World space UVs & Triplanar Mapping  (0) 2021.01.18
Screen Position  (0) 2021.01.15
Voronoi  (0) 2021.01.15
Render Texture  (0) 2021.01.14
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/08   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31