Re: 速度バッファを生成する場合のスキニング行列以外の仕様について ( No.1 ) |
- 名前:管理人 日時:2024/05/29 02:37
> 別途、スキニングなしや広域座標対応など仕様が異なる頂点タイプでは上記URLのスキニング対応のみでは壊れてしまいました。
> (キャラの一部の頂点がずれたり背景モデルなどはすべて原点に配置されているなど)
広域座標対応はまた別ですが、スキニング無しのメッシュはスキニングありのメッシュとは異なる処理を行っているので
スキニング無しのメッシュに対してスキニングありのメッシュ用の処理を行うと正常に処理が行えません
スキニング無しのメッシュは所属するフレームの『ローカル座標をワールド座標に変換する行列』を使用していて、その行列は
MV1GetFrameLocalWorldMatrix で取得することが出来ます
// 指定のフレームのローカル座標からワールド座標に変換する行列を得る
MATRIX MV1GetFrameLocalWorldMatrix( int MHandle, int FrameIndex );
因みに『スキニング無しのメッシュ』は『スキニングありのメッシュ』と異なってトライアングルリスト毎に
使用する行列が異なるといういことはありません、一つのメッシュに含まれるトライアングルリストが全て
同じ行列を使用します
広域座標対応は通常 ローカル座標→ワールド座標、ワールド座標→ビュー座標 と2回に分けている座標変換を
ローカル座標→ビュー座標 と、ローカル座標からビュー座標に一気に変換できるようにワールド行列とビュー行列を
掛け合わせたものを使用するようになっています
|
Re: 速度バッファを生成する場合のスキニング行列以外の仕様について ( No.2 ) |
- 名前:J.Rock 日時:2024/05/29 08:10
情報ありがとうございます。
この場合、背景の各種部品単位でトライアングルリストを個別描画する場合に、それぞれが異なる変換情報をもっているようで
別々に配置情報が必要のようです。
試しに全てのトライアングルリストに同じ行列(FrameIndex)を使用すると背景のすべての部品が一箇所に固まって描画されていまいます。
この場合のFrameIndexは各トライアングルリストでは何番を利用すればよろしいでしょうか?
別々のFrameIndexが必要な場合は
トライアングルリスト番号からFrameIndexを取得する方法があれば実現できそうだと考えています。
TListとFrameIndexを関連付けて参照できる関数か見つからず、困っています。
|
Re: 速度バッファを生成する場合のスキニング行列以外の仕様について ( No.3 ) |
- 名前:J.Rock 日時:2024/05/29 08:28
現状モデルからメッシュ数を取得して下記の関数を経由して描画しています。
MV1GetMeshNum
MV1GetMeshTListNum
MV1GetMeshTList
もしかすると、これをフレーム番号で下記のようにフレーム番号経由でメッシュ参照すれば良いということでしょうか?
一度試してみます。
MV1GetFrameNum
MV1GetFrameMeshNum
MV1GetFrameMesh
MV1GetMeshTList
|
Re: 速度バッファを生成する場合のスキニング行列以外の仕様について ( No.4 ) |
- 名前:J.Rock 日時:2024/05/30 23:04
上記の頂いた情報で、概ね正しく描画することができました。ありがとうございます。
問題が発生していまして、一部のモデルメッシュに9フレーム以上のスキニング DX_MV1_VERTEX_TYPE_NMAP_FREE_FRAME が存在するようで、
その頂点だけが崩れてしまいました。
DXライブラリのソースコードを見る限りでは9フレーム以上の頂点はCPU側でスキニングを計算して頂点バッファ側を更新しているようでした。
これについては1フレーム前の情報をシェーダー内で再現することはDXライブラリでは難しいでしょうか?
|
Re: 速度バッファを生成する場合のスキニング行列以外の仕様について ( No.5 ) |
- 名前:管理人 日時:2024/05/31 03:42
必要な情報が得られたようで何よりです
> これについては1フレーム前の情報をシェーダー内で再現することはDXライブラリでは難しいでしょうか?
それなりに手を加えれば可能かもしれませんが、スキニングメッシュのシェーダーコードの容量が1.5倍に増えてしまうので
今のところ対応する予定はありません
ところで1頂点に9フレーム以上のウェイト値が加わる事はあまりないと思うのですが、現在では頻繁に発生する状況なのでしょうか? (・・;
|
Re: 速度バッファを生成する場合のスキニング行列以外の仕様について ( No.6 ) |
- 名前:J.Rock 日時:2024/05/31 08:23
対応予定について承知しました。
確かにライブラリ内部が複雑になるのは厳しそうですね。。。ありがとうございます。
9フレーム以上のスキニングについてはmixamoのモデルデーターにはいくつか含まれているようでした。
ttps://www.mixamo.com/
こちらの MOUSEY というモデルには含まれていることを確認しています。
ウェイト数が多いモデルは一般的にはあまり多くないとは思います。。
もしかするとコンバーターでウェイトの影響が強い上位8フレームを強制的に8ウェイトとして
正規化&変換出力するモードがあると解決できるのかもしれません。
|
Re: 速度バッファを生成する場合のスキニング行列以外の仕様について ( No.7 ) |
- 名前:J.Rock 日時:2024/05/31 08:24
【追記】
その後非公式ではありますが、強引にスキニングメッシュ頂点をGPU側の出力で得る方式で乗りきってみました
APIがなかったためネイティブにDirectX11のAPIを呼ぶかたちで実装しました
個人的にジオメトリシェーダーStraeamOutは初めて使いましたが…
2パスにはなりますが力業で実現できました。下記が実際の手順です。
----
(1) [D3D11] CreateBuffer() 頂点座標保存用のStreamOutバッファを作成
D3D11_BIND_STREAM_OUTPUT | D3D11_BIND_SHADER_RESOURCE 指定
(2) [D3D11] CreateGeometryShaderWithStreamOutput() で頂点SV_Positionのみを
バッファに出力するStreamOutジオメトリシェーダーを作成
(3) (2)をジオメトリシェーダーをd3d11側で設定 [D3D11] GSSetShader();
(1)をジオメトリシェーダーStreamOutに設定 [D3D11] SOSetTargets()
(4) DxLib::MV1DrawModel() で頂点バッファをStreamOutバッファ出力
(5) 頂点属性を追加するためのジオメトリシェーダーをDxLib::LoadGeometryShader()で作成
(6) ジオメトリシェーダーに1フレーム前の(4) をByteAddressBufferとしてShaderResourceViewに設定
[D3D11] GSSetShaderResources()
(7) 2回目のDxLib::MV1DrawModel() でジオメトリシェーダー(5) で1フレーム前の (4) を参照して
アトリビュートを頂点シェーダー出力に足してピクセルシェーダーへ出力
ピクセルシェーダーで現在のSV_Positionと1フレーム前のSV_Positionを利用
(8) 変更したD3D11スロットをもとに戻す
----
これで今回の9フレーム以上の頂点の場合の他にシェイプなどの変形する頂点にも対応することができました。
DXライブラリの仕様から逸脱する対応部分になりますので非公式にはなりますが
DXライブラリに影響を与えない状態で目的は達成できたと思います。
現在の頂点をバッファに記録して頂点シェーダーに与えるようなAPIがあれば公式に対応できるようになるのかもしれません。
|
Re: 速度バッファを生成する場合のスキニング行列以外の仕様について ( No.8 ) |
- 名前:管理人 日時:2024/06/01 00:38
ご希望の処理が実現できたようで何よりです
> ttps://www.mixamo.com/
> こちらの MOUSEY というモデルには含まれていることを確認しています。
> ウェイト数が多いモデルは一般的にはあまり多くないとは思います。。
ご情報ありがとうございます
現在は4フレーム以内シェーダーと8フレーム以内シェーダーを用意していますが、
何処かのタイミングで 4フレーム以内シェーダーと 12フレーム以内シェーダーに変更してみようと思います (・・;
( 8フレーム以内シェーダーを 12フレーム以内シェーダーに変更するのであればシェーダー容量はあまり増えないので… )
> 現在の頂点をバッファに記録して頂点シェーダーに与えるようなAPIがあれば公式に対応できるようになるのかもしれません。
需要がかなり限定されているので実装の可能性は低いように感じますが、その前に仮に実装するとしたら
どのようなAPIになるのかがちょっと想像できていません
『現在の頂点をバッファに記録して』とは具体的にどのような処理になるのでしょうか?
( 『現在の頂点』とは…? )
|
Re: 速度バッファを生成する場合のスキニング行列以外の仕様について ( No.9 ) |
- 名前:J.Rock 日時:2024/06/04 00:17
検討ありがとうございます。
速度バッファを生成するときには「今のフレームの頂点座標」と「1フレーム前の頂点座標」の
移動差分を求めることになりますが、
そのときに『現在の〜』は前者のことを指していました。わかりにくくて申し訳御座いません。
今のフレームの変換後の頂点バッファを別バッファに出力保存しておき、
次のフレームで利用することで1フレーム前の座標にしています。
本来はそこまでする必要はなく、1フレーム前の行列で座標が再現できれば最も理想ではありました。
今回は9フレーム以上の頂点対応のために、やや強引な解決方法を試してみたという例になります。
シェイプにも対応できるメリットはありました。
|
Re: 速度バッファを生成する場合のスキニング行列以外の仕様について ( No.10 ) |
- 名前:管理人 日時:2024/06/05 00:34
丁寧なご解説ありがとうございます
疑問が晴れてすっきりしました m(_ _)m
|