簡體   English   中英

使用GLM +答案將屏幕轉換為3D世界坐標后結果不佳

[英]Bad results after transforming screen to 3D world coordinates with GLM + Answer

我正在開發3D android游戲,但我是新手。 我正在使用GLM,Android NDK,Opengl ES 2.0。

當我觸摸屏幕時,我想獲得世界空間中的3D點。

我的部分代碼:

//Camera data
float eye[3]  = {0.0f, 11.0f, -2.0f};
float look[3] = {0.0f, -1.0f, 3.0f};
const float up[3] = {0.0f, 1.0f, 0.0f};

glViewport(0, 0, width, height);
...
const float ratio = (float) width / height;
mViewMatrix = glm::lookAt(glm::make_vec3(eye), glm::make_vec3(look), glm::make_vec3(up));
mProjMatrix = glm::perspective(30.0f, -ratio, near, far); // near = 1.0f; far = 100.0f;
mMVPMatrix = mProjMatrix * mViewMatrix;
....

我嘗試了這個:

glm::vec3 worldXYZ = glm::unProject(glm::vec3(x, height - y, 1.0f), mViewMatrix, mProjMatrix, glm::vec4(0, 0, width, height));

其中x和y是屏幕坐標(以像素為單位),但是得到奇怪的結果。 當我觸摸origo示例時,結果應該是(0,0,0) ,但我得到的是: (0.5, -89.6, 16)

我在哪里弄錯了?


更新我的答案:

Andon M. Coleman是正確的,我根據他的回答對代碼進行了更改。 我沒有使用glm::unProject方法,因為最終結果很差,所以我退后了一步,自己計算了一下東西。

float xx = (2.0f * x) / width - 1.0f; // between [-1;+1]
float yy = (2.0f * (height - y)) / height - 1.0f;  // between [-1;+1]
float zzN = 0.0f; // near
float zzF = 1.0f; // far

glm::mat4 invM = glm::inverse(mMVPMatrix);

glm::vec4 mmN = invM * glm::vec4(xx, yy, zzN, 1.0f);
glm::vec4 mmF = invM * glm::vec4(xx, yy, zzF, 1.0f);

歸一化向量:

glm::vec3 nn = glm::vec3(mmN[0] / mmN[3], mmN[1] / mmN[3], mmN[2] / mmN[3]);
glm::vec3 ff = glm::vec3(mmF[0] / mmF[3], mmF[1] / mmF[3], mmF[2] / mmF[3]);

然后我需要射線(從nn到ff)。 我用了這個線方程:

x = x1 +(x2-x1)* t

y = y1 +(y2-y1)* t

z = z1 +(z2-z1)* t

其中P(x,y,z)是射線中的點,nn =(x1,y1,z1)和ff =(x2,y2,z2)是定義射線的2個點。 我對y = 0(射線和平面相交)的點很感興趣,所以最終我像這樣計算了x和z世界坐標:

float t = nn[1] / (nn[1] - ff[1]);
float wx = nn[0] + (ff[0] - nn[0]) * t;
float wz = nn[2] + (ff[2] - nn[2]) * t;

窗口空間(“屏幕坐標”)Z = 1.0是您的遠平面

您已經解決了投影(x, height - y) 最遠點。 在大多數情況下,這並不是特別有用。

無法從2D窗口空間坐標中獲得世界空間中的單個點。 投影不能那樣工作。

您還應該求解最接近的點(Z = 0.0 ),然后可以投射穿過兩個點的射線。 生成的射線將表示投影到(x,y,*)的無限個點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM