近くのクリッププレーンよりも目に近いクリッピング頂点をどのように処理すればよいですか?


13

JavaScriptで独自の3Dエンジンを展開し、キャンバス描画のみを使用し、WebGLは使用していません。これは別のMinecraftクローンです。私は箱が大好きです、私を判断しないでください。

これまでのところ、すべてが素晴らしく機能しますが、1つのことを除いて:3Dでは、いくつかの頂点が近くのクリッピングプレーンの背後に移動すると、画面上の投影が奇妙になります(プレーンをトレースするために使用される他の頂点が前面にあると仮定)。

これらのポイントをクリップしてみましたが、これらの頂点を使用するサーフェスの谷を見ることができます。WebGL / OpenGLでは、グラフィックカードがこれらのポイントを処理し、プレーンが正しくレンダリングされますが、ハードウェアにアクセスできないため、これを自分でコーディングする必要があります。

私はそれをどうすればよいのかよく分かりませんが、現在最後に思いついたのは、プレイヤーの近くのクリッピング平面の後ろにあるポイントの投影を逆にすることです。これは、正面にあるスクリーンにポイントを投影する必要があるため、論理的に思えます頂点の。

私の考えは次のとおりです。

ここに画像の説明を入力してください

以下は、何が起こるかを説明するための画像です。

ここに画像の説明を入力してください

遠くから見ると、青いボックスは完璧にレンダリングされます。

ここに画像の説明を入力してください

頂点のいくつかがプレイヤーのクリッピングプレーンの背後にある場合、逆投影を行いますが、正しく見えません。

focalLength *= -1;
2d.x = x*focalLength/z;
2d.y = y*focalLength/z;

顔の描画に使用されるすべての頂点がプレーヤーの背後にあるため、背後の灰色のボックスは完全に削除されます。

ここに画像の説明を入力してください

これは、ルックアップまたはダウンしたときに起こることです。

私はこの背後にある数学をどうすればいいのかわかりません。誰かがすでに同じ問題に遭遇し、助けてくれることを望んでいます。


1
ポイントが近くのクリッププレーンよりも目に近い場合は、クリップする必要があります。これにより、実際にオブジェクトを「透けて見える」可能性があります。これは典型的な動作です。衝突は通常、その特定の視覚的アーチファクトを防ぎます。クリッピングソリューションの唯一の問題はそれでしたか?

@JoshPetrie:ポイントをクリップする必要があることを理解していますが、そうすると、描画ルーチンが通過しなければならない頂点の1つまたは2つが(2dで)失われ、プレイヤーが見ることができるため、正方形全体が消えますその広場を通して。正方形を描画できるように、キャンバスの(投影上で)「外側」に配置してほしい。十分に明確かどうかはわかりません。
ソレノイド

あなたはしている-私はそれが正常な動作ですし、あなたからのプレーヤーを防止することによって、これを防ぐためにしたいと言ってる取得キューブのいずれかにその近くに。場合あなたが本当にこれをやってみたかったあなたは(おそらく)の三角形をクリップするが、再構築する必要があります。これは、特にテクスチャがある場合はまだ異常に見えます。私が言っていることが意味をなさない場合は、チャットに参加して、本当におしゃべりなコメントスレッドを作成しないようにしてください。

あなたが言っていることは理にかなっています、再構築には時間がかかりすぎるので、それは解決策ではありません。プレイヤーの背後にある2dプレーンにその頂点描画して、lineTo(x,y)関数が呼び出されるようにする方法があればいいのにと思っていました。
ソレノイド

回答:


1

ニアクリッピングプレーンの目的は、それがあるということであるクリッピング面。クリッピングプレーンの外側にある三角形はクリップされます。残された各ピースがクリッピング領域内に収まるように、ピースにカットされます。

必要に応じて、ニアクリップを無視してみてください。実際、OpenGLとD3Dには、ニアプレーンクリッピングを完全にオフにする方法があります(ただし、深度バッファーにはまだ最小ニア値があります)。問題は近いクリップではありません。

問題は、カメラの背後にある頂点あります。

カメラの背後にある三角形をレンダリングすることはできません。透視投影ではありません。このような三角形は、透視投影の背後にある数学の下では意味がありません。さらに、それらは錐台の外側にもあります。

クリッピングの近くでオフにすると、錐台がピラミッドに変わります。ピラミッドがポイントで停止する理由は、ピラミッドの上のポイントがピラミッドの4つの側面すべての背後にあるためです。そのため、カメラの背後にあるポイント(ピラミッドの先端)は、画面の表示領域の上、下、左、右にあります。すべて同時に。

私が言ったように、カメラの後ろにある透視投影下の頂点は意味がありません。

クリッピングを実装する必要があります。クリップ空間(遠近法による分割の)の三角形の頂点がカメラの後ろにあることを検出する必要があります。そうである場合、その三角形をクリップして、カメラの前にある三角形のみを生成する必要があります。

これは単純なプロセスではありません。同種の座標系を完全に理解している場合にのみ意味をなす数学が含まれます。あるいは、三角形の頂点がカメラの後ろにある場合は、三角形をまっすぐに切り取ることができます。


今までは三角形全体をカリングしていましたが、飛行機を透かして見ました(上の写真を参照)。なぜ幾何学的に意味をなさないのかを理解するために写真が本当に必要でした。唯一の解決策は、頂点の1つがクリッピングプレーンの背後にある場合にプレーンとラインの交点を計算し、その交点を使用して前にある頂点からラインをトレースすることです。
ソレノイド

0

三角形の一部がニアプレーンの背後にある場合、ピクセルごとのチェックを実行して、ピクセル位置がクリッピングプレーンの背後にあるかどうかを確認できますか?

ニアプレーンは、他のクリッピングプレーンと同様に扱うことができます。たとえば、クリッピングプレーンは、水面(反射や屈折)のようなものに使用されます。このクリッピングプレーンは、ニアクリッピングプレーンと同じように機能し、ピクセル単位でクリップすると思います。

DirectXを使用してHLSLでクリッピングプレーンを処理する方法は知っていますが、その実装は独自のものである可能性があります。そのための情報を手に入れることができれば、役に立つかもしれません。

さらに、ここに役立つリンクがあります:http : //http.developer.nvidia.com/GPUGems2/gpugems2_chapter42.html


Javascriptのようなインタープリター言語では、ピクセル単位のテストは非常に高価です。
ソレノイド
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.