我正在製作一個OpenGL C++應用程序,用於跟蹤用戶相對於屏幕的位置,然後將呈現的場景更新爲用戶的視角。這被稱爲「桌面VR」,或者您可以將屏幕想象爲立體佈景或魚缸。我對OpenGL相當陌生,迄今爲止只定義了一個非常簡單的場景,只是一個立方體,並且它最初是正確渲染的。OpenGL桌面虛擬現實的非對稱Fr 012
問題是,當我開始移動並想要重新渲染立方體場景時,投影平面似乎已經翻譯過了,我沒有看到我認爲我應該做的事。我想要修理這架飛機。如果我正在寫一個光線追蹤器,我的窗口將永遠是固定的,但我的眼睛可以漫步。有人可以向我解釋如何讓我的相機/眼睛在非原點座標上漂移時如何達到我想要的效果(固定觀看窗口)?
我發現所有的例子都要求相機/眼睛在原點,但這對我來說在概念上並不方便。另外,因爲這是一個「魚缸」,所以我將d_near設置爲z = 0的xy平面。
在屏幕/世界空間中,我將屏幕中心分配給(0,0 ,0)以及它的四個角落到: TL(-44.25,25,0) TR(44.25,25,0) BR(44.25,-25,0) BL(-44.25,-25,0) 對於16x9顯示器,這些值以釐米爲單位。
然後,我使用POSIT計算用戶的眼睛(實際上是我臉上的網絡攝像頭),通常位於(+/- 40,+/- 40,40-250)範圍內的某處。我的POSIT方法是準確的。
我正在爲透視和查看變換以及使用着色器定義我自己的矩陣。
我初始化如下:
float right = 44.25;
float left = -44.25;
float top = 25.00;
float bottom = -25.00;
vec3 eye = vec3(0.0, 0.0, 100.0);
vec3 view_dir = vec3(0.0, 0.0, -1.0);
vec3 up = vec3(0.0, 1.0, 0.0);
vec3 n = normalize(-view_dir);
vec3 u = normalize(cross(up, n));
vec3 v = normalize(cross(n, u));
float d_x = -(dot(eye, u));
float d_y = -(dot(eye, v));
float d_z = -(dot(eye, n));
float d_near = eye.z;
float d_far = d_near + 50;
// perspective transform matrix
mat4 P = mat4((2.0*d_near)/(right-left), 0, (right+left)/(right-left), 0,
0, (2.0*d_near)/(top-bottom), (top+bottom)/(top-bottom), 0,
0, 0, -(d_far+d_near)/(d_far-d_near), -(2.0*d_far*d_near)/(d_far-d_near),
0, 0, -1.0, 0);
// viewing transform matrix
mat4 V = mat4(u.x, u.y, u.z, d_x,
v.x, v.y, v.z, d_y,
n.x, n.y, n.z, d_z,
0.0, 0.0, 0.0, 1.0);
mat4 MV = C * V;
//MV = V;
從我收集看着網頁,我view_dir上最多是保持固定。這意味着我只需要更新d_near和d_far以及d_x,d_y和d_y?我在我的glutIdleFunc中執行此操作(空閒);
void idle (void) {
hBuffer->getFrame(hFrame);
if (hFrame->goodH && hFrame->timeStamp != timeStamp) {
timeStamp = hFrame->timeStamp;
std::cout << "(" << hFrame->eye.x << ", " <<
hFrame->eye.y << ", " <<
hFrame->eye.z << ") \n";
eye = vec3(hFrame->eye.x, hFrame->eye.y, hFrame->eye.z);
d_near = eye.z;
d_far = eye.z + 50;
P = mat4((2.0*d_near)/(right-left), 0, (right+left)/(right-left), 0,
0, (2.0*d_near)/(top-bottom), (top+bottom)/(top-bottom), 0,
0, 0, -(d_far+d_near)/(d_far-d_near), -(2.0*d_far*d_near)/(d_far-d_near),
0, 0, -1.0, 0);
d_x = -(dot(eye, u));
d_y = -(dot(eye, v));
d_z = -(dot(eye, n));
C = mat4(1.0, 0.0, 0.0, eye.x,
0.0, 1.0, 0.0, eye.y,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0);
V = mat4(u.x, u.y, u.z, d_x,
v.x, v.y, v.z, d_y,
n.x, n.y, n.z, d_z,
0.0, 0.0, 0.0, 1.0);
MV = C * V;
//MV = V;
glutPostRedisplay();
}
}
這裏是我的shader代碼:
#version 150
uniform mat4 MV;
uniform mat4 P;
in vec4 vPosition;
in vec4 vColor;
out vec4 color;
void
main()
{
gl_Position = P * MV * vPosition;
color = vColor;
}
好吧,我做了一些修改我的代碼,但沒有成功。當我在頂點着色器中使用V代替MV時,一切看起來都是我想要的,透視圖是正確的,並且對象的尺寸是正確的,但是場景是通過攝像頭的位移來轉換的。
當使用C和V獲取MV時,我的場景從觀察者的視角直接渲染,渲染的場景按照它應該填充的窗口,但是眼睛/相機的視角丟失。
真的,我想要的是通過適當的眼睛/相機的x和y值來平移2D像素,即投影平面,以保持物體的中心(其xy中心爲(0, 0))在渲染圖像的中心。我在教科書「交互式計算機圖形學:基於Shader的OpenGL(第6版)的自頂向下方法」中得到了指導。使用與網絡上免費提供的圖書配對的文件,我繼續採用主要方法。
當不使用矩陣C創建MV時會拍攝以下圖像。當我使用C創建MV時,所有場景看起來像下面的第一張圖片。我希望在z中沒有翻譯,所以我把它作爲0。
因爲投影平面和我的攝像機平面是平行的,所以從一個座標系轉換到另一個座標系僅僅是一個平移和inv(T)〜-T。
這裏是我的眼睛圖像在(0,0,50):
這裏是在我的眼睛圖像(56,-16,50):
一些視頻鏈接到該項目:[背景](https://www.youtube.com/watch?v=Hnn-uZPdJIY)和[結果](https:/ /www.youtube.com/watch?v=EkRiAxPImeo) –