2011-05-04 3 views
4

3D 점을 래스터 화하는 과정에서 간단한 투시 투영을 수행하려고합니다. 다음은 모든 행렬 및 기타 정보입니다. 모든 행렬은 주요 행입니다. 좌표계는 오른 손잡이입니다.3D 투영 문제 : 원근감 나누기 후 Z 값이 [1, -1]에 있지 않음

카메라에있다 [0,0, -1] 및 점에있다 [0,0,0] (매트릭스 연산을위한 1 = w)

모델 뷰 매트릭스 (즉 캠 행렬의 역행렬 TX = 0; TY = 0; TZ = 1)

[1 0 0 tx] 
[0 1 0 ty] 
[0 0 1 tz] 
[0 0 0 1 ] 

관점 매트릭스 : 뷰포트 사각형이므로

[f/aspect,0,0,0] 
0,f,0,0 
0,0,-(near+far)/(near-far),2*far*near/(near-far) 
0,0,1,0] 

형태 1과 동일하다. Far = 100 및 Near = 0.1 f = 1/tan (fovDegress * M_PI/360);

결과의 매트릭스는 다음과 같습니다

1.94445, 0,  0,  0 
0,  1.944445, 0,  0 
0,  0,  1.020202, -2.020202 
0,  0,  1,  0 

가 지금은 포인트 벡터에 다음 모델 뷰 행렬과 투영 행렬을 적용하고 나는 새로운 포인트를 얻을 PV = {X, Y, Z, w} 그러면 표준화 된 좌표 x '= x/w를 얻습니다. y '= y/w; 및 z '= z/w이고; 포인트가 절두체에있는 한 x '와 y'는 항상 [-1,1] 사이에 있습니다. 그러나 z '의 경우는 그렇지 않습니다. 포인트가 카메라 근처에서 접근함에 따라 z '값은 기하 급수적으로 증가합니다. 점이 [0,0,0] 일 때 z '값은 -1과 같습니다.

이제는 몇 줄을 잘라야하므로 [1, -1] 사이에 z '값이 필요합니다. 나는 나의 처치에 무엇이 잘못된지 궁금해하고있다. 고맙습니다.

답변

2

당신이 경험 한 것은 원근법 깊이 매핑의 비선형 성입니다. 절두 원추 투영 행렬을 사용하면 이것은 1/x 법칙을 따라 시점으로부터의 거리를 따릅니다.

편집 :

그냥 더블 당신의 행렬을 확인 : 당신은 당신의 절두체 매트릭스 잘못되었다. 정확한 절두체 행렬은

f/aspect, 0,      0,      0 
0,  f,      0,      0 
0,  0, -(far+near)/(far-near), 2*far*near/(far-near) 
0,  0,      1,      0 

입니다. 원점에 접근하면 여전히 0으로 나누어집니다. 그 점을 통해 벡터 (0, 0, 0, 1)을 넣으면 클립 공간에서 (x = 0, y = 0, z = 2 * far * 근처/(far- 근처), w = 0) . 그리고 균질 한 부분 {x, y, z}/(w = 0) ←가 폭발합니다.

+0

그러나 정규화 된 균질의 경우 깊이가 [-1,1]의 범위가 아니어야합니다. 그렇다면 그것이 어떻게 되어야만하는지, OpenGL은 파이프 라인의이 단계에서 어떻게 클리핑을 수행합니까? 제발 저를 참아주십시오. 이해하려고 노력하고 있습니다. 고맙습니다. – rwb

+0

@rwb : 깊이 범위 [-1,1]은 근거리 및 원거리 자르기 기준면 사이에 매핑됩니다. 그러나 관측점 자체는 항상 가까운 클리핑 평면보다 가깝습니다 (원근감 모드에서는 가까운 클립 거리가 0 인 것은 0을 통한 나누기이므로 불법입니다). – datenwolf

+0

아! 그래서 카메라면 가까이에 선을 감을 수 없습니까? 니어 클리핑 평면에서만 수행해야합니까? 그렇다면 가까운 클리핑면은 0보다 작지 만 1보다 작을 수 있습니까? 내 경우에는 near가 0.1이지만 캠이 (0,0, -1)이고 점이 (0,0, -0.9)이면 z 값은 여전히 ​​천문학적으로 높습니다. 그것은 가까운 비행기에서 그 좌표 이후의 범위에 있어야하지 않아? – rwb