DirectXのビルボードについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
赤鬼

DirectXのビルボードについて

#1

投稿記事 by 赤鬼 » 11年前

DirectXで3D空間に2Dの画像を利用したいと考えて、ビルボード(正射影でのポリゴン)を作る事にしました。
(変換済み頂点とは違って、GPUでの行列演算が使用できるのでCPUの使用を抑えられる、また、一々VRAMにアクセスしなくて済むので)
ですが、その際αやRGB等色の設定はどうしたら効率的でしょうか?

自分がぱっと思いついたのがFVFにDIFFUSEを指定しポリゴンの色値を使いLockして、色情報のみ書き換える方法。
が、これだとどうも動作速度が気になります。(これは期待通りに動きました)

そこで、ライト・マテリアル(実際は法線を用意して無いのでライトは使いません。平面ポリゴンだし、無駄を省こうとおもったので)を使ってみようと思ったのですが、
(ちなみに此方も期待通りに動きました)
シェーダーができればライト系統は要らないと聞きました。
つまり、シェーダーを学習すればライト等をシェーダーに任せることが出来るのでしょうか?
また、出来るのであればシェーダーに指定したほうが効率的なのでしょうか?
(将来もう一寸directXに付いて理解できたらシェーダーをやるつもりなので、お願いします。環境依存しないopenglもやりたいなぁ・・・)

それと、またその他に効率的な方法(速度面、メモリ面で)はあるのでしょうか?


ところで、マテリアル構造体は結構サイズがでかいような・・・画像一個ずつに持たせると大変なことに
sizeof(float)*4*4+sizeof(float)=4*4*4+4=68バイト画像百個で6.8k・・・
ワールド変換行列もそこそこ大きいだろうし、
やはり、メモリ節約のために、DXライブラリだとSetDrawBlend()やSetBrite()で一つのマテリアルを指定してたのかな?(描画であればDraw~系でワールド変換していたのかな?ソース見てませんが、そもそもビルボードなのか?これも出来ればお願いします)。


また、ビルボードで、DXライブラリに合ったDrawModiGraph()と同じような関数を作りたいのですが
そのための行列が思いつきません。(平行移動、回転、スケールはわかりますが、自由変換の行列はさっぱりです(自分が思いつかないだけでしょうか?))
この場合はLockして頂点座標を書き換えたほうが良いのでしょうか?

アバター
lriki
記事: 88
登録日時: 13年前

Re: DirectXのビルボードについて

#2

投稿記事 by lriki » 11年前

この手のGPUの使い方や効率化は「SpriteBatch」でググるといくつかきっかけが見つかると思います。

シェーダーができればライト系統は要らないと聞きました。
つまり、シェーダーを学習すればライト等をシェーダーに任せることが出来るのでしょうか?
「任せる」というのがどういう状態なのかあいまいなのですが・・・
自動的に計算してもらえると考えているのであれば、それは間違いです。
シェーダを使う場合、陰影の計算はすべて自分で書く必要があります。
ビルボードで、DXライブラリに合ったDrawModiGraph()と同じような関数を作りたいのですがそのための行列が思いつきません。
3D空間上の4点を直接指定するのではダメなのですか?

赤鬼

Re: DirectXのビルボードについて

#3

投稿記事 by 赤鬼 » 11年前

梨樹さん、回答有難うございます、このまま底に落ちるのではないかと思いました(笑)
梨樹 さんが書きました:この手のGPUの使い方や効率化は「SpriteBatch」でググるといくつかきっかけが見つかると思います。
有難うございます。
そこで、ggって見たところ XNA Game Studio 2.0てのが出てきました。
見たところXBOXの開発言語っぽいのですが何処から探せばよいのやら。
2Dグラフィックスの概要は読みましたが、めぼしいものは見つかりませんでした。
もう少し漁ってみます。
梨樹 さんが書きました: 「任せる」というのがどういう状態なのかあいまいなのですが・・・
自動的に計算してもらえると考えているのであれば、それは間違いです。
シェーダを使う場合、陰影の計算はすべて自分で書く必要があります。
すみません、言葉が足らなかったみたいで。
シェーダーを書いて指定してやればライトの設定がされるのかと思いまして。
つまり、シェーダーで陰影だけではなくライトの設定とかも出来るのでしょうか?(ライトの設定はdirectX側でやる必要がなくなる?)


梨樹 さんが書きました: 3D空間上の4点を直接指定するのではダメなのですか?
えっと、つまりLockして書き換えで良いんですよね?(ワールド行列を単位にして)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: DirectXのビルボードについて

#4

投稿記事 by softya(ソフト屋) » 11年前

>XNA Game Studio 2.0

それはC#から使えるDirectXのラッパーライブラリ・開発環境で最新は4.0です。
Windows8だと4.5でWihdowsPhone8にも対応ですね。

>つまり、シェーダーで陰影だけではなくライトの設定とかも出来るのでしょうか?(ライトの設定はdirectX側でやる必要がなくなる?)

GPUにはある程度知っていますが、DirectXには詳しくないので見当違いの答えならすいません。
シェーダーでライティング計算は可能ですが、頂点カラーとして情報を持っていても問題はないと思われます。
それともすごく特殊なライティングなのでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

赤鬼

Re: DirectXのビルボードについて

#5

投稿記事 by 赤鬼 » 11年前

softya(ソフト屋) さんが書きました: それはC#から使えるDirectXのラッパーライブラリ・開発環境で最新は4.0です。
Windows8だと4.5でWihdowsPhone8にも対応ですね。
なるほど。
C#は齧った程度なので余りよく分かりませんが(汗)
C++とJAVAは多少は出来るので構文はなんとなく理解できました。
softya(ソフト屋) さんが書きました: GPUにはある程度知っていますが、DirectXには詳しくないので見当違いの答えならすいません。
シェーダーでライティング計算は可能ですが、頂点カラーとして情報を持っていても問題はないと思われます。
それともすごく特殊なライティングなのでしょうか?
なるほど。
特殊なというか、今のゲームの映像が凄いものは全部自作のシェーダーを使っている、またライトの等計算はシェーダーで行われている、と言う記述を見たもので、ライトの設定の方もシェーダーで出来てしまうのかなと思いまして。
早くシェーダー書けるようになりたいです。

余談ですが、HLSLとCg、GLSLだったらどれをやったら良いでしょうか?
調べたところ、DirectXがHLSL、OpenGLがGLSL、両方に互換性があるのがCgとの事でしたが
OpenGLやってみたいとも思うので、Cgの方が良いですかね?
(HLSLのみ特化した事項が等、他の言語等、あるならぜひお願いします)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: DirectXのビルボードについて

#6

投稿記事 by softya(ソフト屋) » 11年前

最新技術で、どのようなことが行われているかは下記サイトが参考になるでしょう。

「GAME-連載-3Dゲームファンのためのグラフィックス講座 バックナンバー」
http://game.watch.impress.co.jp/docs/series/3dcg/
「3Dグラフィックス・マニアックス | コラム | パソコン | マイナビニュース」
http://news.mynavi.jp/column/graphics/index.html

HLSL,GLSL,Cgの違いは良く分かりません。すべてを把握している人はそういないでしょう。
まずHLSLを極めるのが先ではないでしょうか。
ちなみにCgはnVidia専用じゃなかったかと思ったりしますが(INTELやRADEONで動かない可能性)。
何をやるのも趣味なので自由にやってもらっても良いんですが、わざわざ聞かれているのは効率とかを気にしてのことでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

peach

Re: DirectXのビルボードについて

#7

投稿記事 by peach » 11年前

自分はHLSLしか書けない(書けているのか怪しいレベル)のですが、C言語で使えるものはほとんど使えるということが利点に挙げれると思います。

予約語として、class、template、union、throwなどがあがっていることから将来C++のようなプログラムを書けるようになると考えられます。

HLSLの構文ですが基本的にはC言語なのですが、とにかく一つの宣言が長くなってきます。また、変数には3種類あってスカラー型、ベクトル型、行列型の三種類があり、データ型にはbool(ブール型),int(32bit符号あり整数型),uint(32bit符号なし整数型),DirectX9まではhalf(16bit浮動少数定数型)とfloat(32bit浮動少数定数型),DIrectX10からはfloatとdouble(64bit浮動少数定数型)があります。互換のためにDirectX10以降にもhalf型というものは存在するのですが、大きさはfloat型と同じく32bit浮動少数定数型になっています。

