Unity3Dのポータルを移動するときに2つのカメラをブレンドする方法


18

私が質問する前に、最も明白な解決策は正規化されたビューポート長方形を使用することであることを知っていますが、長方形よりも複雑な形状が必要であり、ビューポート長方形の使用を検討しましたが、そうではないようです私の解決策です。

編集:一部の人々は私の質問に混乱していたので、もう少し詳しく見てみましょう。 ここに画像の説明を入力してください プレイヤーが1つのポータルに移動すると、クローンFPSコントローラーを作成し、他のポータルから移動します。これにより、2台のカメラと、右上に表示されるビューが提供されます。1つのカメラを表示し、ポータルを切り取っているだけです。私が欲しいのに似たものである。このカメラがブレンドして滑らかな移行の錯覚を作成します。私がやりたいのは、下の画像の緑のチェッカー画像から左にあるものをすべて削除し、それを他のカメラに置き換えます。これにより、カメラAのビューの一部がポータルの外に出て、カメラBのビューの一部が他のポータルの外に出て、1つの完全な画像が得られます。ポータル内を移動すると、カットが適切に変更されます。

ポータルシステムを設計してきましたが、プレイヤーがポータル内をスムーズに移動できるようにするなど、すべてがダウンしています。私の主な問題は、Valveのカメラブレンドエフェクトを取得することです。ポータルから頭を突っ込んでいるかのように、2つのカメラがシームレスにブレンドする必要があります。そして、それは単なる長方形ではなく、プレイヤーがポータルを通して見ているものと一致しなければなりません。

現時点での私の最善のリードは、各ポータルの背後に深度マスクシェーダーを投影し、移動しているポータルのカメラを深度のみにすることです。その後、どういうわけか2つのカメラをミックスします。私の主な問題は、これをどのように行うか、2番目のカメラでポータルの外にあるもののみをレンダリングし、残りをデフォルトでカメラ1に設定して全画面投影を行う方法を正確に把握することです。

あなたが私にアイデアを与えることができるか、私が非常に役立つだろう深さマスクシェーダーでこれを行う方法を説明することができれば。私はこれに取り組み続け、突破口を作りながら更新します。


5
「バルブが行うカメラブレンドエフェクト」とは何ですか?ポータルレンダリングでは、1台のカメラで十分であることがわかりました。一人称ゲームでは、プレーヤーに接続され、プレーヤーと一緒にポータルをトラフすると、自動的に新しい場所に変換されます。ポータルエフェクトをレンダリングするために、シーンの変換されたコピーがレンダリングされます。これは2番目のカメラでも実現できますが、これらのカメラをブレンドする必要はありません。
msell

1
視覚効果はすでに完全にダウンしています。私がやろうとしているのは、ポータルを歩くことの効果を得る方法を見つけ出すことです。私はすでにすべてのキャラクターグラフィックとそのようなスムーズな動きを持っているので、私は一人称視点から滑らかに見えるためにそれが必要です。
ティモシーウィリアムズ

1
多くの人が、それが何であるかを理解していれば、あなたがその問題についてあなたを助けたいと思うと確信しています。問題をよりよく説明する必要があります。おそらく、写真を追加するか、何が間違っているかを視覚化するビデオを追加する必要があります。
msell

2
エフェクトのサンプル動画へのリンクを追加できますか?
マイクバクスター

2
1台のカメラ/ FPSコントローラーのみを使用した場合はどうなりますか?カメラがポータル内を移動するとき、新しい場所と向きにカメラを変換できます。ポータルのレンダリングが正しい場合、トランジションはシームレスであり、ブレンドは不要です。
msell 2013

回答:


6

問題を理解する

あなたが説明している問題を私が見ることができるのは、ポータルによって定義された平面と交差するカメラの近い平面の結果です。この交差が発生している間、ポータルのある壁の後ろを見ることができます。

これは 、プレイヤーが水上から水中に移行するときに他のゲームで発生問題にます。カメラが水面のすぐ上にある場合、プレーヤーのビューを難読化するためのポストプロセッシング効果は適用されません(暗くぼやけて青になります)。そのため、ニアプレーンの底が水面下にある場合、プレーヤーは水面下ではっきりと見ることができます。

正しい場合は、投影行列を定義するときにこの平面の位置を変更することで確認できます。カメラの原点からニアプレーンまでの距離が長くなると、問題も大きくなります。

簡単なソリューション

ニアプレーンをカメラに非常に近づけると、この問題はほぼ解消されます。このソリューションは完全なものではありませんが、ほとんどの場合に十分な結果が得られ、効率的です。

完全なソリューション

ニアプレーンをカメラに近づけるだけでは満足できない場合は、「マスク」を作成して、プレーヤーとポータルの視点からシーンをレンダリングすることで生成された画像をブレンドできます。

ポータルを平らな面にのみ適用できると仮定すると、カメラのニアプレーンと、ポータル(またはポータルが置かれている壁)によって定義されたプレーンとの交線を計算できます。この行は、画面を2つの部分に分割します。スクリーンピクセルが行のどちら側にあるかを判断すると、使用するレンダリングイメージ、ポータルイメージまたはプレーヤーカメライメージがわかります。

