2010-01-20 3 views
1

필자는 필자의 관점에서 256x256 짜임새를 사용하여 텍스처가 화면에 ACTUAL 크기로 복제되는 z 위치로 이동해야합니다.OpenGL : 1 : 1 픽셀 비율의 z 값 계산

는 내가 지금까지있는 것은 : itemSize 세계 공간 (2.0 단위) 내 텍스처의 크기

const float zForTrueScale = -((itemSize/2)/tanf(DEGREES_TO_RADIANS(fieldOfView/2))) * 2;  

. 이것은 itemSize/2 (반대)가 1.0 일 때 Z (인접)가 무엇인지 계산하는 것입니다. 나는 이것이 효과가있을 것이라고 생각했다.

이 수식은 내가 사용하는 FOV에 관계없이 일관되게 약 10 %의 텍스처가 너무 작음을 보여줍니다.

감사

편집 : 나는 3D 공간에서 이미지를 주위에 이동하고 올바른 Z-거리로 원활하게 전환 할 필요가 있어요. 나는 정사영 투영법을 사용할 수 없다. 그것은보기 절두체에 있어야한다.

답변

6

필요로하는 정보가 프로젝션 매트릭스에 직접 저장되어 있기 때문에 시야각을 어지럽히 기보다 약간 더 쉽게 할 수 있습니다.

따라서는 투영 행렬은 다음과 같을 것이다 주어진다 :

Z-파 (ZF) 및 (Z) - 근처 (아연), 엑스 스케일과 yScale 공지되어
xScale  0    0      0 
0  yScale   0      0 
0   0  -(zf + zn)/(zf - zn) -(2 * zf)/(zf-zn) 
0   0    -1      0 

.

정확한 Z-Depth를 선택하려면 w가 1로 끝나는 지 확인해야합니다.이 방법으로 w로 나누면 아무 것도 바뀌지 않습니다.

다행히도 w는 매우 쉽습니다. 그것은 단순히 입력 z의 음수입니다. 따라서 z에 -1을 입력하면 1의 w가 반환됩니다.

사용자가 1024x768의 해상도를 사용하고 올바른 크기로 원하는 텍스처가 256x256이라고 가정합니다.

또한 사각형의 왼쪽 상단이 -1, 1, 오른쪽 하단이 1, -1로 설정되어 있다고 가정합니다.

그래서 이것을 끼워 넣어 z를 풀어보세요.다음과 같이

-1, 1, -1, 1 
1, -1, -1, 1 

우리가 뭔가를 얻을 것이다 : 우리는 다음과 같은 사용하는 경우

.

1/xScale, -1/yScale, someZThatIsn'tImportant, 1 
-1/xScale, 1/yScale, someZThatIsn'tImportant, 1 

뷰포트 변환은 그 값이 변환되도록 -1, 1 0, 0, 1, -1 1024,768

그래서 우리는 수행하여 작동 것을 확인할 수있다 ((X + 1)/2) * 1024 그리고 ((1 - y)/2) * 768

우리가 3/4의 xScale과 1의 yScale을 가정하면 우리는 그것을 연결함으로써 다음과 같은 것을 얻을 수 있음을 알 수 있습니다 :

좌측 상단 :

x = -3/4 
=> ((-3/4 + 1)/2) * 1024 
=> 128 
y = 1 
=> ((1 - 1)/2) * 768 
=> 0 
01 오른쪽 아래에 들어 23,516,

:

x = 3/4 
=> ((3/4 + 1)/2) * 1024 
=> 896 
y = -1 
=> ((1 + 1)/2) * 768 
=> 768 

당신은 따라서 우리가 화면 중심 768x768 픽셀 이미지를 볼 수 있습니다. 분명히 256x256을 얻으려면 w가 3이되도록해야합니다. 따라서 w를 나누면 좌표 (xScale * 1024)/256이 (yScale * 768)/256과 같아야 정사각형이됩니다. . 투사

다음과 같이 우리의 최종 좌표는 그래서 경우 :

-1, 1, -3, 1 
and 
1, -1, -3, 1 

우리는 (w-분할 후) 밖으로 다음 얻을 것이다 :

-0.25, 0.333, unimportantZ, 1 
and 
0.25, -0.333, unimportantZ, 1 

위의 화면 방정식을 통해 사람들을 실행하고 우리는

을 얻습니다.

x = -0.25 
=> ((-0.25 + 1)/2) * 1024 
=> 384 
y = 0.3333 
=> ((1 - 0.3333)/2) * 768 
=> 256 

오른쪽 아래의 경우 : 왼쪽 상단의 경우 63,210

x = 0.25 
=> ((0.25 + 1)/2) * 1024 
=> 640 
y = -0.333 
=> ((1 + 0.33333)/2) * 768 
=> 512 

640 - 384 = 256 
512 - 256 = 256 

따라서 우리는 지금 올바른 픽셀 크기의 최종 RECT ...

+0

와우, 멋진 답변, 고마워요. – Sam

2

상황을 너무 많이 모르는 상태에서 직교 투영을 투영 매트릭스 스택으로 밀어 넣고 텍스처를 그린 다음 다시 튀어 나오게하는 것이 거의 확실합니다.

+0

아니, 난 주위에 이동하고 이미지의이 3D 공간과 올바른 z- 거리로의 완벽한 전환이 필요합니다. 직각 투영을 사용할 수 없으며 3D로 구현되어야합니다. – Sam

+1

아 좋아. 죄송합니다 - 오해. 이 경우 : 제 삼부는 꽤 녹슬었지만 결국에는 곱셈이 필요합니까? – Pike65

0

비록 느리지 만 glDrawPixels()을 사용하면됩니다.

... 성능면에서 중요하지 않더라도!

0

프레임 버퍼가 사각형입니까?

그렇지 않은 경우 수평 시야와 수직 시야가 있습니다. 올바른 것을 사용하고 있습니까? 또한 세계 좌표계에서 2.0 단위가되도록하려면 어떻게 알 수 있습니까? 최종 목표가 픽셀로 매핑되는 경우 뷰포트를 고려해야하며이를 다시 처리해야합니다.

나는 또한 * 2가 어디서 오는지 Pike65에 동의한다.

+0

* 2는 삼각대가 반대쪽의 길이 (항목 너비의 절반)를 사용하고 있기 때문에 끝 부분에서 전체 길이를 얻기 위해 다시 곱하기 때문입니다. 나는 처음부터 항목 너비를 절반으로 줄이지는 못했지만 그 당시 나에게 더 잘 읽었습니다. 어쨌든, 제 질문은 "어떻게 뷰포트를 고려하여 다시 작업해야합니까?"입니다. 내 프레임 버퍼가 사각형입니다. – Sam

+0

최종 결과에 13.5/FOV를 추가하면 모든 FOV에 대해 정확한 결과를 얻을 수 있다는 것을 알게되었습니다. 그러나 13.5가 어디서 왔는지 이해하지 못합니다. 현재 코드에 끔찍한 마법 번호가 있습니다. – Sam

+0

trig :/2의 경우 항목 너비의 절반을 얻는 것이 좋습니다. tan()은/z 항목의 절반입니다. * 2는 거기에 관여하지 않습니다. 무승부 시점의 뷰/proj 행렬은 어떻게됩니까? 텍스처를 그리기 위해 어떤 쿼드를 전달합니까? – Bahbar