2011年2月21日

【XNA】CPUSkinningModelサンプルに関するメモ

WP7向けのサンプル、CPUSkinningModelの無駄な処理のお話。 メッシュ操作を自前でやる人は必見?
1
ウィルフレム(Wilfrem) @WilfremLuminous

@Higeneko ところで、MMD杯見てる時にすみませんが、この前教えていただいた、WP7のCPUスキニングモデルのサンプルだと、せっかくのインデックスバッファが解体されているようなのですが、WP7向けの仕様でしょうか?

2011-02-21 17:27:19
ひげねこ@猫 @Higeneko

@WilfremLuminous インデックスバッファの解体ってどういう意味ですか?

2011-02-21 17:29:17
ウィルフレム(Wilfrem) @WilfremLuminous

@Higeneko えーっと、あのサンプルだと、プロセッサでジオメトリごとに頂点データとインデックスバッファを取り出して、ModelPartクラスにいれていますが

2011-02-21 17:30:59
ウィルフレム(Wilfrem) @WilfremLuminous

@Higeneko その時に、同じ頂点が頂点データ内に複数個入り、かつインデックスバッファが[0,1,2,...]と、単純な数列になるようなのですが

2011-02-21 17:34:02
ひげねこ@猫 @Higeneko

@WilfremLuminous もしかしてCpuSkinnedModelPorcessor.cs内のProcessGeometryメソッド内の処理の事ですか?

2011-02-21 17:39:47
ひげねこ@猫 @Higeneko

@WilfremLuminous うーん、特に展開しているようなコードは見受けられませんが、どのコードです?

2011-02-21 17:46:02
ウィルフレム(Wilfrem) @WilfremLuminous

@Higeneko 展開しているというよりも、しちゃってるという状態で

2011-02-21 17:46:49
ひげねこ@猫 @Higeneko

@WilfremLuminous どのコードが教えてもらえませんか?

2011-02-21 17:47:19
ウィルフレム(Wilfrem) @WilfremLuminous

@Higeneko 96行目ぐらいから出てくる、geometry.Vertices.VertexCountですが、実際の頂点数と違い、インデックスバッファの頂点数を出しているようなのです。

2011-02-21 17:50:07
ウィルフレム(Wilfrem) @WilfremLuminous

@Higeneko で、101行目のgeometry.Vertices.Positions[i]はインデックスバッファi番目が指し示す頂点データ、になっていて、geometry.Indicesが最初から0,1,2...になっているようなのです

2011-02-21 17:52:13
ひげねこ@猫 @Higeneko

@WilfremLuminous うーん、これは単にコード量を少なくするためにこうやっているような気がしますね。

2011-02-21 18:04:30
ひげねこ@猫 @Higeneko

Positionsは頂点「位置」の数になり、頂点位置は同じでもUV値が違ったりする場合があるので、その場合はVerticesの数はPositionsより多くなるので、重複を考慮したコードを書く必要がありますね。

2011-02-21 18:05:37
ひげねこ@猫 @Higeneko

恐らく、テストした段階でGPUより速くなったので良しとしたのでしょう。

2011-02-21 18:06:16
ウィルフレム(Wilfrem) @WilfremLuminous

@Higeneko なるほど。MMDモデルを読ませてみたら頂点数が変に多いなぁと(9000→3-4万)と思ってたので……。

2011-02-21 18:07:46
ウィルフレム(Wilfrem) @WilfremLuminous

@Higeneko IndexBufferを活用して頂点数を減らせば、サンプルもっと早くなりますよね。

2011-02-21 18:10:01
ウィルフレム(Wilfrem) @WilfremLuminous

@Higeneko WP7持ってないので実験できないのですが><

2011-02-21 18:10:48
ひげねこ@猫 @Higeneko

@WilfremLuminous っていうか、メッシュを生成した後にMeshHelper.DupulicateVerticesメソッドを呼ぶだけで済むと思いますよ。これのメソッドは件のような処理をした後などに有効ですよ

2011-02-21 18:11:07
ひげねこ@猫 @Higeneko

@WilfremLuminous 間違えたMeshHelper.MergeDuplicateVerticesでした( http://bit.ly/fP6MYx )

2011-02-21 18:12:24
ウィルフレム(Wilfrem) @WilfremLuminous

@Higeneko あ、これ、GeometoryContentも対象に出来るんですね。てことはProcessGeometoryの最初に呼べばいいのか。

2011-02-21 18:14:28
ひげねこ@猫 @Higeneko

ああ、このサンプルは間違ってMeshHelper.OptimizeForCacheの方を呼んでますね(これはModelProcessor内で呼ばれるので呼ぶ必要はない)

2011-02-21 18:15:33
ひげねこ@猫 @Higeneko

MergeDuplicateVerticesは自前でメッシュ操作する場合には必須のメソッドですね(メタセコパイプラインでも使ってます)、これと似たようなので頂点位置が近いものをマージするMergeDupulicatePositionsメソッドもあります。

2011-02-21 18:21:17
ひげねこ@猫 @Higeneko

MergeDuplicatePositions -> MergeDuplicateVerticesの順に呼ぶと良いでしょう。

2011-02-21 18:22:04

コメント

コメントがまだありません。感想を最初に伝えてみませんか?