この問題が発生している場合、カメラビューの錐台はポータル内に完全に収まる必要があるため、交差線は常に画面の端から端まで完全に切断されることに注意してください。

このリンクは、行を見つけるための数学に役立ちます。以下のコードはおおよそ正しいはずです。

交線は、線上の点と線の方向を使用して定義されます。交差方向の下は、ポータルの法線とカメラのビュー方向(平面に近い法線)の外積を使用して計算されます。線上のポイントは、ポータルプレーンに向かって(ポータルの法線に沿って)ニアプレーン上のポイントからレイをキャストし、交差ポイントを見つけることによって与えられます。

Vector3 intersectionDir = Vector3.cross(portalNorm, viewDir);
Ray ray = new Ray(camPos + viewDir * camNearPlaneDist, portalNorm);
Vector3 intersectionPos = ray.intersects(new Plane(portalVert1, portalVert2, portalVert3);

viewDirが単位ベクトルであることを確認してください。portalVert1、2、および3は、ポータルデカールまたはその上にあるサーフェスに使用される4つの頂点のうちの3つです。ポータルが存在するプレーンを定義する方法は他にもありますが、これは最も簡単に入手できる情報であると思います。

これらの2つのベクトルが交差線を定義するようになったら、それぞれビューと投影マトリックスを乗算して、スクリーン空間でそれらを取得します。

その後、ポストプロセスシェーダーを使用してこれらの画像をブレンドできます。現在のピクセルが分割線のどちら側にあるかを判断することにより、各ピクセルで使用する画像を選択します。これは、ピクセル位置(レンダーターゲットテクセルの検索に使用する位置でもある)を取得して実行することで実行されます。

float d = (pixelX - intersectionPos.X) * intersectionDir.Y - (pixelY - intersectionPos.Y) * intersectionDir.X;

辺は、dが0より大きいか小さいかによって与えられます。正確に0であれば、あなたはその線上にいます。

上記の数学の参照については、これを参照してください。

このメソッドは、ポータルの観点からレンダリングする前に使用する深度マスク/ステンシルバッファを作成するときにも使用できます。フルスクリーンクワッドを作成し、そのラインを使用してスライスできます。


近いクリッププレーンは良いアイデアでしたが、私が探しているものとはまったく異なります。しかし、その2番目の部分は興味深いアプローチです。現在、既存のポータルプレーンの背後にあるすべてで深度マスクシェーダーを使用し、既存のカメラのクリアフラグを深度のみに設定しています。これにより、出て行くカメラのポータルの外に出ている部分が画面に描画され、入るカメラが深さのマスクに描かれるので、出て行く各カメラの部分を混合して1つの画像を作成しますそれぞれのポータル。唯一の問題は、私はいくつかのマイナーなクリッピングの問題を取得していますです
ティモシー・ウィリアムズ

プレイヤーが移動する際のわずかな動き。あなたが育てたこのアイデアは非常に有望です。したがって、本質的に私がする必要があるのは、カメラに近い面とポータル面が交差する画面に沿った線を計算することです。次に、シェーダー/スクリプトで、ピクセルが分割線のどちら側にあるかをどのように判断しますか?
ティモシーウィリアムズ

基本的なコードを示すために、回答を少し更新しました。クリッピングプレーンの距離に近いビューを変更して、問題を確認してください。これをできるだけ小さくすることでも十分です。覚えて、それを動作させ、正しく動作させ、そしてすぐに正しく動作させてください。
OriginalDaemon


クリッピングプレーンに近い距離の変更をテストしましたが、問題はわずかに改善されましたが、Mellが投稿した記事で、通り抜けるときの問題は修正されません。それでも、交差線が機能する可能性があると感じているので、試してみます。また、メルが投稿したその記事をもう少し詳しく見ていきます。最終的には、深さマスクが高速であるかどうかに降りてくるだろうか、交差点のこのラインは高速です
ティモシー・ウィリアムズ

3

提案された答えは非常に良いものでしたが、最終的には深度マスクを使用した別の手法を採用することになりました。

何をすることは取るでTHISスクリプトとシェーダを、あなたのシーンでレンダラですべてのオブジェクトにスクリプトを入れて、3020にレンダーキューを設定します(私は後で簡単にこれを行うためのスクリプトを投稿します)。

次に、ポータルの両方の背後に、プレーンのボックスを作成します(すべて内側を向いており、ボックスの最も近くにあるボックスの側面は見えませんが、ボックスの内側にいるときは灰色で表示されます)そのように: ここに画像の説明を入力してください そして、それらを独自の特別なレイヤーに設定し(私の場合は「DepthMask」を選択しました)、その上にシェーダーのあるマテリアルを追加します。 ここに画像の説明を入力してください

次に、メインカメラを取り出し、カリングマスクから特別なレイヤーのチェックを外し(DepthMaskレイヤーのチェックを外しました)、深さを0に設定します。 ここに画像の説明を入力してください

次に、カメラをテレポートしてクローンを作成するときに、他のカメラのクリアフラグを「Depth Only」に設定し、深度を1に設定します。 ここに画像の説明を入力してください

その後、2つのカメラビュー間でシームレスな画面がブレンドされます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.