왜 z로 나누기 위해 네 번째 좌표가 필요한가요?


12

나는 여기에 응답을 읽었습니다.

그래픽 카드는 벡터의 네 번째 요소를 최종 위치로 어떤 역할을합니까?

"제 4의 구성 요소는 원근 투영을 추적하는 트릭입니다. 원근 투영을 수행 할 때 z로 나눕니다 : x '= x / z, y'= y / z, 그러나 이것은 조작이 아닙니다 x, y, z의 벡터에서 작동하는 3x3 행렬로 구현할 수 있습니다.이 작업의 표준이 된 트릭은 네 번째 좌표 w를 추가하고 x, y, z는 항상 w로 나눌 것이라고 선언하는 것입니다. 모든 변환이 적용된 후 및 래스터 화 전에 "

그러나 왜 우리가 3x3 행렬을 사용하여 z로 나눌 수 없었는지를 이해하지 못했습니까?

우리는 그냥 곱할 수 없습니다

1/z 0 0
0 1/z 0
0 0 1/z

얻을 [x/z y/z 1]

?


체인 어딘가에 번역이 포함 된 변환 (또는 변환 구성)을 표현하십시오. 값이 없으면 단일 행렬로 표현할 수 없습니다.
DMGregory

나는 번역 부분을 이해하지만 나는 단지 네 번째 좌표를 추가하는 것이 어떻게 도움이되거나 z로 나눌 수있는 트릭인지 이해하지 못했다

그 가치가있는 것에 대해 당신은 당신이 말한 것을 완전히 할 수 있습니다. x와 y를 z로 나누는 것은 먼 거리의 물체가 더 작아지는 투영법으로 3D 좌표에서 2D 화면 공간으로 변환하는 유효한 방법입니다. w는 변환을 수행 할 수 있도록 네 번째 차원까지 가져 오는 균질 좌표입니다.
Alan Wolfe

답변:


14

만 나눈다면 때문에 [x, y, z]에 의해 z당신이 얻을 [x/z, y/z, 1]당신이의 실제 값 손실 z이 가까이 / 멀리 평면 클리핑을 또는 Z 버퍼를 채우려는 경우 실제로 유용하다.

z적어도 GPU에 대한 정보를 유지하는 가장 좋은 방법 은 따라서 3 대신 4 개의 구성 요소를 사용하는 것입니다. 실제로, 투시 분할 이전의 마지막 두 벡터 구성 요소는 실제로 어떤 종류의 투영 및 효과에 따라 달라집니다 필요.

예를 들어, 투시 투영의 경우 결과 4 성분 벡터입니다.

| a 0 0 0 |   | x |   |   ax   |
| 0 b 0 0 |   | y |   |   by   |
| 0 0 c d | × | z | = | cz + d |
| 0 0 1 0 |   | 1 |   |    z   |

원근 분할 후 벡터는 다음과 같이됩니다.

|  ax/z   |
|  by/z   |
| c + d/z |
|    1    |

그리고 그 c + d/z부분은 Z 버퍼를 채우기에 충분한 정보를 남겼습니다.


X와 Y 만 Z로 나누면 [x / z, y / z, z]가 나옵니다. GPU가되지 않습니다 벡터 부문을 수행하는, 어떤 계산을 할 수 있도록 설계되었습니다 수 있습니다.
user253751

3

기술적으로 그렇게 할 있습니다. 그런데 왜 귀찮게? 당신이 그 마지막을 가질 때까지 z, 당신은 다음 중 하나를 할 수 있습니다 :

  • 설명 된대로 3x3 행렬을 구성하고, 9 * sizeof(float)바이트 공간을 낭비하고 , 계산주기를 소비하여 1/z(1 나누기) 9 번 곱하기와 6 번 더하여 최종 정점을 얻습니다. 또는
  • 현대 파이프 라인이 현재하는 것처럼 세 개의 디비전을 수행 할 수 있습니다.

이 중 하나가 나에게 훨씬 더 최적 인 것 같습니다. 첫 번째가 아닙니다. 매트릭스에 최적화 된 하드웨어가 여러 번 존재하더라도 가장 확실한 방식으로 단순 분할보다 개념적으로 더 복잡합니다.

또한, 3 × 3 행렬은 번역을 인코딩 할 수 없으며, 4 × 4 매트릭스 있도록 (따라서 네 번째 w좌표) 파이프 라인의 이전에 사용됩니다 어쨌든 . 즉, 네 번째 구성 요소가 이미 거기에 있으므로 유용한 값을 전송하고 나누는 데 사용할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.