また、ユーザー定義の関数以外にも、組み込み関数と呼ばれている、C言語でいう所の標準ライブラリに近いものがあります。

欠点といいますか、個人的にどうにかならないのかなという点ですが、全ての関数がinline関数であるため再起がサポートされていません。

補足としましては、CgもHLSLも開発もしくは開発協力にIntel社が絡んでいるためどちらも構文は似ていると思います。

赤鬼

Re: DirectXのビルボードについて

#8

投稿記事 by 赤鬼 » 11年前

softya(ソフト屋) さんが書きました:最新技術で、どのようなことが行われているかは下記サイトが参考になるでしょう。

「GAME-連載-3Dゲームファンのためのグラフィックス講座 バックナンバー」
http://game.watch.impress.co.jp/docs/series/3dcg/
「3Dグラフィックス・マニアックス | コラム | パソコン | マイナビニュース」
http://news.mynavi.jp/column/graphics/index.html
有難うございます。後でじっくり見させてもらおうと思います。FFとか凄いですよね(笑)
softya(ソフト屋) さんが書きました: HLSL,GLSL,Cgの違いは良く分かりません。すべてを把握している人はそういないでしょう。
まずHLSLを極めるのが先ではないでしょうか。
分かりました。まずはHLSLからはじめようと思います。
でも、いつかはすべて把握できるようになりたいです。
softya(ソフト屋) さんが書きました: ちなみにCgはnVidia専用じゃなかったかと思ったりしますが(INTELやRADEONで動かない可能性)。
ああ、なるほど。言語に対しての互換性ではなく。
ビデオカード互(社の違い)との互換性があまり無いんですね。
softya(ソフト屋) さんが書きました: 何をやるのも趣味なので自由にやってもらっても良いんですが、わざわざ聞かれているのは効率とかを気にしてのことでしょうか?
あ、はい、それもありますが。
知識が共通であれば移植もしやすいのではないかと思ったので、そこのところを詳しく聞きたいなと思いまして。
DirectXGraphics(シェーダー:Cg)→OpenGL(シェーダー:Cg?)のように。
peach さんが書きました: また、ユーザー定義の関数以外にも、組み込み関数と呼ばれている、C言語でいう所の標準ライブラリに近いものがあります。
おお、なるほど。
これはリファレンスを見ながらの勉強になる予感がしますね。
peach さんが書きました: 欠点といいますか、個人的にどうにかならないのかなという点ですが、全ての関数がinline関数であるため再起がサポートされていません。
再帰?ですか。
そうなら、スタックオーバーフローが怖いので基本的に再帰関数は使ってませんので問題ないかと思います。(必要な場合は別ですが、大体は繰り返し処理で出来ますし。Cではソートとか作ったりしましたが、C++にはコンテナありますからソートはアルゴリズム任せです(汗))
もしかして、陰影計算とかに再帰関数って必要なんですかね?
peach さんが書きました: 補足としましては、CgもHLSLも開発もしくは開発協力にIntel社が絡んでいるためどちらも構文は似ていると思います。
なるほど、ではいったんHLSLを学習してからCgを学びたいと思います。

peach

Re: DirectXのビルボードについて

#9

投稿記事 by peach » 11年前

赤鬼 さんが書きました: 再帰?ですか。
そうなら、スタックオーバーフローが怖いので基本的に再帰関数は使ってませんので問題ないかと思います。(必要な場合は別ですが、大体は繰り返し処理で出来ますし。Cではソートとか作ったりしましたが、C++にはコンテナありますからソートはアルゴリズム任せです(汗))
もしかして、陰影計算とかに再帰関数って必要なんですかね?
使う場面は無いに等しいのですが、ときたま文が冗長的になりやすいだけですね

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: DirectXのビルボードについて

#10

投稿記事 by ISLe » 11年前

シェーダーは固定機能に置き換わるものです。
特殊なこともできますが、固定機能にプラスアルファできると考えているならかなり面食らうと思います。
固定機能と同じことをするにも特殊なことをするにも同じ手順が必要になるのではじめは面倒くさいと感じるでしょう。


ところで気になっていることがあるのですが…
赤鬼 さんが書きました:DirectXで3D空間に2Dの画像を利用したいと考えて、ビルボード(正射影でのポリゴン)を作る事にしました。
(変換済み頂点とは違って、GPUでの行列演算が使用できるのでCPUの使用を抑えられる、また、一々VRAMにアクセスしなくて済むので)
ですが、その際αやRGB等色の設定はどうしたら効率的でしょうか?
頂点バッファを書き換えるのに、VRAMにアクセスしなくて済むと思われるのは何故でしょう。

赤鬼

Re: DirectXのビルボードについて

#11

投稿記事 by 赤鬼 » 11年前

ISLeさん有難うございます。
ISLe さんが書きました:シェーダーは固定機能に置き換わるものです。
特殊なこともできますが、固定機能にプラスアルファできると考えているならかなり面食らうと思います。
固定機能と同じことをするにも特殊なことをするにも同じ手順が必要になるのではじめは面倒くさいと感じるでしょう。
なるほど、まずは固定機能と同じものが作れるようになるというのが一番の課題ですね。
ISLe さんが書きました: ところで気になっていることがあるのですが…
頂点バッファを書き換えるのに、VRAMにアクセスしなくて済むと思われるのは何故でしょう。
あーすみません、少し間違ってました。
一々Lockして外部からのアクセス、つまりグラボ内部でのアクセスじゃないので速度が落ちると、書きたかっただけです。すみません。(VRAMへのアクセスが一切無いわけじゃないです、誤解を与えてしまい申し訳ありません)
変換済み頂点ではないので、グラボ内部で行列演算をして変換しているから、変換済みの様なLock使ってバスを通してのアクセスが無い分早い筈だと思ったのですが。

アバター
lriki
記事: 88
登録日時: 13年前

Re: DirectXのビルボードについて

#12

投稿記事 by lriki » 11年前

赤鬼 さんが書きました: 有難うございます。
そこで、ggって見たところ XNA Game Studio 2.0てのが出てきました。
見たところXBOXの開発言語っぽいのですが何処から探せばよいのやら。
2Dグラフィックスの概要は読みましたが、めぼしいものは見つかりませんでした。
もう少し漁ってみます。
ちょっと投げやりでしたね。すみません。
普通に描画をするだけなら頂点バッファをLockしてDrawPrmitiveすればいいのですが、
なぜそれをせずに SpriteBatch (DirectX9 では ID3DXSprite)なんていうものを用意しているのかを考えてほしかったのです。
楽をする…っていうのもありますけど、それよりも描画の効率化の面で。

赤鬼 さんが書きました: すみません、言葉が足らなかったみたいで。
シェーダーを書いて指定してやればライトの設定がされるのかと思いまして。
つまり、シェーダーで陰影だけではなくライトの設定とかも出来るのでしょうか?(ライトの設定はdirectX側でやる必要がなくなる?)
ライトの設定が D3DLIGHT9 構造体や SetLight のことでしたら、それらは基本的に必要なくなります。
(最終的に固定機能と同じものを実装しようとしたら D3DLIGHT9 相当の情報が必要になりますが…)

とりあえず、一番簡単な平行光源のHLSLソースは以下のページが参考になると思います。
http://maverickproj.web.fc2.com/pg08.html
(Lambert1.fx という部分です。これ以外にもいろいろなシェーダを公開していらっしゃるので、興味があれば参考にしてみてください)

赤鬼 さんが書きました: えっと、つまりLockして書き換えで良いんですよね?(ワールド行列を単位にして)
ですね。

ちなみに、Lockの速度が気になるようでしたら頂点バッファを使わずに
DrawPrimitiveUP を使うという手もありますよ。

赤鬼 さんが書きました: 余談ですが、HLSLとCg、GLSLだったらどれをやったら良いでしょうか?
個人的にはHLSLをお勧めします。日本語の解説が多いので。

