2016-07-18 10 views
0

私は、衝突によるレイピッキングを試みます。つまり、画面上の2D位置がモデル空間の3D位置に変換されます。 私の問題は、レイがモデルと常に交差して有効な3D位置にならないということです。2Dエッジから3Dモデル空間へglm :: unproject - rayとモデルが交差しない

は、ここで私は何をすべきかです:

は、私は後でそれからglReadPixels()にフレームバッファに深度テクスチャを作成します。

glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, screenWidth, screenHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); 

cv::Mat_<float> depthCV(screenHeight, screenWidth); 
glReadPixels(0, 0, screenWidth, screenHeight, GL_DEPTH_COMPONENT, GL_FLOAT, depthCV.ptr()); 

私はその後深さを線形化し、エッジ検出のためのcv::Mat_<uchar>にそれを保存cv::Canny()経由:

cv::blur(gray, edge, cv::Size(3, 3)); 
cv::Canny(edge, edge, edgeThresh, edgeThresh * ratio, 3); 

...を介して輪郭を取得する(画像を反転することを忘れないでください。)

0:

cv::findContours(canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE, cv::Point(0, 0)); 

輪郭(S)の2次元座標(x、y)は今の3Dモデルに変換されているビア座標

GLint viewport[4]; 
GLfloat winX, winY, winZ; 
glGetIntegerv(GL_VIEWPORT, viewport); 
winX = (float)x; 
winY = (float)viewport[3] - (float)(y); 
glReadPixels(x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ); 
glm::vec4 viewportvec(viewport[0], viewport[1], viewport[2], viewport[3]); 
glm::vec3 winCoords(winX, winY, winZ); 

glm::vec3 modelCoords = glm::unProject(winCoords, view*model, proj, viewportvec); 

これを実行し、それが示す3D点を見て、一部の光線がモデルと交差しないことを確認します。光線の長さは、遠方平面の値に近い。 入力(x、y)の周りの1つのピクセル近傍を見て入力を拡大しようとしました。まだいくつかの光線はモデルと交差していません。

これは何故でしょうか?またはそれを解決する方法は?以前のぼかしでエッジ抽出が行われていますか?

Teapot

私分布を見ることができる画像を添付。青い点はモデルと交差しない点(遠い面の値に近い光線の長さ)です。赤い点は赤い点です。私は私のテストのためにティーポットモデルを使用しました。

読書を容易にするためにここにコード全体を貼り付けたくありませんでした。何が間違っているかを理解するために、より多くのコードや情報が必要な場合は、私に知らせてください。

答えて

0

以前のぼかしでエッジを抽出していますか?

はい、もっともです。

エッジ検出後処理フィルタの代わりに、エッジ抽出ラスタライズフラグメントシェーダを実装することをお勧めします。実際には単純です。

顔の法線を画面座標(断片ごと)に変換します。 abs(screenspace_normal.z) < thresholdの場合、面は画面に対して垂直なので、エッジになります。エッジでないすべてのフラグメントについては、discardフラグメント。残っているのは、エッジに(近くに)あり、さらに処理できるフラグメントです。

「隠れた」サーフェスのエッジも抽出されることに注意してください。だから、おそらく深さテストに "初期Z"のパスを実行する必要がありますし、深さのバッファに書き込まれず、エッジの断片のみを出力する第2のパスを実行する必要があります。

関連する問題