티스토리 뷰
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에서 화선 효과를 위한 원근 투영과 앞서 언급 한 안개 효과에도 비슷한 것을 사용했습니다. 아래 그래프는 플랫폼 차이 (역 깊이 버퍼)를 고려하여 직교 투영에서 어떻게 작동하는지 보여줍니다. 마스터 노드도 투명으로 설정되어 깊이 버퍼에 자체 깊이를 쓰지 않습니다.
'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