Cgは一応公式に日本語ドキュメントはありますが、日本語の解説がHLSLと比べて少ないので
HLSLが応用できるレベルになってから触るのがいいと思います。
文法がHLSLと9割以上同じなので、最悪ドキュメント無くてもなんとかなる…かも。
(大抵のHLSLで書かれたシェーダはコンパイルできますが、
実行時に動かないといったものもちらほらあります。MMEのGaussian.fxとか)

GLSLはCgが対応していない環境用でしょうか… 携帯端末とか。
(Cgのサイトで Android という単語をちらっと見たことはありますけど…)

赤鬼

Re: DirectXのビルボードについて

#13

投稿記事 by 赤鬼 » 11年前

梨樹 さんが書きました: ライトの設定が D3DLIGHT9 構造体や SetLight のことでしたら、それらは基本的に必要なくなります。
(最終的に固定機能と同じものを実装しようとしたら D3DLIGHT9 相当の情報が必要になりますが…)
一応使えると聞いたのですが、やっぱり必要なくなるんですね。
もう少し勉強してから深く知りたいと思います。
梨樹 さんが書きました: とりあえず、一番簡単な平行光源のHLSLソースは以下のページが参考になると思います。
http://maverickproj.web.fc2.com/pg08.html
(Lambert1.fx という部分です。これ以外にもいろいろなシェーダを公開していらっしゃるので、興味があれば参考にしてみてください)
おお、シェーダーが無い場合も書いてあって分かりやすくて良さそうです、参考にさせて頂きます。
梨樹 さんが書きました: ちなみに、Lockの速度が気になるようでしたら頂点バッファを使わずに
DrawPrimitiveUP を使うという手もありますよ。
速度を期待するとやはり、DrawPrimitiveUPになってしまいますか。
頂点情報を、頂点バッファに置けない分、やはりどうしても速度の低下は免れませんね。
それでもLockに比べると速いと思いますが。
う、自作のライブラリ書き直しかな・・・・orz
頂点情報をシステムメモリに保持しないで頂点バッファに入れて行列で操作していたので。
いやでも、メモリを多少犠牲にして(頂点バッファは使わず)関数から受け取ったものをPrimitivUPに入れた方が良いのかもしれませんね(とりあえず思考錯誤していきます)。
梨樹 さんが書きました: 個人的にはHLSLをお勧めします。日本語の解説が多いので。

Cgは一応公式に日本語ドキュメントはありますが、日本語の解説がHLSLと比べて少ないので
HLSLが応用できるレベルになってから触るのがいいと思います。
文法がHLSLと9割以上同じなので、最悪ドキュメント無くてもなんとかなる…かも。
(大抵のHLSLで書かれたシェーダはコンパイルできますが、
実行時に動かないといったものもちらほらあります。MMEのGaussian.fxとか)

GLSLはCgが対応していない環境用でしょうか… 携帯端末とか。
(Cgのサイトで Android という単語をちらっと見たことはありますけど…)
なるほど、やはり最初はHLSLですね。
貴重な意見有難うございます!

たくさんの人の意見が聞けてとても参考になりました。
ひとまず、知りたいことは大方把握出来たので解決にさせていただきます。
回答していただいた方々どうも有難うございました!

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: DirectXのビルボードについて

#14

投稿記事 by ISLe » 11年前

赤鬼 さんが書きました:一々Lockして外部からのアクセス、つまりグラボ内部でのアクセスじゃないので速度が落ちると、書きたかっただけです。すみません。(VRAMへのアクセスが一切無いわけじゃないです、誤解を与えてしまい申し訳ありません)
変換済み頂点ではないので、グラボ内部で行列演算をして変換しているから、変換済みの様なLock使ってバスを通してのアクセスが無い分早い筈だと思ったのですが。
一般的に明示的にLockするとグラボからシステムメモリに読み込み、再びグラボに書き戻されるので遅くなる気がします。
バスのアーキテクチャや頂点バッファの管理方法によるので一概には言えませんが。

頻繁に書き換える場合は、システムメモリで書き換えて、グラボ間の転送が一方だけのUP系のほうが速いと思います。
書き換えが発生しない大量の頂点情報を持つ背景モデルなどはあらかじめ転送しておくのが効果的ですが。

さらなる高速化が必要であればDrawPrimitive系APIの呼び出し回数を減らす工夫をしてください。

赤鬼

Re: DirectXのビルボードについて

#15

投稿記事 by 赤鬼 » 11年前

ISLe さんが書きました: 頻繁に書き換える場合は、システムメモリで書き換えて、グラボ間の転送が一方だけのUP系のほうが速いと思います。
書き換えが発生しない大量の頂点情報を持つ背景モデルなどはあらかじめ転送しておくのが効果的ですが。
やはりUP系になってしまいますね。
モデルの頂点情報を書き換えるなんて事は余りしませんが、書き換える必要がある2DはUP系にするべきなんですかね。
ISLe さんが書きました: さらなる高速化が必要であればDrawPrimitive系APIの呼び出し回数を減らす工夫をしてください。
UP系の遅さは承知していましたが。
UP無しのDrawPrimitiveとかの呼び出しも凄く処理を食うんですか?
それだとまた書き直しが。回転やスケール変換等の時にワールド行列を設定してDrawPrimitive呼んでいるので。
うーん、こっちの方が速いと思うんですけどね、数が嵩張るとやはり一括描画の方が早いのでしょうか?
もっと具体的に言うとDrawIndexedPrimitiveUP(DrawPrimitiveUP)にして一括描画の方が良いんでしょうか?
(indexは描画順記憶の為、正射影のZ値を描画順にするって言う手もありますよね。また、描画は縮退三角で勿論LISTじゃありませんよ)
そうなるとコンテナ辺りでの頂点の管理になりそうですね。

でも、同じテクスチャ持ったポリゴンを何百枚も使う2DゲームはSTG位ですよね。
ならば、STGはSTGでSTG用のライブラリを作れば良いですかね。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: DirectXのビルボードについて

#16

投稿記事 by ISLe » 11年前

赤鬼 さんが書きました:モデルの頂点情報を書き換えるなんて事は余りしませんが、書き換える必要がある2DはUP系にするべきなんですかね。
スレのテーマがビルボードなのでUP系のほうが良いのではないかと思いました。


UP系はVRAMにデータ転送するのにLockと同じことをするわけなので、Lockの回数が多くなれば遅いのは当たり前です。
しかし頻繁に頂点バッファを書き換える必要があるのならUP系が特に遅いということにはなりません。

UP系のほうがデータ転送を含むので速度低下が分かりやすく、そのためUP系が遅いという評価に繋がっているのではないかと思います。
しかしデータ転送が必要だからUP系を使うのであって、遅いという評判だからUP系を使わないというのは間違った考え方です。

UP系でもそうじゃなくても呼び出し回数の多さはネックになります。
3Dライブラリで、プリミティブの管理と描画を一対一で行うように設計するのをよく見ます。
分かりやすいですが速度は期待できない設計です。
高速化を目指すなら、描画を分離して、描画マネージャーが描画を一括して最適化してバッチ処理するような設計にする必要があります。

赤鬼 さんが書きました:でも、同じテクスチャ持ったポリゴンを何百枚も使う2DゲームはSTG位ですよね。
ならば、STGはSTGでSTG用のライブラリを作れば良いですかね。
商業ゲームソフトなら、どんなジャンルでも、テクスチャをまとめるのは基本です。
テクスチャの切り替えは速度低下に大きく影響します。
背景、キャラ、情報表示用のビットマップなどにグループを分けてまとめます。
これも描画マネージャーでテクスチャの切り替えが最小となるように最適化する処理を実装しておくと良いです。

赤鬼

Re: DirectXのビルボードについて

#17

投稿記事 by 赤鬼 » 11年前

