トップ 差分 一覧 ソース 検索 ヘルプ PDF RSS ログイン

独り言日記(2005/02)

独り言日記

昔の作りかけ(2005/02/28)

昔作っていたパチもんゲー(ただし、ダンジョンを歩けるだけ)がHDDから出てきました。

リアルタイムで影とバンプ処理などしてます。さて、何のゲームをぱくってるか分かるかな?

さて、このようなリアルタイムでノドが渇いたり持ち物制限があったり、ちょっと休んでいると後ろから敵にタコなぐりに合うゲームって、よく考えると今のFPSですね。当時、どきどきして遊んだものです。が、今のFPSではDOOMIII以外興味なかったりします。もっとまったりとしたFPSだといいのですが・・・(反射神経がいるのとかシューティング要素がいるのは苦手ですねぇ)

前処理計算を速くした(2005/02/27)

以下のシーンで、オリジナルレンダラの場合、空間分割(前処理)時間が551msで1秒もかかってないです。

Athlon 1100MHz/Mem 512MBのWin2000マシンにて。全ポリゴン数 197190ポリゴン。

レンダリング全体で34sec(トラバース時のメイルボックスは今は未対応)640x480pixelです。Shade7.5標準レイトレーサでは42secですが、前処理で15secかかってます。このうちどれだけが空間分割処理かはわかりませんが、前処理(空間分割処理)では余裕勝ちですね。

で、去年のレンダラだとこれが17secで終わってますのでまだまだ速くできるはず。また、頂点法線を求めるための計算(スムージング角度による変化を求める)もポリゴン数が増えると負荷がかかりますのでなんとかしたいところです。

と、リファクタリングするといろいろ見えて(目標は過去の自分のソース)すっきりしますね。ちなみに、前処理に関しては以前のレンダラよりも10倍近くは速くなっているかと思います。次はトラバースを詰めねば。

「1:8:1」の法則(2005/02/26)

レンダラを作る際にボトルネックを探ると、主に重くなる部分として「トラバース」「交差判定」「シェーディング」などがあり、だいたいどこに負荷がかかっているか傾向が出てきます。UG/HUGの場合、どのようなシーンでも(これが影処理・反射・屈折などを含む場合、ポリゴン数が多い場合でも)「トラバース:交差判定:その他」の全体に対するウェイトは「1:8:1」に落ち着きます。あくまで私が実験した範囲内なので、トラバース手段や輝度計算のタイプなどによっては変わるかもしれません。でも、いくら反射を繰り返そうが屈折でレイが2手に分かれようがこの割合はあまり揺れませんでした。

では、トラバースと交差判定部分をハードウェア化して仮に「負荷0」になったとしましょう。これを理想値としても、最大は(当社比)10倍速となります(「その他」の1が残る)。これ以上はいくらがんばっても速度アップできません。Saarcorなどはリアルタイムレイトレできてますが、これの違いは「レイシューティングすべてをハードウェア化しているかどうか」が肝のように感じています。実は、このようにしないといけないのは昨今のGPUでも同じで「ハードウェアとソフトウェアのI/O(DMA転送など)がボトルネックになりうるから」でもあります。やるのなら、まとめてばっとハードに投げて結果はスクリーンに反映、でないと純粋なレイトレではリアルタイムには追いつかないのです(HevenSevenみたいな間引きでも使わない限りは)。部分的に、例えば「交差判定」だけハードウェア化してもソフトウェアとハードウェアのやりとり(I/O)部分が見えてしまって逆に速度低下を起こす可能性があります。

また、レイの挙動をカスタマイズできるように(レイトレでもパストレでもフォトンでも自由に「プログラムできるように」)しないと、このあたりは普及は難しいでしょうね。で、この手のレイトレ高速化の手段は「GPUを使用する方法」と「レイシューティングを並列化する方法」に大きく分かれるような気がします。前者はすでに実現可能、後者は・・・実はこれがネットワークを使った分散処理につながるものであるかもしれません(よくあるネットワークレンダリング。これを1マシン上の演算器(と仮に呼びます)に分散させるとするとアクセラレータになる)。後者はハードウェア化するにも規模(コスト含む)が大きすぎて難しい(というよりもラスタライズのほうがはるかに軽いですしね)ということで、なかなか微妙な分野ではありますね。

