これは長い答えですが、実際にはdivide-by-camera-zの基本的な前提は非常に単純です。何かが離れているほど、小さく見えます。また、2つの物の間のより短い距離が表示されます。
ポジション(Unityを使用している場合は読む必要はありません!)
まず、正しい視点を使用して位置/ポイントをレンダリングする必要があります。
位置は平面上にあります。右の画像のようなものが必要です...タイルの角をサンプルポイント/位置と見なしてください。
ポイントの変換方法は次のとおりです。
- 座標系は次のとおりです。ポジティブ
z
は画面に出て、x
左から右にy
走って下に走ります。カメラz はワールドzです。これは、完全な3Dエンジンを作成するよりもはるかに簡単なショートカットです。欠点?カメラは向きを変更できません(ただし、位置は変更できます)。
- カメラの初期3D位置を保存します。それを
z
世界の起源から少し(マイナス)戻します。
- 3Dポイントのコレクションをxz平面に格納します(それらを指定します
y=0
)。世界の起源を越え、それらを中心に試してみてくださいx
、(0,0,0)
すなわち、負からn
正へn
。これは、レンダリングの開始時にビューポートの中央に配置するためです。
- 減少点/ピクセルプロットの原点を画面の中心と見なします。
- 1ワールドスペースユニット= 1ピクセルとなるカメラからの距離を決定します。つまり、カメラを1ワールドスペースユニットだけ移動すると、10ユニット離れたオブジェクトは1ピクセルだけシフトします-かなり遠くにあります!この距離を定数として保存し
K
ます。
ここで、すべてのポイントについて、次の式を使用して位置でレンダリングしscreenPosition(x,y) = screenOrigin + (worldPosition(x,y) - cameraPosition(x,y)) / ((worldPosition(z) - cameraPosition(z)) * K)
ます。...ご覧のz
とおり、現在のポイントとカメラ間の距離に基づいてレンダリング位置を決定しています。
ポイントのレンダリングが表示されるまで、カメラのz位置を試してください。しかし、表示されるのは、すべてのポイントが画面の中心線を横切って表示されることです。したがって、それを改善する必要があります。試しK=1
対をK=10
差異を見るために。
これで、カメラを移動して、カメラy
がポイントの平面の上と下にどのように移動するかを確認できます(つまり、カメラを上下に移動すると、ポイントはそれぞれ画面の正中線の下または上にレンダリングされ、遠近法で正しく表示されます) )。
これらは非常に大まかなガイドラインです。実装の詳細はいくつかあります。最初のステップは、何かを表示させ、そこから修正することです。頭に浮かぶのは、カメラが地面を見下ろしているように見えるようにしたい場合は、レンダリングの原点をビューポートの上部に近づける必要があるということです。別の詳細としては、カメラとポイントの間の距離にトリガー比率を含める必要があるかもしれません...を使用するとtan
、より現実的な視点が得られると思います。これについてははっきりと覚えていませんが、パースペクティブが奇妙に見え、それに応じて適応できるかどうかがすぐにわかります。サンプルを書き直さなければ、もっと具体的にすることはできません。
ビルボードごとのワーピングとスケーリング(必須)
ポイントの位置のセットの中で遠近法を見ることができ、自由に位置を追加、削除、または移動できる(キャラクターと同様に)ことができるようになったので、それらの位置をルートとする個々のスプライトにも遠近法を適用する必要があります。
D2では常に、単純な横方向のワープ関数であるように見えました。これは、画面上部のビルボードよりも画面下部のビルボードに多く適用され、正中線から遠ざかるほど多く適用されます。スクリーン。
看板にも垂直方向のスケーリングが適用されている場合があります。木が期待される縮尺に比べて短くなり、画面の下部に近づきます(カメラが木を見下ろしているように見えるようにするために-これを安全に探索するには、トリストラムの木が最善の方法であることがわかりました。日 ;) )。
私がすることは:
- さまざまなポイントでのカメラから地面までの距離に基づいて、基本的なスケーリング関数に取り組みます。したがって、すべてのスキャンラインに同様のスケーリングが適用されます。
- それを行った後で初めて、横方向のワープを確認します。最初に画面を走る正中線からの距離に基づいています。
- 最後に、横方向のワープが画面の距離によってどのように影響を受けるかを調査します(そして、単純なトリガー比率がこの中心にあると感じます)。
遠近法正しいタイリング(Unityを使用している場合は読む必要はありません!)
上記は、正しく配置され、歪んだ「立ち上がる」スプライト(つまり、地面に垂直に座っているキャラクター、木、家などのオブジェクト)を提供することを期待しています。
ただし、地面のタイルを正しくシームレスに変形させる方法も考慮する必要があります。そして、それが特にD2でGPUを必要とする部分であることがわかると思います。GPUが搭載されていないシステムでは、パースペクティブオプションが無効になっていたことを覚えています。これは、GPUがテクスチャサーフェスを取得し、それにパースペクティブ補正を非常に迅速に適用できるためであり、タイル間のグリッチがなく、アプリケーションコードで非アフィン変換を実行することに関する懸念もありません。そして少し高価になる可能性があります:
これに対処するためのいくつかの提案があります。
- (Unity)Unityカメラを使用して、テクスチャのある平らな地面のレンダリングを提供し、画面スペースの位置に基づいて看板の歪みを個別に処理します。
- このロジック(またはすべてのレンダリングロジック)をGPUシェーダーで実行します。
- 地面のタイルはまったく使用しないでください。代わりに、ポイントスプライトを使用して-キャラクター自体と同じように-均一に色付けされた平面(たとえば、緑の芝生)でその平面の詳細を提供して、鈍く見えないようにします。これによりレンダリングのコストが増加しますが、この問題に取り組む最も確実な方法は確かです。