返信が遅れてしまってすみません。
色々試してみたので。
ISLe さんが書きました: UP系のほうがデータ転送を含むので速度低下が分かりやすく、そのためUP系が遅いという評価に繋がっているのではないかと思います。
しかしデータ転送が必要だからUP系を使うのであって、遅いという評判だからUP系を使わないというのは間違った考え方です。
データ転送もそうですが、一々のポリゴン変換の処理をCPUで行わなければならないこと(その分のCPUの消費、出来ればCPUは描画では無いところで使いたい)、その分のシステムメモリの消費
(画像表示の場合もとのテクスチャのサイズを確保しておく必要がある)
とデメリットが気になって居たので使いたくなかっただけです。
別に評判で選んでるわけではありませんので、全体で見てUPの方が速ければUPの方を使います。
まだまだ、拙い知識で的外れな考えを持っているかも知れませんがそのつど訂正して頂けると嬉しいです。
ISLe さんが書きました: UP系でもそうじゃなくても呼び出し回数の多さはネックになります。
3Dライブラリで、プリミティブの管理と描画を一対一で行うように設計するのをよく見ます。
分かりやすいですが速度は期待できない設計です。
えっと、3Dライブラリで、プリミティブの管理と描画を一対一ってどういうことでなのでしょうか?
モデル(骨無し)一個に描画一個ってことですか?
それともテクスチャ一枚につき一primitiveでしょうか?
よく分かりませんのでもう少し詳しくお願いします。
ISLe さんが書きました: 高速化を目指すなら、描画を分離して、描画マネージャーが描画を一括して最適化してバッチ処理するような設計にする必要があります。
描画処理をバッチ処理ってことは描画形態を分割して一括でってことですかね。
(2D画像の表示の場合  テクスチャを保存してすでに描画するだけの状態からです)
描画情報の受け取り。(頂点情報やdifuse等の情報)

情報を確保。最適化。(もとの、頂点の情報から、描画する際の頂点に変換し、コンテナとかでテクスチャ別に確保しておく、またはテクスチャに関連させておく。やり方は沢山ありそうなので省略)

バックバッファにテクスチャごとに一括描画。(UPなら転送も含まれる。確保された情報をテクスチャごとに書き込む。またその情報を削除する)

表画面に表示

以下ループ

例えばこんな感じでしょうか?

これなら、UP系の方が良さそうですね(保持するのはシステムメモリなので簡単に削除可能)。
UP無しの場合一々回転させるのにワールド行列を指定しなくてはならないので、そのたびにprimitiveを呼ぶ必要がありますし。
そうなると、CPUで回転演算するのとどっちが速いかという話になりますので、
primitiveの回数と回転演算がどちらが早いかで決めるしか無いですね。

そこで、ちょっと調べてみました。
実行環境はcore2 duo E8400 3.0Ghz グラフィックボードはNVIDIA Geforce GT 440です。
PCは自作です。

変換済み頂点の回転(本来行列でやるものをばらして作りました。バッファじゃないので変換済みの方が直感的に操作できる)。
使った三角関数はmath.hのsin、cosです。
2万個の三角ポリゴンの変換処理、primitiveに掛かる時間を1000回分のプロセッサ時間すべて足し、秒に直し、平均を出したものです。
つまり、単位は秒です。

DrawPrimitiveを行列ごとに毎回呼ぶ
1万回、二つのポリゴンを描画させるので。
また、そのつど行列をセットしなおしています

DrawPrimitive
1回0.017129998654127121
2回0.017857000231742859
3回0.019200999289751053