これが、リアルタイムレイトレがボード化しにくい現状のように思います。Cell関連が話題に上がる昨今、既存マシンでも純粋なレイトレースの並列化はやりやすくなるかもしれません。そうなると、オフラインレンダラとリアルタイムレンダラは時代の流れに任せているといずれは交差するかも、と、そんな動きを見届けたいものですね。

CPUパワーとハード性能(PCIボードなどを使ったアクセラレータ)はいたちごっこですので、このあたりは将来明るいかというとグレイな面が多いのかもしれません。が、夢はありそうです。そもそも、基本概念を覆す使い方をされているのが昨今のGPUですので、レイトレース処理(もしかしたらそれすら考えなくてもいいかもしれないですし)でも何かしら画期的な手法が出てくれば面白いですね。

自分にうち勝つべし(2005/02/25)

数日風邪をひいていたのですが、睡眠パワーで回復。やはり、薬よりも何よりも休息です。インフルエンザかどうかは不明でしたが、寝れば直るもんです(が、風邪ひいたら普通は病院行きましょう(^_^;;。過信は厳禁です・・と私が言っても説得力ないけど)。

さて、ひさびさにレンダラを根底からチェック。レンダリング速度が従来の3倍ほど速くなりました。というよりも元から遅かったのね(^_^;;。しかし、まだ去年作っていたレンダラよりは遅いのです(レンダラ何本作ってるやら・・・いい加減に完成させないと)。

ということで、まずは自分に勝たなくては。用途によってレンダラを作り替えたりはするのですが、目的によっても最適化方法は異なったりします。というわけで、空間分割はBSPから再びUG/HUGへ移行中。手慣れた手法のほうが最適化しやすいっす。HUGって、行き着く先はOctreeと同じですから実装次第でメモリにも優しく効率もよくできると思うのです(これは前処理の時間も含めて)。という訳分からん理由で、ここは我が道を進もうと思います

夢のしずく(2005/02/22)

ドラクエのアイテムか?と思われますが、松たか子さんの曲です。テレビでちらっとかかっていたことがあって「いいなぁ」と思ってましたので(2/20のマンガ喫茶に行ったときの渋谷で)アルバム買ってきました。エンドレスで聴きながらプログラム書いてます。

ちょっと気になったのですが、アーティストや有名人は「さん」付けで書いたほうがいいのか迷いますね(^_^;;。一応、不特定多数が見るのがWebですので「さん」付けか「氏」付けが無難かな。

しかし風邪かな、のどがやばい状態だ・・・・咳も出るし。ということで、しばらく安静状態です(悲しいかなどこでも仕事できるんで、頭がもうろうとしない限り問題なしです)。渋谷混んでましたからねぇ・・・・どっかから移されたかな。

マンガ喫茶に行って来た(2005/02/20)

知り合いとノリでマンガ喫茶に初めて行ってきました。PS2やパソコンもできるんですね。想像していたマンガ喫茶像と違ったのでとまどいました(^_^;;(想像してたマンガ喫茶像:カウンターみたいな横並びの席に座って、前や後ろの棚にあるマンガを取って黙々と読みふける・・・)。実際は個室の狭い部屋で戸を閉めて1人の空間で読む、でした。カラオケボックスを1人用にした空間、って感じでしょうか。

で、「ジョジョを1巻から通して読みたい!」が目標だったんですが1時間でコミック2巻ちょっとしか読めなかったです、読むのが遅い?(^_^;;。ジャンプ全盛期に3部くらいまでは読んでいたのですが見事に内容を忘れているので、それがよかったか悪かったか・・・しかし、確実に元取れてないな・・・読解力を上げなければ。

ということで、以下のRRTエクスポータプラグインはもうちょっとかかりそうです。

Redqueen(2005/02/19)

先日URLを書いたMaxwellの教室みたいな画像はRedqueenで出るんではないか、という気もしてきましたので腕試しがてらチャレンジ。また、軌道から大きく外れてますがこれも息抜きです(^_^;;。とりあえず、rrtファイルの作成はShadeからの自前エクスポータで出してるんですが、この際まともなプラグインの形にしてしまおうと整備中です。(すでにsio29さんの作成されているのがあるのですが、Shade7.5対応とはたしてどれくらいの時間で形にできるか、という自身のリハビリもかねて。いや、差し迫っている締め切りがあるのですがちょっと脇道にそれてみたい、というのが本心です(苦笑))エクスポータは2日もあれば完成できる、かな。これも腕試しです。・・・Shadeエクスポータ機能ではぶっちゃけ標準のコールバックは使えない(使い勝手があまりよろしくない)ので、地道にscene_interfaceから形状をたどるほうが確実ですね。後、ダイアログはやはり独自のパラメータを出したいので・・・(出せるんですが、do_export関数とかでdialog_interfaceを出すとキャンセルでもファイルが生成されてしまうんだわ)と、エクスポータプラグイン部を触ってみてもいろいろモノ申すことが多いっす。

以下、Shade7.5にてRedqueen2.0 Freeでレンダリング。

Shade7.5のパストレはノイズがやはり気になります。Redqueenはさすがにこなれているというか、絵としての完成度が高い気がします。後エクスポータでは、マテリアルと背景のエクスポート部のみ。ShadeとRedqueen双方のパラメータをいじって挙動を確認してみると、いろいろ勉強になりますね。

だれかMaxwellの画像をパストレで再現しようという蒙者はいないものか・・・8割方(根拠はないけど)は再現できるんでないかなぁ。空気感はモデリングとかテクスチャの出来次第と思いますので・・・(Maxwell本家のサンプルもちょっとわかりにくいかも、と思います。後、α版のサンプルをアップしている海外サイトを見ても、見せ方がいいのと悪いのとがありますね)。

いいなぁ、Maxwell・・・(2005/02/18)

http://www.bisand.com/

http://www.bisand.com/maxwell/slides/1.html
http://www.bisand.com/maxwell/slides/2.html

なんかは空気感がツボです。いいっ!!今はα版で395ドル(約4.1万円ちょっと)。悩みどころです・・・(実は仕事場にMAX7があるのですが、、、Maxwellいじってみたい・・・)なんかShadeにも対応するみたいですね、対応に苦労すると思いますが(^_^;;。

こんなのを見ちゃうとフォトンマップを掘るのがむなしくなります(^_^;;。レンダリングとしては、指定時間を決めてその制限時間内でできる部分だけを(プログレッシブのように)計算していくみたいです。粗いのがだんだん鮮明になっていく、みたいな。これだとトライアンドエラーが楽になりそうですね。Maxwellの御本家は以下です。日本語で説明してくれているので、英語の苦手な私も安心です。

http://www.maxwellrender.com/indexjp.html

手元にあるRedqueenいじりたくなってきた・・・ちょっくら遊ぼうっと。

ワイヤーフレームレンダラ(2005/2/18)

どんどん目的から遠ざかっているみたいですが気にしない(^_^;;!!ってことで、今までの内容を生かしてワイヤーフレームレンダラを作ってみました。

また、形が出来次第公開しようかな(Shadeのプラグインです)。

このポリゴン描画+ワイヤーフレーム描画方法だと、ソフトウェアレンダラでもワイヤーフレームが途中で途切れたりしません。またアルゴリズムについては、改めてTipsとして(ソース付きで)公開予定にしてます。もはや、この程度でしたらリアルタイムで(ソフトウェアレンダラでもいいですし、OpenGL/DirectX使ってもいいですし)できそうですね。

ただ、苦労した点として「クリッピング」があります。これによって境界部分の挙動が変わりますので、結局スクリーン全体のレンダリングが必要でした。(実は、上記画像はCarraraやMentalRayみたいにブロック単位でレンダリングしてます。なので、メモリは食わないですが速度は犠牲になってます)

Shade本体のワイヤーフレームレンダラでも、ぜひこの方法でソフトウェアで対応してほしいものです。(そうすると、大きなサイズでも対応できるんで。後、ハードウェアでの挙動不審を回避できるし)

続・ポリゴン描画とワイヤーフレーム(2005/2/16)

ようやく、ポリゴン描画の上にワイヤーフレームを重ねる場合のブチ切れ解消ができました。

過去のもの。線が途切れている部分があります。

改善後。途切れることがなくなりました。ちょっと直線がガタガタな部分があるのはbresenhamアルゴリズムにてテスト用の計算いれているからです。もうちょっとすっきりできると思います。

ワイヤーフレーム描画時に手前に少し浮かしている、ということはしてません。厳密には、浮動小数点のエラーの問題がありますので(AthlonとPentiumでは挙動が微妙に異なります。実は、同じ開始点・終了点を持つラインを同じZ値で描画してもイコールにはならない場合があります)気持ち程度の調整は入れてます。

DirectX/OpenGLを使ってポリゴン描画すると当たり前のことが、ソフトウェアレンダラでは意外と難しい実装になる、というなかなか骨の折れる検証となりました。・・・・思いっきりレンダラからそれていってる内容ですが(^_^;;、これはいろいろ役に立つことでして。例えば自前のモデリングツール(オリジナルの3Dエンジンを使用する場合)を作る場合でもワイヤーフレーム描画が汚くならない、Shade標準のワイヤーフレームレンダラはOpenGLに頼ってますが、これを自前の描画に置き換えるとハードの制限に左右されない(かつ、環境依存する挙動の問題に対処できる)、などなどです。

これにトライしている人ってネット上で見かけませんね・・・。というか、ソフトウェアの3Dエンジン作る人が少ないからかな(^_^;;。理屈としては、直線描画時(ワイヤーフレーム描画時)にポリゴンとして補間しつつエッジだけ描画する、ということになります。こうすると、理論上は同じポリゴン描画の上にポリゴン(といいつつ実はエッジだけ描画)を重ねるのでZ値の微妙な前後関係は確保される(イコールになる)ことになります。

意外と難しいポリゴン描画(2005/2/15)

ポリゴンをソフトウェアで独自描画する場合、よく使われるのが左右の稜線に対し、スキャンライン方向に交わる交点を結ぶ直線を引いていく方法です。

Zバッファで処理する場合はZ情報も持ちます。左右稜線それぞれに対して始点・終点を探し、このうちスキャンラインで交わる点を求めます。(x1, y, z1) - (x2, y, z2)とします。水平方向では、この交点2点を線形補間することで求めていきます。これを垂直方向に最小から最大まで繰り返します。

普通にゲームなどで使う場合はこれで問題ないのですが(つか、ソフトウェアで独自には実装しませんわな)、この上にワイヤーフレームを重ね合わせたい場合、不都合が生じることがあります。線がとぎれたり汚くなったりする問題です。

なぜそうなるのかというと、最終的に2D描画するときのドットの厚みによるものに感じます。

の上面図をスクリーンに描画するとすると、稜線部分を拡大すると以下のようになります。

横方向に4ピクセル分の厚みがあるのがわかりますでしょうか。さて、ではこの4ピクセルのうちで、Z値が大きく変化するとすると「ポリゴン描画(スキャンラインコンバージョン)」とエッジ部分を描画する「直線描画」でZ値がぴったり一致するでしょうか?ポリゴン描画では、稜線はBresenhamを使っても1ピクセルごと地道に計算してもいいです。ただし、ポリゴン・直線の描画は同じアルゴリズム・同じ順番で稜線・直線を追いかけるようにしてください(でないと、誤差が出るのが明白ですしね)。

普通に考えると、ポリゴンのエッジをなぞっているだけなのでZ値が一致すると思うかもしれないですが、これが一致しないのです。ポリゴン描画でスキャンラインごとの描画をする、このときに横方向では「ポリゴンとスキャンラインの交点の開始位置・終了位置」の直線を描きます。Z値もそれで線形補間されます。

直線描画(ワイヤーフレーム部分の描画)を行う場合は、直線の開始位置・終了位置でZが線形補間されます(X方向・Y方向のうち、変化量が大きいほうで分割)。ここで、Z値の矛盾が出てきます。2つめの画像の上面図を見ると、実際は横1ライン描画するにも(直線を構成する同一ライン上の3-4ピクセル間でも)Z値が変化するため、スキャンライン描画と直線描画(斜め)でZ値がずれてしまうのがわかりますでしょうか(う〜む、説明が難しい・・・)。

解決策は、直線描画も(補助線を入れるなりして)ポリゴンと見なして対象となる直線を描画するか、スキャンラインコンバージョンをやめるか、です(バイアスかけて直線を少し手前に出す、はゴミが気になります)。

DirectX/OpenGLによるハードウェア描画ではこの問題も解決されているのですが、複雑そうです。別の方法でポリゴン描画してるみたいだし。

http://spin.s2c.ne.jp/」のArticlesの【第3回 ラスタライズアルゴリズム】参照。

このあたり、乗り越えたい問題ですのでいろいろあさってみることにします。いやはや、単純に見えて奥が深いです。

ポリゴンエッジ部の微妙な誤差(2005/2/13)

ハードウェアにてレンダリング時に陰線消去する場合など、以下のようにきれいに線が出ています(以下、DirectX9のMeshView)。

で、こちらで作ったポリゴンの描画ルーチンだと途中で線が消えたりして汚いわけですが(^_^;;、これはどうもポリゴン描画にてBresenhamの直線描画のアルゴリズムを、ポリゴンの稜線をたどるのに使っているから(整数でエッジ部をたどっている)かなぁと想像しています。

DirectX/OpenGLなどでの陰線消去のやり方は、Zバッファのみをレンダリングし(色は反映しない)、その上に直線をZ値を考慮して描画します。このときZ値が<=の直線のみを描きます。ここでブチ切れ直線にならない、ってことはこのポリゴン描画と直線描画のZ値がぴったりフィットしているから、かな。

ちょっくら私のほうのポリゴン描画ルーチンを見直してみることにします。これ、何に使っているのかというとセレクティブレイトレースで使ってるんです。微妙に汚れが出るんですね(直線描画時にZ値を少し手前に持ってくればいいのですが、奥行きがあるとつらいし)。見直さねば。

あ、でも、これをやるとソフトウェアのリアルタイム3Dエンジンを作りたくなる諸刃の剣・・・。このへんは情報公開しても差し支えありませんので、またTipsとしてまとめることにします。

レンダラをShadeに持っていった(2005/2/11)

ということで、開発中のレンダラをShadeプラグインにしてみました。・・・遅いネッ(T_T)!!。ということで、思ったより重かったようです。アンチエイリアス処理をするまでもなく、トラバースでネックになってました。

で、空間分割としては実はBSPを実験的に取り入れているのですがどうもこれが最適化できてないようで(以前作ったUniformGridのトラバースのほうが速かったです)。「BSPって空間を再帰的に二分してやればいいだけやん」で独自実装したのがまずかったか・・・。ということで、先人の知恵を頼ってみることにします(以前、教えていただいたソースを見てみようかと)。まぁでも、ようやくいろいろなシーンをテストできますのでこのあたりで、プラグイン化するって意味は大きいですね。いろいろバグが見つかりましたし(^_^;;。(Shadeでのプラグインについては、いろいろ問題というか壁があって、それは後々ネタにしていきます)

大垣さんのところのコラムで、アンチエイリアスについて書かれています。これも取り入れてみようかな。

http://www.teamredqueen.com/

ネットでは知識を公開してくださる方も多々おり、感謝感謝です。特に英語の苦手な私としても日本語での解説があると非常に起爆剤になるとともに、英語理解せねばという焦りが募ります(^_^;;。でも、なぜ外国の方のほうが優れたアイデア・論文などが多いんでしょうね。そこに日本がソフトウェアが何歩も遅れている、ってカギがあるのかなぁ。そもそもデキが違うって以外に環境(社会体制)の問題も大きいかも。しかし、日本で活躍しておられる方もちらほら目にしますので盛り上がっていきたいものです。

過去の遺物発掘(2005/2/8)

> 今は無き、工学社の「I/O」

・・未だ健在でした・・・申し訳ないっす。しかし、投稿プログラムってやってるんだろうか・・

過去の遺物発掘(2005/2/8)

私は昔「後10年後にこれを見たら自分自身どう思うだろう」ってことで、記念に作ったモノを残したりしたのですが、あさっていて過去に書いた書物を発見しました。

1993年製のPC-9801用のレイトレーシングプログラムの原稿

日付から見て1995年ごろのキャラクタエディタ仕様書

1つ目のを見て(文書生成ソフトとして)何を使って書いたか分かった方、非常にマニアです。罫線を見ると特徴あるのでピンと来る方もいるかもですが、今争っているジャストシステム社の「一太郎」「花子」のDOS版で書いてました。DOS時代は結構お世話になったので、ぜひ裁判ではジャストシステムにがんばっていただきたいですね(ちなみに、当時はうちの親がジャストユーザだったんで使ってました)。今はATOKだけしか使ってないですが、JustSystemユーザです、私。

1枚目のは、PC-9801の4096色中16色の環境にて、ディザを使ってレイトレースする(コプロを使わない)レイトレーサです。当時は、数値演算コプロセッサをマシンにつけないと浮動小数点演算がものすごく遅いって時代だったんですわ。なんで、ぶっちゃけ固定小数点のほうがはるかに速かったです。で、その解説をしていた原稿っす。今は無き、工学社の「I/O」に乗ったやつです。今は、この手のプログラム雑誌なくなりましたねぇ。GRCGとかQuickC Ver2.0とかが哀愁を誘いますなぁ(QuickC Ver2.0はDOS時代最強のCコンパイラでした。BCCと二分してたけど)。

2枚目のWinG・・・って今は分かる人のほうが少なくなりましたね。DirectX Ver1.0と後付けで言われたものです。今は、Windows APIの「DIBSection」がその名残です。当時、Win3.1/95は使い物にならなくって「これってゲームできるの?」ってそんなレベルでした。画期的でしたねぇ。Windowsの転換期で出てきた目玉APIがWinGでした。ちなみに、これより先にDOS版の「MCE16」ってのを作ってました。1992年くらい?これもI/O関連ですな。

おまけ。チラシの裏に書いたいつの時代のか分からないBASICのプログラム。

たぶん、小学生〜中学生くらいだと思う・・・暗号化って・・・・。

ということで、昔の自虐ネタは(^_^;;なかなか面白いっすね。なんか「無限の心臓」(PCゲーム。IBMのJXでやったと思う)の攻略のためにマッピングしたもの出てきました。・・ってやってること昔から変わらんです(^_^;;。

セレクティブレイトレース(2005/2/7)

とりあえず実装完了。以下、4x4サンプリング/pixelです。

面光源の影が新聞の印刷みたいなノイズになっちゃいましたが・・・。1x1サンプリングで25sec、2x2サンプリングで85sec、そして上の4x4サンプリングで291secです。面光源1つと、球はすべて反射物体です(最大10追跡)。でも、まじめに面光源の計算をしているので、現実的に使えるようにするためにシャドウマップ実装か以前の研究ネタを投与して高速化したいなぁ。

相対的には速度比較できてないので、一度シーンを変えて試していかないといけないですね。

実際は、4x4サンプリングなら(はしょらずに行くと)1x1の約16倍になるのですが、10倍ちょっとに抑えてます。というのは、アンチエイリアス処理で最適化をかましているからですが、アニメーション時にもしかしたらちらつきが目立つかもしれないですね。古い日記にアルゴリズムを書いたことがあったのですが、再帰(1ピクセルを深く再分割し、同じような色ならスキップする)を使わずにはしょる方法を実装してみました。

そろそろ負荷テストもかねてでかい形状で試さねば。ということで、よく研究で使われる形状(ハッピーブッタとかバニーとかドラゴンとか)のファイルフォーマットは「ply」という形式のものがあります。

http://www-graphics.stanford.edu/data/3Dscanrep/

高品質で、しかも2000万ポリゴンを超える形状もありますのでコンバータ作ってレンダリングかけようと思ってます。初心に戻ってレイトレースで実験してますが、SIMD対応ハイパースレッド対応など一通りしたら再びGI参戦(<こう書くと格闘技みたいだ・・・)ですなぁ、時間かかりそうですが一歩一歩やってこうかと。

デジタルな音の仕組み(2005/2/6)

先日からサウンドについてネタにしているのですが、DirectSoundのストリーミング実装、思ったよりも簡単でした。

まずは、基本的な音のデジタル処理の仕組みです。元々、アナログな音はPCで扱えるようなものではなく途切れのない滑らかな波で構成されます。これをPCに取り込むためにアナログ・デジタル変換(A/D変換)が行われます。これの変換方式により、音質が良かったりざらついていたりします。しかし、自然な音以上の質は取り込めず、結局は劣化してしまいます。

CD音質であれば「44.1kHz/16bit/2ch」なんて表現されます。順に、サンプリングレート(サンプル数/秒)/サンプリングサイズ/チャンネル数を表します。

チャンネル数
モノラル・ステレオの表現で使います。モノラルの場合は1、ステレオの場合は2です。この数分だけ、音の波を複数持つことになります。
サンプリングレート
実際は「Hz/sec」という周波数単位で表現されています。samples/secです。1秒間に何回のサンプリングを行うか、というのを表します。44.1kHzの場合は44100回のサンプリングを行います。これが大きいほど、精度が高くなります。
サンプリングサイズ
1サンプルにおける精度を表現するビット数(bits/sample)です。Wave形式では、8ビットと16ビットが一般的です。上記の図では-1.0〜+1.0ですが、これを1バイトまたは2バイトで「振幅」を表現することになります。

上記の図を考えると、「サンプリングサイズ x サンプリングレート x チャンネル数」が1秒間に転送する情報となり、これをbps(bits/sec)で表します。このbpsを「ビットレート」と言います。

CD音質の場合は、「44100 x 16 x 2 = 1411200bps(約1400kbps)」となります。バイトに直すと176400 bytes/secとなります。

さて、DirectSoundの「WAVEFORMATEX」構造体にてこれの情報を設定することになりますが関係としては以下のようになります。

構造体変数名意味
wFormatTagWAVE_FORMAT_PCM
nChannelsチャンネル数
nSamplesPerSecサンプリングレート(Hz/sec)
wBitsPerSampleサンプリングサイズ(bits/sample)
nBlockAlignnCannels * (wBitsPerSample / 8)
nAvgBytesPerSec平均データ転送速度(bytes/sec)。nBlockAlign * nSamplesPerSec

nBlockAlign/nAvgBytesPerSecは、バイト単位で扱っている点に注意です。「nAvgBytesPerSec * 8」がビットレートを表します。

話変わってmp3では 標準で128kbpsのビットレートを持つのですが、CD音質(約1400kbps)よりもはるかに少ないです。逆算してサンプリングレートが4kHz/secくらいで表現できるのか(128kbps / 16bit / 2ch)、と思われるかもしれないですがこれではとてもでないけど音の再生は不可能です。

どうしているのかというと、あらかじめ圧縮した音をリアルタイムで解凍・再生してるんですね。Wave形式はベタですので膨大な量となるわけです。これで、mp3ではサンプリングレートやサンプリングサイズで表現しない訳が理解できます。(128kbpsの転送速度までだいたいで圧縮するようにしている、といった感じでしょうか)

考えてみると、ステレオ(2チャンネル)の場合は似通った部分が多いですので圧縮は効くはず、また時間軸上で見て変化の少ない部分(振幅の少ない部分)は最適化できるはずですので、DirectSoundでのストリーミングでは(ベタWaveっぽいので)圧縮して転送するなどの効率化は必要かもしれませんね。

DirectSound(2005/2/5)

ちょっと新しいことにもチャレンジしよう、ということで新プロジェクトのためにDirectSoundをいじりました。ということで、ひさびさにDirectXを触ってます。DirectXの中の一機能ですが、サウンド周りは昔のDirectXからあまり仕様が変わってないですね。(いかに3D(DirectX Graphics)が重宝されているかが分かります。DirectSoundのサンプルってDX8から変わってないし(^_^;;)

で、DirectSoundの機能としては音を出す(相変わらずWaveの解析は自前で)、ミキシング・エフェクト、そして録音のためのキャプチャに分かれます。

で、私のやりたいのはストリーミングだったりしますが、ずばりに近いサンプル「fullduplexfilter」が有効そうです。これをWinSockでつなぐと あっという間にIP電話ができ、電話代の節約になるわけですねぇ、うんうん。(すでに既存のメッセンジャーとかがあるやん、とも思われる方があるかと思いますが、そこを自前で開発するというのが醍醐味なわけで・・・もちろん、ただ単にIP電話を実現するというのが目標ではないっす)

とはいえ、DirectXはブラックボックス化された部分が多いですので、例えばミキシングなどは自前で行ったほうが効率がいい場合もあるかもしれません(ハードウェアが効いているのなら別ですが、特にストリーミングの場合は送る前に独自圧縮したい場合があります)。

とりあえず、DirectSoundがネットワークのトラフィックなども加味した場合にストリーミングに使えるのか、などなどいろいろ検証してみようと思います。

ちなみに、このためにマイク買いました(昔のSoundBlaster付属のマイクが壊れているようで使えなかったため)。カラオケとか司会にも使えそうなダイナミックマイクです。歌いながら実験するかぁ。リアルタイムストリーミングでボイスチェンジとかできても楽しそうですし。

セレクティブレイトレース その2(2005/2/3)

先日、格段に速くなると豪語したセレクティブレイトレースですが、29秒のが25秒に・・・ってあんまり変わらない・・・(2/2の日記にある平面に反射する球を敷き詰めたやつね)。これは、全体的な反射と面光源(サンプリング数10)を使っていたというのが影響してました。GIだと全体に占める一次レイの走査の割合は少なくなるのでセレクティブレイトレのインパクトは薄いですね。

で、別途面光源を高速化できないかということでいろいろ試してみたのですが、シャドウマップが一番品質と速度共に確保しやすく感じました。しかし、メモリを食うのと広大なシーンではボケボケになりますので別のアルゴリズムを考案中です。理論は固まったのですが画質はまだいまいち。まだ研究の余地ありですが手応えはありそうです。実装すると、25秒のが11秒くらいに短縮できました。

面光源の影のエッジは緩やかになる傾向が強いため、補間が有効なはず。というのを切り口にしてシャドウマップでないノイズのない面光源の影、ぜひ実現したいところです。

セレクティブレイトレース(2005/2/2)

日記でちらっと話題にしていたのですが、改めて実装中ですので記載。セレクティブレイトレースとは、レイトレースするときに一次レイを「はしょる」ことにより高速化を図る手段です。

この一次レイを求めるときに、スキャンラインまたはZバッファで「オブジェクト番号・ポリゴン番号・Z値」によって塗りつぶします(これはラスタライズ的に)。

それを色つきで可視化したもの。

上記は64x64ピクセルのブロックごとに処理しているため、メモリとしては最大64x64ピクセル分を保持するといいことになります(レンダリング画像全体だとさすがにメモリを食いますので)。Zバッファで書いています。

ここのバッファに存在するピクセルは、「そのオブジェクト番号・ポリゴン番号」の組み合わせでのみ交差判定を行えばいいことになり、反射・透過しない物体のレイトレースでは格段に速度アップします(実際、レイトレースしてないわけですし)。2次レイ以降は普通のレイトレースになります。

以下、レイトレースの最終結果と合成してみました。

この手法の場合、込み入ったシーンほど速度アップが見込まれます。これは、CALLISTOとShadeでテストしてみると一目瞭然で違いが分かると思います(複雑になればなるほど。例えば枝が多数分かれている木とか、髪の毛をポリゴンで作ってレイトレレンダリングするとわかりやすいです)。

ただ、GIになるとすべてが反射するようなものですので効果が薄いです。ですが、少しは足しにはなるかなぁ。

問題はアンチエイリアスの処理なんですが、これは基本はオーバーサンプリングで行うといいと思います。アンチ処理ではちょっと複雑にはなりますね。

ちなみに、上記画像は48002ポリゴンのシーンで320x240pixelのセレクティブレイトレースで、このZバッファ描画の前処理は800ms程度(Athlon 1100MHzのWin2000にて)、と負荷は無視できるレベルです。このために、BMPにブロック書き出しするルーチンを作って組み込んでみました。それ込みで(ブロックごとのアフィン変換・ファイル書き出し込みで)800msなんで実用には使えそうですね。(ブロックごとにいちいち計算を発生させるので遅いかと思ったけど大丈夫みたい)

たぶんですが、CarraraとかMentalRayとかって このタイプかなぁと思ってまねてます(^_^;;。

Future's Laboratory 技術格納庫 2004-2013 Yutaka Yoshisaka.