OpenGLでオブジェクトを曲げるにはどうすればよいですか?


11

OpenGLを使用して円柱や平面などのオブジェクトを曲げることができる方法はありますか?

私はOpenGL初心者(OpenGL ES 2.0を使用しています。問題があったとしても、この場合は数学が最も重要であるため、どういうわけかバージョンに依存しません)、変換、回転、行列変換などの基本を理解しています。 。オブジェクトのジオメトリを実際に変更できる(この場合はオブジェクトを曲げて)ことができるテクニックがあるかどうか疑問に思っていましたか?

リンク、チュートリアル、その他の参考資料を歓迎します!

回答:


11

オブジェクトを「曲げる」ために必要なことは、問題のオブジェクトの頂点の一部のサブセットのみに、移動/回転/スケーリングの適切な組み合わせを適用することです。おそらく、それに応じて変換に重みを付けます。

これを行うには、見栄えの良い方法で、元のメッシュを記述するために厳密に必要な場合よりも多くの頂点を使用する必要があります。たとえば、単純な円柱の両端には頂点しかありませんが、その円柱を中央で曲げたい場合は、そこにも頂点が必要です。

あなたが興味を持っているのが非常に特定の、非常に単純な形状(前述の平面のような)の1回限りの変形である場合、おそらく手動でこれを行うことができます。たとえば、平面の「ベンド軸」を決定し、平面頂点の各行の適切な変換を計算して、そのベンド軸からの距離に応じてそのベンド軸を中心に適切な回転を実現し、それをジオメトリに適用します(おそらくCPUは、少なくとも最初は最も簡単です。しかし、そのような手法はうまく拡張できず、非常に退屈なものになります。

目的の変形を達成するためにセット内の個々の頂点への変換に重みを付ける方法を正確に把握するのは非常に面倒な場合があるため(特に、より実用的で複雑なオブジェクトの場合)、多くのゲームは骨格アニメーションと呼ばれる手法を使用します。大まかに言うと、これには、別個のジオメトリセット(「スケルトン」)をメッシュに関連付けることが含まれます。そのジオメトリはオブジェクトのボーンを表し、実際のモデルの頂点とスケルトンのボーン間のマッピングを定義します(多くの場合、モデリングツールで)-どのボーンが各頂点に関連付けられているか、およびそのボーンが変形にどの程度影響するかその頂点の。次に、スケルトンが直接アニメーション化され、アニメーションがボーンとそれらの頂点の間の関係を介して実際のモデルに転送されます。

通常、この手法では、スケルトンと実際のメッシュ間のマッピングはアセットの作成時に定義されます。その後、アニメーションを作成することも、実行時に手続き的に作成することもできます。実際のメッシュへのアニメーション変換の適用は、実行時に行われます。通常、実行時に新しい頂点は生成されません。つまり、見栄えのする変形の範囲は、メッシュが最初に作成されたときに暗黙的にメッシュで固定されます。

理論的には、アニメーションの変換の分析に基づいて、実行時にメッシュにテッセレーションとサブディビジョンを適用し、適切な頂点を生成して、必ずしも計画されていなかったアニメーションを作成することもできます。私はこの問題に関する論文を気づいていないのですが。

こちらもご覧ください:


9

実際のワーピングの計算では、これは非常に複雑になる可能性があります。ここから始めてみませんか?

これを適用する方法について説明します。変形をどのように行うかについての数学がすでにわかっていると仮定します。

2つの方法:

1)すべてのフレームで、シリンダーモデルのすべての頂点にアクセスし、何らかの方法でオフセットします。

2)レンダリングするときに、頂点シェーダーで頂点をオフセットします。OpenGL ES 2.0は頂点シェーダーをサポートしています。ある意味であなたは運がいいです。

画面に表示されたオブジェクトのみをワープしますか、それともオブジェクトをワープして、ゲーム内のすべてのオブジェクトが変形したことを認識しますか?

あなたが頂点シェーダでオブジェクトをワープした場合、その前の表示/ラスタライズにのみ、すぐに起こるので、この手段のゲームオブジェクトのどれも変形について知っているんだろう。単にスクリーンセーバーを作成している場合、または変形が小さすぎてオブジェクトの衝突可能な形状に影響を与えない場合は、これで問題ありません。

頂点シェーダーで ジオメトリをワープすると、モデルの元の頂点は実際に移動しません(それら移動しているように見えます)。

頂点シェーダーの変形

変形していない:

変形していない

変形した

変形した

これは、cgチュートリアルの第6章からのものです(プログラム#14)。

この変形を生成するシェーダーコードは次のようなものです。

// choose a displacement amount
float displacement = scaleFactor * 0.5 * sin(position.y * frequency * time) + 1 ;

// displace it in the direction of the normal
float4 displacementDirection = float4(normal.x, normal.y, normal.z, 0) ;

// move the vertex
float4 newPosition = position + displacement * displacementDirection ;

// transform (as normal)
oPosition = mul(modelViewProj, newPosition) ;

ご覧のとおり、これは表示の直前に発生します(頂点シェーダーはGPUで発生します)。したがって、CPUコードは、変換された頂点の位置にアクセスする方法がありません(GPUからCPUにデータを送信する方法があります(主にテクスチャを介して))。そこには行きません)。


8

あなたが達成しようとしていることは、基本的にメッシュ変形のトピックのサブセットです。しかし、あなたは初心者なので、この種の情報は今のところ少し奇妙すぎるかもしれません。ただし、基本的な概念を説明します。

これを行うには、次の2つが必要です。

  1. メッシュには、変換するのに十分な頂点が必要です。たとえば、それが平面である場合、変形するための多くの頂点を持つ、一種のグリッドとして実際に作成されていることを確認する必要があります。シリンダーも同じです。実行時にテッセレーションを使用してこれを実現することは可能かもしれませんが、私は主題についてあまり知りません。
  2. 頂点を変形するには、頂点シェーダーを使用する必要があります。基本的に、頂点シェーダーが各頂点の最終的な変換位置を計算するので、任意の変形を適用できます。

どれほど役立つかはわかりませんが、このOpenGLリソースを見てください。必要なものとしては適切だと思われます。

http://www.ozone3d.net/tutorials/mesh_deformer_p3.php#part_3

そのリンクからのスクリーンショット:

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

編集

ジョシュの返答を見ただけで、私は同意します。骨格アニメーションもこの問題をカプセル化する非常にエレガントな方法です。特に、変形がより複雑になり、数学的に表現することが困難になる場合に特にそうです。

ただし、上記の2つの点は依然として当てはまりますが、変形できるのは頂点のみです。そのため、明らかに頂点が最初に存在する必要があるため、メッシュには適切な量の頂点密度が必要です。そして通常、骨格アニメーションを駆動し、頂点のブレンドなどを行うのは頂点シェーダーです。

ちなみに、これらはCPUでも実行できますが、今日では通常、GPUで実行する方がより良いオプションです。そのため、私は頂点シェーダーに重点を置いているので、これを調べる必要があります。とにかく、CPUで実行するよりも、プログラム的にはそれほど難しいことではありません。

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