DrawPrimitiveUP60000個の頂点(縮退三角で描画)
(sin,cosはそれぞれ8万回ずつ呼ばれることになります(頂点一個につき2回、また、6個中2個は縮退用の頂点の為コピーできるので、2ポリゴン辺り2*4=8個になります。)

//math.hのcos sin
DrawPrimitiveUP一括
1回目0.017601000145077705
2回目0.018381001427769661
3回目0.016913000494241714

うーん、sin,cosがネックではと思ったのでテイラー展開を利用した、sin cosの近似値を求めるヘルパー関数を自作してみたところ円じゃなくなってしまいました・・・orz(もしかしたらソース間違えてた可能性有り(数学的な意味で)形は丸にちょこっと羽が生えた感じになりました)。
なので、cosにテーブルを用意しそれで三角関数を呼び出すようにしました。

//cosテーブル使用
//my_cos
1回目0.018381001427769661
2回目0.017653999850153923
3回目0.016913000494241714

若干の動作速度の改善が見られました。

うーん、どっちも変わらん。
と、最初は思ったんですよ。
デバッグのままだったんですよ。はい、すみません。
DirectXコントロールパネルでRetail Verisionでビルドをしてみると

//cosテーブル使用
DrawPrimitiveUP一括
1回目0.018381001427769661
2回目0.017653999850153923
3回目0.016913000494241714

あまり変わらず(CPU使ってますからね)。

//PrimitiveUP1万回呼び出す行列適用の方
1回目0.012939000502228737
2回目0.013244999572634697
3回目0.013079000636935234

どうやらこっちのが断然速いという結果になりました(GPUの負荷は大きそうですが、もっと増えればUPの方が速くなるのかな?)。
つまり、sin,cosを呼ぶ方が遥かに遅いわけです(Releaseだとブレークポイントすっ飛ばされるので速度不明。もしかしたら、速いのかもしれません)。

primitive1回の呼び出しの方が速いと分かっている以上、何とかsin,cosを早く出来ないかと考えつつ、primitiveの方を弄っているとどうやらprimitiveよりも行列のセットの方が処理を使うことがわかりました。(自分は行列の演算の方に時間が掛かっていると思っていました。orz)
primitive1万回読ぶのと比較するとprimitiveの2~3倍も時間が掛かっていて、回転は殆ど影響していませんでした。
つまり、セットしなければ良いので自前で行列変換用意すれば良いのではと思い、ためしに作成してみたところ。

1回目0.00000000000000000
2回目1.5999999959603883e-005=0.000015999999959603883

もう調べなくて良さそうですね。
ISleさんの言うとおり、見事に物凄い高速化に成功しました。
しかも全然CPUを使用しませんね、これ。
あとは、テクスチャごとに一括で出来るように書き直せば。
あー、でも一括描画だから、正射影行列のZ値使った方がいいかな。
ISLeさん有難うございます。
ISLe さんが書きました: 商業ゲームソフトなら、どんなジャンルでも、テクスチャをまとめるのは基本です。
テクスチャの切り替えは速度低下に大きく影響します。
背景、キャラ、情報表示用のビットマップなどにグループを分けてまとめます。
これも描画マネージャーでテクスチャの切り替えが最小となるように最適化する処理を実装しておくと良いです。
ううむ、なるほど。
では種類ごとに分けた(キャラや弾等)大きなテクスチャ一つに(ポリゴン別に確保?,そういえばUV変換行列あったような・・・余り深く考えないようにしよう)UVマッピングで指定すると言うのが一般的なわけですか。
この場合不要なポリゴン一部分のテクスチャのみを開放するのが難しいので、開放処理は(使い終わったテクスチャの削除=メモリの有効的な管理)テクスチャ全部になってしまい多少不便になりますが、速度の低下を防ぐ為には仕方が無いことなのでしょう。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: DirectXのビルボードについて

#18

投稿記事 by ISLe » 11年前

赤鬼 さんが書きました:データ転送もそうですが、一々のポリゴン変換の処理をCPUで行わなければならないこと(その分のCPUの消費、出来ればCPUは描画では無いところで使いたい)、その分のシステムメモリの消費
(画像表示の場合もとのテクスチャのサイズを確保しておく必要がある)
とデメリットが気になって居たので使いたくなかっただけです。
別に評判で選んでるわけではありませんので、全体で見てUPの方が速ければUPの方を使います。
まだまだ、拙い知識で的外れな考えを持っているかも知れませんがそのつど訂正して頂けると嬉しいです。
すみません。意味が分かりません。
非UP系は既存の頂点バッファを参照し、UP系はその都度頂点バッファを作成する、という違いしか無いのでは?
赤鬼 さんが書きました:えっと、3Dライブラリで、プリミティブの管理と描画を一対一ってどういうことでなのでしょうか?
モデル(骨無し)一個に描画一個ってことですか?
それともテクスチャ一枚につき一primitiveでしょうか?
よく分かりませんのでもう少し詳しくお願いします。
一般的によく見掛けるのがビルボードならビルボードクラスを作って、ビルボードクラスにビルボード一個描画するメソッドが実装されているという形です。
ポリゴンクラスとかモデルクラスとかでも同じことです。
赤鬼 さんが書きました:描画処理をバッチ処理ってことは描画形態を分割して一括でってことですかね。
(2D画像の表示の場合  テクスチャを保存してすでに描画するだけの状態からです)
例えばパーティクルとか、ポリゴン一個ずつ描かずにまとめて描くということです。
あらかじめ充分大きな頂点バッファを用意して一回のAPI呼び出しで複数のポリゴンを描画します。
この場合は縮退三角ストリップかリストかは速度的にはあまり変わらない気がします。
赤鬼 さんが書きました:UP無しの場合一々回転させるのにワールド行列を指定しなくてはならないので、そのたびにprimitiveを呼ぶ必要がありますし。
そうなると、CPUで回転演算するのとどっちが速いかという話になりますので、
primitiveの回数と回転演算がどちらが早いかで決めるしか無いですね。
UPありとなしで違いがあるというのは意味が分かりません。
変換済み頂点でなければ、常に行列演算されるのでは?
変換処理をCPUでするかGPUでするかという話はしていませんが。
赤鬼 さんが書きました:この場合不要なポリゴン一部分のテクスチャのみを開放するのが難しいので、開放処理は(使い終わったテクスチャの削除=メモリの有効的な管理)テクスチャ全部になってしまい多少不便になりますが、速度の低下を防ぐ為には仕方が無いことなのでしょう。
一部分のテクスチャのみが不要になるという設計自体が良くないと思います。
ゲームの設計段階でシーンの変わり目にまとめて切り替えられるようにしておくと良いと思います。

赤鬼
記事: 58
登録日時: 11年前

Re: DirectXのビルボードについて

#19

投稿記事 by 赤鬼 » 11年前

ISLe さんが書きました: すみません。意味が分かりません。
非UP系は既存の頂点バッファを参照し、UP系はその都度頂点バッファを作成する、という違いしか無いのでは?
すみません、今見てても伝えたい意味に取れないと思いました(日本人なのに日本語下手で本当にすみません)。

バッファなら、最初にローカル座標を決めて、その頂点バッファを参照して、指定した行列を使ってGPUで座標計算をすると思いますが、
(バッファに保存する場合画像の一括描画は難しいと思います、一枚のポリゴンに一つのワールド行列を指定しなくてはならないので)
UPで頂点情報を作成する場合、まずローカルの頂点座標を確保しないといけないと思います。
また、格納するのはメインメモリに格納しますし、一括で描画するので個々にワールド変換行列を扱えない。
その為、回転や拡大縮小させる場合、回転や拡大縮小の際の座標計算の処理をCPUで計算しないといけないと思うのですがどうでしょうか?
(大元のローカル座標はテクスチャ毎にその都度descで作る場合が殆ど?関数を一々呼び出すより、座標を保持していた方が早いと思うのですが)
ISLe さんが書きました: 例えばパーティクルとか、ポリゴン一個ずつ描かずにまとめて描くということです。
あらかじめ充分大きな頂点バッファを用意して一回のAPI呼び出しで複数のポリゴンを描画します。
この場合は縮退三角ストリップかリストかは速度的にはあまり変わらない気がします。
パーティクルシステムはまだ、よく分かりませんが、
つまり、一枚の大きなテクスチャ(グループごとの)に大きな頂点バッファを作成して、それに割り当てると言うことですね。
ISLe さんが書きました: UPありとなしで違いがあるというのは意味が分かりません。
変換済み頂点でなければ、常に行列演算されるのでは?
変換処理をCPUでするかGPUでするかという話はしていませんが。
すみません、行列演算にはUP系ある無しは関係ないですね。(何度もすみません)
両方行列演算できますから。
言いたかった事は、画像のワールド変換をいちいち行列セットしてGPUにやらせるか、
CPUで頂点の座標を変換して、一括描画する方が速いかどうかです。
UPを使った方が良いって言って頂いたのはそういう意味ではないのでしょうか?
(頻繁に書き換わるのでvramのローカル座標を書き換えるのは不便
UPならシステムメモリ上で高速に頂点を書き換えられる、バッファを一々作成するので単体では遅いですが。)
ISLe さんが書きました: 一部分のテクスチャのみが不要になるという設計自体が良くないと思います。
ゲームの設計段階でシーンの変わり目にまとめて切り替えられるようにしておくと良いと思います。
なるほど。設計自体が間違いでしたか。
つまりシーンごとにテクスチャを用意するべきだと、そういうわけですね。
弾描画なら、弾の集合画像。
キャラクターなら、キャラクターのこまアニメーションの集合画像ごとという具合ですか?

それと、シーンの変わり目ってアバウトでよく分からないのですが。
たとえばSTGの場合。
//ここから
キャラクタの集合画像テクスチャに切り替え

一括でキャラクタの描画
//此処までが1シーンと言うことですか?

複数の弾の集合画像テクスチャに切り替え

一括で弾の描画

........

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: DirectXのビルボードについて

#20

投稿記事 by ISLe » 11年前

前にも書きましたが、スレのテーマがビルボードということなので、わたしの提案は特定の状況にのみ通用するということはお断りしておきます。
いわゆる3Dモデルを描画する際には個々に異なる変換行列を指定する必要がありますので。
テクスチャの切り替えは広範な話ですが、頂点バッファをまとめる話は用途が限定的です。
赤鬼 さんが書きました:バッファなら、最初にローカル座標を決めて、その頂点バッファを参照して、指定した行列を使ってGPUで座標計算をすると思いますが、
(バッファに保存する場合画像の一括描画は難しいと思います、一枚のポリゴンに一つのワールド行列を指定しなくてはならないので)
UPで頂点情報を作成する場合、まずローカルの頂点座標を確保しないといけないと思います。
また、格納するのはメインメモリに格納しますし、一括で描画するので個々にワールド変換行列を扱えない。
その為、回転や拡大縮小させる場合、回転や拡大縮小の際の座標計算の処理をCPUで計算しないといけないと思うのですがどうでしょうか?
(大元のローカル座標はテクスチャ毎にその都度descで作る場合が殆ど?関数を一々呼び出すより、座標を保持していた方が早いと思うのですが)
ビルボードはワールド行列をポリゴンごとに指定する必要ないと思いますが。
頂点バッファは、頂点情報構造体の大きさと頂点の数ぴったりにその都度確保する必要なく、あらかじめまとめてメモリ領域を確保しておいて、ポインタで間接参照すれば良いと思います。
ゲーム用途での回転や拡大縮小程度はCPU側でもテーブル参照で軽くできると思います。
赤鬼 さんが書きました:言いたかった事は、画像のワールド変換をいちいち行列セットしてGPUにやらせるか、
CPUで頂点の座標を変換して、一括描画する方が速いかどうかです。
UPを使った方が良いって言って頂いたのはそういう意味ではないのでしょうか?
(頻繁に書き換わるのでvramのローカル座標を書き換えるのは不便
UPならシステムメモリ上で高速に頂点を書き換えられる、バッファを一々作成するので単体では遅いですが。)
ビルボードの話なのでGPUで処理する前提ですが。
データが拡張バスを通る回数を減らす話なので、ワールド行列は関係無いかと。
ワールド行列が共通でないと頂点バッファをまとめられないですが。
データ転送速度については変換済み頂点でも同じことが言えると思います。
スコアの数字ひとつひとつとかAPIを呼び出して描画したらとうぜん遅くなりますから、情報表示の2Dビットマップは全部一回のAPI呼び出しで描画するとか。
赤鬼 さんが書きました:つまりシーンごとにテクスチャを用意するべきだと、そういうわけですね。
弾描画なら、弾の集合画像。
キャラクターなら、キャラクターのこまアニメーションの集合画像ごとという具合ですか?
例えば、ステージ1に敵A,敵B、ステージ2に敵B,敵Cが出てくるとします。
その場合、ステージ1キャラ用テクスチャとステージ2キャラ用テクスチャの両方に敵Bの画像を重複して格納します。
前に書きましたが、1フレームあたり、背景、キャラ、情報表示で3回テクスチャを切り替えるだけで済めば理想的ですね。
格闘ゲームの1プレイヤーキャラと2プレイヤーキャラは別々にするとか開発のしやすさも考慮しながら決めることですが。

アバター
lriki
記事: 88
登録日時: 13年前

Re: DirectXのビルボードについて

#21

投稿記事 by lriki » 11年前

赤鬼 さんが書きました:また、格納するのはメインメモリに格納しますし、一括で描画するので個々にワールド変換行列を扱えない。
その為、回転や拡大縮小させる場合、回転や拡大縮小の際の座標計算の処理をCPUで計算しないといけないと思うのですがどうでしょうか?
固定機能を使う以上、一括で描画するためには個々の頂点の座標変換はCPUで行わなければなりません。
(頂点スキニング用の機能を使えばある程度できますけど・・・)


シェーダを書く場合ですが、シェーダのレジスタ(シェーダプログラム用のグローバル変数のようなもの)に
いくつかの行列を転送することで頂点ごとに別の行列を使った座標変換を行うことはできます。

が、レジスタのサイズは環境に依存する上、最低限保証されているサイズもものすごく小さいです。
(そこそこ古いPCでも動くシェーダモデル2.0で、確かfloat4x4の行列30個くらいが限界 = 一度の DrawPrimitive で描画できる画像は30個くらいまで)

回避するために「頂点ひとつごとに回転・拡大の情報を格納する」とか、
「行列をテクスチャに書き込んでGPU側でピクセルをフェッチ→計算」とか
いろんな裏ワザはありますが、それなりの知識や環境が必要です。

結局のところ「古いのは全部切り捨て!」っていう感じで割り切らない限り、CPU側で計算した方が
いろいろと最適化しやすかったり融通がきいたりします。

「別のスレッドで重い処理してるからどうしてもCPUを空けたい!」という場合はもう少し考えないとですけど。



ちなみにスレのテーマと少しずれますが、弾幕など画像が何枚も重なるような描画が必要な時は

・深度書き込みと震度テストを有効にする
・ビルボードを手前から奥にかけて描画するようにソートして描画

という風にして、実際に描画される「ピクセルの数」を減らす方が、
行列計算云々よりも圧倒的に有効だったりします。

ご参考までに。

赤鬼
記事: 58
登録日時: 11年前

Re: DirectXのビルボードについて

#22

投稿記事 by 赤鬼 » 11年前

貴重なご意見感謝です。

それと、返答が遅れてしまいすみません。
恥ずかしながら虫垂炎で入院していたもので。
ISLe さんが書きました: ビルボードはワールド行列をポリゴンごとに指定する必要ないと思いますが。
頂点バッファは、頂点情報構造体の大きさと頂点の数ぴったりにその都度確保する必要なく、あらかじめまとめてメモリ領域を確保しておいて、ポインタで間接参照すれば良いと思います。
ゲーム用途での回転や拡大縮小程度はCPU側でもテーブル参照で軽くできると思います。
んーと、つまり、
テクスチャ毎にバッファを一つ保持、シーンごとにバッファを作り直すって事ですか?
一番最初に全部のバッファを作るんじゃメモリの大量消費ですし。
例えば樹の配置などが、シーンごとに違う場合
このシーンでは50本
次のシーンでは40本
必要な場合

頂点バッファに50本分確保(回転拡大縮小、平行移動済みの物 最大で50本使用するので50)

シーン終了

頂点バッファ50本の内の40本を書き換え

のような感じですか?
それとも、全部一括で最初に確保するべきですかね?
かなりメモリは食いますが、足りるのであればその方が良いということですか。


梨木さん
やはりCPUでやった方が良いのですね。

色々な方法があるんですね。
シェーダのはよく分かりませんでしたけど(汗)
レジスタの数は2.0で30個までですか、勉強になります。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: DirectXのビルボードについて

#23

投稿記事 by ISLe » 11年前

ですから必要数ぴったりでなくても良いと申し上げました。
メモリの空き容量に応じて適当に確保すれば良いと思いますが。

30本分しか確保できなくても、50は30と20に分けて、40は30と10に分ければ描画できます。

UP系APIを呼び出したあともバッファの内容を維持する必要はありませんから、バッファを多目的に使い回すこともできます。

テクスチャ毎にバッファが必要などとは申しておりません。
テクスチャとバッファは別の話で、同じテクスチャを使うAPI呼び出しをまとめてテクスチャ切り替えを減らすと良いという話です。

赤鬼
記事: 58
登録日時: 11年前

Re: DirectXのビルボードについて

#24

投稿記事 by 赤鬼 » 11年前

ISLe さんが書きました: 30本分しか確保できなくても、50は30と20に分けて、40は30と10に分ければ描画できます。
流石にそれくらいは分かります。
しかし、よく見てみると自分が書いた内容がおかしかったですね。
すみません。
余分に確保して、テーブルを保持しておくって言う話なのに違うごと書いてました、すみません。
ちょっと勘違いして書いていたみたいです。

改めて、これに付いてお尋ねします↓
ISLe さんが書きました: ビルボードはワールド行列をポリゴンごとに指定する必要ないと思いますが。
頂点バッファは、頂点情報構造体の大きさと頂点の数ぴったりにその都度確保する必要なく、あらかじめまとめてメモリ領域を確保しておいて、ポインタで間接参照すれば良いと思います。
ゲーム用途での回転や拡大縮小程度はCPU側でもテーブル参照で軽くできると思います。
テーブル参照で確保しておくと言うのがよく分からないのですが。
回転させたポリゴンテーブルをバッファに保持って事ですか?
UPでの場合は呼び出すたびに構造体を指定してやれば良いのですが、非UP系でバッファを保持する場合、平行移動も当然行列で変換しますよね。
その場合一々移動用の変換行列を設定しなくてはならないので、回転のテーブルを保持するよりも、行列で回転移動もまとめた方が良いと思うのですが。(あと、画像なので矩形となるため、一枚じゃなくて二枚です、すみません。UP系はそもそもワールド変換行列必要ないので単位でスルーします。使っても良いのでしょうが使わなくても出来ますし、行列で変換してると後で見たときこんがらがると思います。)
まさか、平行移動までテーブルで確保なんて事は無いと思いますが。
ISLe さんが書きました: テクスチャ毎にバッファが必要などとは申しておりません。
テクスチャとバッファは別の話で、同じテクスチャを使うAPI呼び出しをまとめてテクスチャ切り替えを減らすと良いという話です。
あれ、そんな事書きましたっけ?
primitiveの呼び出し回数の削減とテクスチャ切り替えのコスト削減の話だったと思ったのですが。
テクスチャの切り替えの回数を減らす   primitive系の回数を減らす
↓                          ↓
結果速度の向上に繋がる
だと思ったのですが。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: DirectXのビルボードについて

#25

投稿記事 by ISLe » 11年前

赤鬼 さんが書きました:テーブル参照で確保しておくと言うのがよく分からないのですが。
テーブル参照は回転や拡大縮小の計算を軽くするという話です。
もし分からなければ無視してください。詳細説明するとたいへん長くなるので。
“三角関数テーブル”とかで検索すると良いかもしれません。

頂点バッファをまとめるには、変換行列が同一でなければなりません。
平行移動を含む変換行列が必要になれば頂点バッファをまとめることはできません。
赤鬼 さんが書きました:あれ、そんな事書きましたっけ?
赤鬼 さんが書きました:んーと、つまり、
テクスチャ毎にバッファを一つ保持、シーンごとにバッファを作り直すって事ですか?
この文章を見てテクスチャとバッファの話を混同していると思いました。

赤鬼
記事: 58
登録日時: 11年前

Re: DirectXのビルボードについて

#26

投稿記事 by 赤鬼 » 11年前

ISLe さんが書きました: テーブル参照は回転や拡大縮小の計算を軽くするという話です。
もし分からなければ無視してください。詳細説明するとたいへん長くなるので。
“三角関数テーブル”とかで検索すると良いかもしれません。
えっと?
前の書き込みで三角関数テーブルを使った場合で計測したと思うんですけど。
しかし、アルゴリズムが駄目だったので修正しました。
変換の際に一々呼んでいたのを修正して
(sin,cos変数を用意すれば2回で出来る、関数呼び出し回数が非常にネックになるので。)
計測してみたところ、行列を自前で変換する場合と大差ありませんでした。
三角関数テーブルを用意してやるのも、行列を変換するのも速度的には同じなようです。
ISLe さんが書きました: 頂点バッファをまとめるには、変換行列が同一でなければなりません。
平行移動を含む変換行列が必要になれば頂点バッファをまとめることはできません。
やはり、梨樹さんの仰ったとおり、まとめる場合は変換行列が同一で無いといけないんですね。
(ワールド変換行列は確かindexなしで8個まで指定出来たと思ったので、重みをつければ8個まではばらばらに指定できそうですけど8個では流石に・・・・
いや、そもそも、行列を設定するのに処理を食われるので)
赤鬼 さんが書きました:あれ、そんな事書きましたっけ?
赤鬼 さんが書きました:んーと、つまり、
テクスチャ毎にバッファを一つ保持、シーンごとにバッファを作り直すって事ですか?
ISLe さんが書きました: この文章を見てテクスチャとバッファの話を混同していると思いました。
えっと、それはテクスチャをUVマッピングする場合での話で
バッファを複数持つと、その分primitiveの呼ぶ回数が増えると思ったので。
だから一つと言いました。別に、テクスチャ一枚だからでは無いです。
要するに余計なバッファ分割はしないって事です。
いろんな状況があるので一概には言えませんが。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: DirectXのビルボードについて

#27

投稿記事 by ISLe » 11年前

赤鬼 さんが書きました:三角関数テーブルを用意してやるのも、行列を変換するのも速度的には同じなようです。
どんなテーブルを使ったのか分からないですが。
ビルボードの回転・拡大縮小のような演出レベルなら精度が低くても構わないと思うので、整数型を使って処理すれば速くできるんじゃないですか?

そろそろビルボードの描画の話とは関係なくなってきてますね。
これ以上はゲームプログラム全般の高速化の話になってしまってキリがないのでは。
赤鬼 さんが書きました:いろんな状況があるので一概には言えませんが。
状況に応じてできることをやるだけの話ですね。

赤鬼
記事: 58
登録日時: 11年前

Re: DirectXのビルボードについて

#28

投稿記事 by 赤鬼 » 11年前

ISLe さんが書きました: どんなテーブルを使ったのか分からないですが。
ビルボードの回転・拡大縮小のような演出レベルなら精度が低くても構わないと思うので、整数型を使って処理すれば速くできるんじゃないですか?
単純に三角関数のテーブルですcosのみの(分割数は1000です。速度に関しては分割数は殆ど関係ありません10000でも1000でも顕著な違いはありませんでした。分岐数は変わりませんから当然ですね。)。
整数型と言うのは回転済みの頂点を確保したテーブルの話ですか?
(一般的に整数型の方が速いって言われてますが基本的に処理系依存ですよね。
PCだと整数型のほうが速いのでしょうか。
更に言うならCPUでの小数点の計算の場合float使わずにdouble使うべきですが、GPUではfloatで計算してますからキャストの負荷が掛かって寧ろ遅くなりそうですね。なんと言うジレンマ)
回転済みの頂点テーブルも使ってみましたが速度的には他の二つより少し速い程度でした。10%位?
小数点のと比較しても大差ありませんでした。実際に計算し終えたものを、ポインタで呼び出すだけですから、大して速度に違いは出ませんよね。
(但し回転のみ、拡大まで入れるとメモリ圧迫が酷いです。)
誤差が大きいので正確ではないですが。一回で約15%前後ずれます。
測るときに常駐は必要なもの以外切ってネットも切断してますけど、一回一回かなりずれます。

この結果なら一回で拡大も縮小もできる行列やsin,cosの方が多少遅くとも、メモリの圧迫も減らせますし、此方の方が良いかと思います。
実際に高速化には関数一つの速度ではなく、呼び出し回数を減らすということにあるみたいですね。(他二つの変換と頂点テーブルでの結果から)
ISLe さんが書きました: そろそろビルボードの描画の話とは関係なくなってきてますね。
これ以上はゲームプログラム全般の高速化の話になってしまってキリがないのでは。
そうですね。
では、此処らで解決とさせて頂きます。
すでに解決済みですが、長引かせてしまい申し訳ありません。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: DirectXのビルボードについて

#29

投稿記事 by ISLe » 11年前

赤鬼 さんが書きました:整数型と言うのは回転済みの頂点を確保したテーブルの話ですか?
浮動小数点数をまったく使わない三角関数の話です。
例えば、わたしがブログで公開しているようなものとか。

わたしと赤鬼さんとは、基本的な部分で、前提から大きく異なっている気がします。
赤鬼 さんが書きました:(一般的に整数型の方が速いって言われてますが基本的に処理系依存ですよね。
PCだと整数型のほうが速いのでしょうか。
更に言うならCPUでの小数点の計算の場合float使わずにdouble使うべきですが、GPUではfloatで計算してますからキャストの負荷が掛かって寧ろ遅くなりそうですね。なんと言うジレンマ)
どこかに浮動小数点数型とのキャストによる変換が入ってしまったら整数型を使うメリットはほとんど失われてしまうでしょう。
『Game Programming Gems』に載っているようなキャストを使わず直接内部表現を書き換える変換(環境依存ですが)を使えばけっして小さくはないキャストのコストを減らすことができます。

浮動小数点数型と整数型のどちらが速いかは知りませんが、どちらか一方だけを使うようにすれば遅くないことは確かです。
配列の添字は整数型しか使えないので、テーブル参照する場合に角度を浮動小数点数型で表現すると必ず速度低下を伴うことになります。

赤鬼
記事: 58
登録日時: 11年前

Re: DirectXのビルボードについて

#30

投稿記事 by 赤鬼 » 11年前

ISLe さんが書きました: 浮動小数点数をまったく使わない三角関数の話です。
例えば、わたしがブログで公開しているようなものとか。
固定少数点ですね。
ただ、整数といわれてもぱっと浮かんで来ませんでした。
経験不足ですね。すみません。
ISLe さんが書きました: わたしと赤鬼さんとは、基本的な部分で、前提から大きく異なっている気がします。
単純に私の知識と経験量の差から来る勘が足りないだけだと思います。
つまり、自分の勉強不足です。申し訳ありません。
ISLe さんが書きました: 『Game Programming Gems』に載っているようなキャストを使わず直接内部表現を書き換える変換(環境依存ですが)を使えばけっして小さくはないキャストのコストを減らすことができます。
それ読んで無いんですよ。
買いたいんですけど高いんですよね。
最初見たとき新品で一冊12600!?
もっとバイトしないとって思いましたから。
5巻で一体いくらになるんだろうと、手が出無いので中古品漁ってます。
ISLe さんが書きました: 配列の添字は整数型しか使えないので、テーブル参照する場合に角度を浮動小数点数型で表現すると必ず速度低下を伴うことになります。
そうですね、少し、考えてみます。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: DirectXのビルボードについて

#31

投稿記事 by ISLe » 11年前

赤鬼 さんが書きました:
ISLe さんが書きました: 浮動小数点数をまったく使わない三角関数の話です。
例えば、わたしがブログで公開しているようなものとか。
固定少数点ですね。
ただ、整数といわれてもぱっと浮かんで来ませんでした。
経験不足ですね。すみません。
角度については純粋な整数にしてますけどね。

赤鬼
記事: 58
登録日時: 11年前

Re: DirectXのビルボードについて

#32

投稿記事 by 赤鬼 » 11年前

そういえば四角の1,2ってクリックできたんですね。
気がつかなかった。
ISLe さんが書きました: 角度については純粋な整数にしてますけどね。
ソースを見させていただきました。
固定小数点を整数型で表すのは作ったことあるんですが、これってそれの応用どころの話じゃないですね。凄い目から鱗なんですが!!
なるほど、共用体を使っての分割ですか、凄いですね。
自分じゃ絶対こんなの思いつきませんよ。

それと、一寸気になったのはfixedmath13.cの
SIN_TABLE_LENGTH ((1<<13)/4)
1<<11
で良いと思うのですが。
同様にfixedmath1312.cも
1<<10
のように出来ますよね。
何でわざわざ4で割ってるんでしょうか?
円の4分の1ということを示唆したいからですか?

そういえばオペレーターやオーバーロードはオブジェクトを生成するため速度が落ちるとどこかに書いてありましたが其処はどうなんでしょうか。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: DirectXのビルボードについて

#33

投稿記事 by ISLe » 11年前

赤鬼 さんが書きました:なるほど、共用体を使っての分割ですか、凄いですね。
自分じゃ絶対こんなの思いつきませんよ。
処理系依存というか環境依存ですけどね。
現実にはいまやこれが動かないCPUを探すほうが困難ですが。
赤鬼 さんが書きました:何でわざわざ4で割ってるんでしょうか?
円の4分の1ということを示唆したいからですか?
そのとおりです。
赤鬼 さんが書きました:そういえばオペレーターやオーバーロードはオブジェクトを生成するため速度が落ちるとどこかに書いてありましたが其処はどうなんでしょうかね。
「オブジェクトを生成」とは一時オブジェクトのことですかね。
一時オブジェクトが生成されるのはそれが必要なときだけだと思いますが。

全部ヘッダで定義しているので基本的にインライン展開されます。
最適化ありでコンパイルすればたいていほとんどただの整数型の演算だけが残ると思います。


整数部と小数部に共用体使ってアクセスするのはふつうのことだと思ってましたけど。
それよりもテーブルにアクセスするときのインデックスを丸めるコードのほうが珍しいし応用範囲が広い(ゲームだとスクロールとかで)と思います。

赤鬼
記事: 58
登録日時: 11年前

Re: DirectXのビルボードについて

#34

投稿記事 by 赤鬼 » 11年前

ISLe さんが書きました: 「オブジェクトを生成」とは一時オブジェクトのことですかね。
一時オブジェクトが生成されるのはそれが必要なときだけだと思いますが。

全部ヘッダで定義しているので基本的にインライン展開されます。
最適化ありでコンパイルすればたいていほとんどただの整数型の演算だけが残ると思います。
一時オブジェクトです。
あー、そうかヘッダでしたね。
インライン展開されれば、無駄なコピー等は殆どなくなりますよね。
ISLe さんが書きました: 整数部と小数部に共用体使ってアクセスするのはふつうのことだと思ってましたけど。
自分は、実装の仕方だけ見て組んだので、普通とはかけ離れていると思います。
(見本コード無かったし、其処まで深く勉強していなかったので)
自分は二つしかとっておらず(整数部と小数部のみ)共用体でのアクセスをしなかったのでその分色々処理に時間が掛かってるので遅いですorz
ISLe さんが書きました: それよりもテーブルにアクセスするときのインデックスを丸めるコードのほうが珍しいし応用範囲が広い(ゲームだとスクロールとかで)と思います。
そうなんですか?
ビット反転を除いて、自分が考えた中にありましたので驚きはしませんでした。
ビット反転のは面白いなぁと思いましたけど。
あのやり方は初めて見ました。

赤鬼
記事: 58
登録日時: 11年前

Re: DirectXのビルボードについて

#35

投稿記事 by 赤鬼 » 11年前

あー、すっかり忘れてた問題がありました!
Zバッファリング有効にするので、一括描画も分割しなくてはなりませんでした。
例えば二つのテクスチャ貼り付けのポリゴンの場合
ポリゴン1のZ値(射影前)
0.0f;(手前)
ポリゴン2
1.0f;(奥)
だとして、テクスチャに透過情報が存在する場合
ポリゴン1を先に描画した場合Zバッファリングによってテクスチャの上下に付いては問題はありませんが
透過情報もちのポリゴンは深度テストを飛ばされるのか、ポリゴン2の透過が上手く反映されません。
つまり
ポリ1(手前)
[ 0 ][0xff]
[0xff][0xff]
ポリ2(奥)
[0xff][0xff]
[0xff][0xff]
透過情報がこのような場合
描画順ではポリ1が先に描画され、ポリ2が後に描画されます。
そして、Zバッファによりポリ2が奥なのでポリ1が手前に来ます。
その場合、ポリ1で透過されるべき場所がぽっかり切り抜かれた情報になってしまいます。
これを回避する場合描画順序を変えなくてはなりませんよね。
1枚のテクスチャではこういう事は起こり得ませんが
2枚以上の場合、ポリ1(テクスチャ1)、ポリ2(テクスチャ2)、ポリ3(テクスチャ1)
テクスチャ1を2枚描画

テクスチャ2を1枚描画
と、なるので一括描画の場合、くり抜きが発生します。
これを防ぐために一括描画を分割してやる必要がありますよね。
テクスチャ1を1枚描画

テクスチャ2を1枚描画

テクスチャ1を1枚描画
しかし、それだったらZバッファを切って描画順を自分でやってしまった方が良いと思うのですが
何か欠点等ありますでしょうか?
また、この場合一括描画の利点が薄まる気がします。

こ、これは、シェーダの深度テストを自分で書けということでしょうか。

アバター
lriki
記事: 88
登録日時: 13年前

Re: DirectXのビルボードについて

#36

投稿記事 by lriki » 11年前

アルファテストするだけでいいような気がしますけどどうでしょう。
(何かテクスチャにフィルタリングかけてる場合は難しいですけど・・・)
赤鬼 さんが書きました:しかし、それだったらZバッファを切って描画順を自分でやってしまった方が良いと思うのですが
何か欠点等ありますでしょうか?
Zバッファを使わないようにすると今度は二つのポリゴンが十字に重なった時に問題がでてきますよ。
赤鬼 さんが書きました:また、この場合一括描画の利点が薄まる気がします。
この辺はもう宿命ですね。
あるところ以上は見栄えを重視するか速度を重視するか、どちらかを選ばないとなりません。
赤鬼 さんが書きました:こ、これは、シェーダの深度テストを自分で書けということでしょうか。
深度テストをシェーダで行うことはできません。
頂点シェーダで描画先の座標が決まった後、プログラマからは見えないところで行われます。



ちなみに、自分もこの問題に悩んだことがありますが、結局見栄え重視で作りました。
考え方の肝は「可能な限り1度の描画にまとめる」ではなく「チャンスがあれば1度にまとめる」っていう感じ。

自分一人でゲーム作るときは素材を作るときに「絵は全部1つのテクスチャにまとめる!」とか気をつかえますけど、
グループで作るときは余計な制約持たせると後で素材管理が面倒になるので・・・。

赤鬼
記事: 58
登録日時: 11年前

Re: DirectXのビルボードについて

#37

投稿記事 by 赤鬼 » 11年前

梨樹 さんが書きました:アルファテストするだけでいいような気がしますけどどうでしょう。
(何かテクスチャにフィルタリングかけてる場合は難しいですけど・・・)
ああ、そうか、すみません、有難うございます。
見直してみたらD3DCMP_NOTEQUALじゃなくてD3DCMP_GREATER使ってました。
そういえば、フィルタリング掛けるとまずいことがあるんでしょうか?
あまり、凄いの使ったこと無いので分かりません。
シャギを消すミップマップのフィルタリングくらいしかないので。
梨樹 さんが書きました: Zバッファを使わないようにすると今度は二つのポリゴンが十字に重なった時に問題がでてきますよ。
あ、そうか、メッシュとか共存できませんね。
斜めのが刺さらず、浮いて見える!不思議!ってなりますね。
梨樹 さんが書きました: 深度テストをシェーダで行うことはできません。
頂点シェーダで描画先の座標が決まった後、プログラマからは見えないところで行われます。
そうなんですか!有難うございます。
シェーダに付いても、赤ん坊レベルなので。
梨樹 さんが書きました: ちなみに、自分もこの問題に悩んだことがありますが、結局見栄え重視で作りました。
考え方の肝は「可能な限り1度の描画にまとめる」ではなく「チャンスがあれば1度にまとめる」っていう感じ。

自分一人でゲーム作るときは素材を作るときに「絵は全部1つのテクスチャにまとめる!」とか気をつかえますけど、
グループで作るときは余計な制約持たせると後で素材管理が面倒になるので・・・。
なるほど、チャンスがあればですね。

追記。
フィルタは分かりませんが、アルファブレンディングも忘れてました。
アルファあるなしで条件分岐。
うーん、一括描画がますます難しく・・・・。
高速化からは程遠くなっていく。

閉鎖

“C言語何でも質問掲示板” へ戻る