独り言日記

独り言日記
昔の作りかけ(2005/02/28)
昔作っていたパチもんゲー(ただし、ダンジョンを歩けるだけ)が HDD から出てきました。
リアルタイムで影とバンプ処理などしてます。さて、何のゲームをぱくってるか分かるかな?
さて、このようなリアルタイムでノドが渇いたり持ち物制限があったり、ちょっと休んでいると
後ろから敵にタコなぐりに合うゲームって、よく考えると今の FPS ですね。当時、どきどきして
遊んだものです。が、今の FPS では DOOMIII 以外興味なかったりします。もっとまったりとした
FPS だといいのですが・・・
(反射神経がいるのとかシューティング要素がいるのは苦手ですねぇ)
前処理計算を速くした(2005/02/27)
以下のシーンで、オリジナルレンダラの場合、空間分割(前処理)時間が 551ms で1秒もかかっ
てないです。
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 でも同じで「ハードウェアとソ
2
フトウェアの I/O(DMA 転送など)がボトルネックになりうるから」でもあります。やるのなら、
まとめてばっとハードに投げて結果はスクリーンに反映、でないと純粋なレイトレではリアルタ
イムには追いつかないのです(HevenSeven みたいな間引きでも使わない限りは)。部分的に、例え
ば「交差判定」だけハードウェア化してもソフトウェアとハードウェアのやりとり(I/O)部分が
見えてしまって逆に速度低下を起こす可能性があります。
また、レイの挙動をカスタマイズできるように(レイトレでもパストレでもフォトンでも自由に
「プログラムできるように」)しないと、このあたりは普及は難しいでしょうね。で、この手のレ
イトレ高速化の手段は「GPU を使用する方法」と「レイシューティングを並列化する方法」に大
きく分かれるような気がします。前者はすでに実現可能、後者は・・・実はこれがネットワーク
を使った分散処理につながるものであるかもしれません(よくあるネットワークレンダリング。
これを1マシン上の演算器(と仮に呼びます)に分散させるとするとアクセラレータになる)。後
者はハードウェア化するにも規模(コスト含む)が大きすぎて難しい(というよりもラスタライ
ズのほうがはるかに軽いですしね)ということで、なかなか微妙な分野ではありますね。
これが、リアルタイムレイトレがボード化しにくい現状のように思います。Cell 関連が話題に上
がる昨今、既存マシンでも純粋なレイトレースの並列化はやりやすくなるかもしれません。そう
なると、オフラインレンダラとリアルタイムレンダラは時代の流れに任せているといずれは交差
するかも、と、そんな動きを見届けたいものですね。
CPU パワーとハード性能(PCI ボードなどを使ったアクセラレータ)はいたちごっこですので、こ
のあたりは将来明るいかというとグレイな面が多いのかもしれません。が、夢はありそうです。
そもそも、基本概念を覆す使い方をされているのが昨今の GPU ですので、レイトレース処理(も
しかしたらそれすら考えなくてもいいかもしれないですし)でも何かしら画期的な手法が出てく
れば面白いですね。
自分にうち勝つべし(2005/02/25)
数日風邪をひいていたのですが、睡眠パワーで回復。やはり、薬よりも何よりも休息です。イン
フルエンザかどうかは不明でしたが、寝れば直るもんです(が、風邪ひいたら普通は病院行きま
しょう (^_^;;。過信は厳禁です・・と私が言っても説得力ないけど)。
さて、ひさびさにレンダラを根底からチェック。レンダリング速度が従来の 3 倍ほど速くなりま
した。というよりも元から遅かったのね (^_^;;。しかし、まだ去年作っていたレンダラよりは遅い
のです(レンダラ何本作ってるやら・・・いい加減に完成させないと)。
ということで、まずは自分に勝たなくては。用途によってレンダラを作り替えたりはするのです
が、目的によっても最適化方法は異なったりします。というわけで、空間分割は BSP から再び
UG/HUG へ移行中。手慣れた手法のほうが最適化しやすいっす。HUGって、行き着く先は Octree
と同じですから実装次第でメモリにも優しく効率もよくできると思うのです(これは前処理の時
間も含めて)。という訳分からん理由で、ここは我が道を進もうと思います
夢のしずく(2005/02/22)
ドラクエのアイテムか?と思われますが、松たか子さんの曲です。テレビでちらっとかかってい
3
たことがあって「いいなぁ」と思ってましたので(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 でレンダリング。
4
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 の御本家は以下です。日本語で説明してくれているので、英語
の苦手な私も安心です。
5
http://www.maxwellrender.com/indexjp.html
手元にある Redqueen いじりたくなってきた・・・ちょっくら遊ぼうっと。
ワイヤーフレームレンダラ(2005/2/18)
どんどん目的から遠ざかっているみたいですが気にしない (^_^;;!!ってことで、今までの内容を
生かしてワイヤーフレームレンダラを作ってみました。
また、形が出来次第公開しようかな(Shade のプラグインです)。
このポリゴン描画+ワイヤーフレーム描画方法だと、ソフトウェアレンダラでもワイヤーフレー
ムが途中で途切れたりしません。またアルゴリズムについては、改めて Tips として(ソース付き
で)公開予定にしてます。もはや、この程度でしたらリアルタイムで(ソフトウェアレンダラで
もいいですし、OpenGL/DirectX 使ってもいいですし)できそうですね。
ただ、苦労した点として「クリッピング」があります。これによって境界部分の挙動が変わりま
すので、結局スクリーン全体のレンダリングが必要でした。(実は、上記画像は Carrara や
MentalRay みたいにブロック単位でレンダリングしてます。なので、メモリは食わないですが速
度は犠牲になってます)
Shade 本体のワイヤーフレームレンダラでも、ぜひこの方法でソフトウェアで対応してほしいも
のです。(そうすると、大きなサイズでも対応できるんで。後、ハードウェアでの挙動不審を回避
できるし)
続・ポリゴン描画とワイヤーフレーム(2005/2/16)
ようやく、ポリゴン描画の上にワイヤーフレームを重ねる場合のブチ切れ解消ができました。
過去のもの。線が途切れている部分があります。
6
改善後。途切れることがなくなりました。ちょっと直線がガタガタな部分があるのは bresenham
アルゴリズムにてテスト用の計算いれているからです。もうちょっとすっきりできると思いま
す。
ワイヤーフレーム描画時に手前に少し浮かしている、ということはしてません。厳密には、浮動
小数点のエラーの問題がありますので(Athlon と Pentium では挙動が微妙に異なります。実は、同
じ開始点・終了点を持つラインを同じ Z 値で描画してもイコールにはならない場合があります)気
持ち程度の調整は入れてます。
DirectX/OpenGL を使ってポリゴン描画すると当たり前のことが、ソフトウェアレンダラでは意外
と難しい実装になる、というなかなか骨の折れる検証となりました。・・・・思いっきりレンダ
ラからそれていってる内容ですが (^_^;;、これはいろいろ役に立つことでして。例えば自前のモデ
7
リングツール(オリジナルの3Dエンジンを使用する場合)を作る場合でもワイヤーフレーム描
画が汚くならない、Shade 標準のワイヤーフレームレンダラは OpenGL に頼ってますが、これを自
前の描画に置き換えるとハードの制限に左右されない(かつ、環境依存する挙動の問題に対処で
きる)、などなどです。
これにトライしている人ってネット上で見かけませんね・・・。というか、ソフトウェアの3D
エンジン作る人が少ないからかな (^_^;;。理屈としては、直線描画時(ワイヤーフレーム描画時)
にポリゴンとして補間しつつエッジだけ描画する、ということになります。こうすると、理論上
は同じポリゴン描画の上にポリゴン(といいつつ実はエッジだけ描画)を重ねるので Z 値の微妙
な前後関係は確保される(イコールになる)ことになります。
意外と難しいポリゴン描画(2005/2/15)
ポリゴンをソフトウェアで独自描画する場合、よく使われるのが左右の稜線に対し、スキャンラ
イン方向に交わる交点を結ぶ直線を引いていく方法です。
Z バッファで処理する場合はZ情報も持ちます。左右稜線それぞれに対して始点・終点を探し、こ
のうちスキャンラインで交わる点を求めます。(x1, y, z1) - (x2, y, z2) とします。水平方向では、こ
の交点 2 点を線形補間することで求めていきます。これを垂直方向に最小から最大まで繰り返し
ます。
普通にゲームなどで使う場合はこれで問題ないのですが(つか、ソフトウェアで独自には実装し
ませんわな)、この上にワイヤーフレームを重ね合わせたい場合、不都合が生じることがありま
す。線がとぎれたり汚くなったりする問題です。
なぜそうなるのかというと、最終的に2D描画するときのドットの厚みによるものに感じます。
8
の上面図をスクリーンに描画するとすると、稜線部分を拡大すると以下のようになります。
横方向に 4 ピクセル分の厚みがあるのがわかりますでしょうか。さて、ではこの 4 ピクセルのう
ちで、Z 値が大きく変化するとすると「ポリゴン描画(スキャンラインコンバージョン)」とエッ
ジ部分を描画する「直線描画」で Z 値がぴったり一致するでしょうか?ポリゴン描画では、稜線
は Bresenham を使っても 1 ピクセルごと地道に計算してもいいです。ただし、ポリゴン・直線の
描画は同じアルゴリズム・同じ順番で稜線・直線を追いかけるようにしてください(でないと、誤
差が出るのが明白ですしね)。
普通に考えると、ポリゴンのエッジをなぞっているだけなのでZ値が一致すると思うかもしれな
いですが、これが一致しないのです。ポリゴン描画でスキャンラインごとの描画をする、このと
きに横方向では「ポリゴンとスキャンラインの交点の開始位置・終了位置」の直線を描きます。Z
値もそれで線形補間されます。
直線描画(ワイヤーフレーム部分の描画)を行う場合は、直線の開始位置・終了位置でZが線形
補間されます (X 方向・Y 方向のうち、変化量が大きいほうで分割 )。ここで、Z値の矛盾が出て
きます。2 つめの画像の上面図を見ると、実際は横1ライン描画するにも(直線を構成する同一ラ
イン上の 3-4 ピクセル間でも)Z 値が変化するため、スキャンライン描画と直線描画(斜め)でZ
値がずれてしまうのがわかりますでしょうか(う∼む、説明が難しい・・・)。
9
解決策は、直線描画も(補助線を入れるなりして)ポリゴンと見なして対象となる直線を描画す
るか、スキャンラインコンバージョンをやめるか、です(バイアスかけて直線を少し手前に出す、
はゴミが気になります)。
DirectX/OpenGL によるハードウェア描画ではこの問題も解決されているのですが、複雑そうで
す。別の方法でポリゴン描画してるみたいだし。
「http://spin.s2c.ne.jp/」の Articles の【第 3 回 ラスタライズアルゴリズム】参照。
このあたり、乗り越えたい問題ですのでいろいろあさってみることにします。いやはや、単純に
見えて奥が深いです。
ポリゴンエッジ部の微妙な誤差(2005/2/13)
ハードウェアにてレンダリング時に陰線消去する場合など、以下のようにきれいに線が出ていま
す(以下、DirectX9 の MeshView)。
で、こちらで作ったポリゴンの描画ルーチンだと途中で線が消えたりして汚いわけですが (^_^;;、
これはどうもポリゴン描画にて Bresenham の直線描画のアルゴリズムを、ポリゴンの稜線をたど
るのに使っているから(整数でエッジ部をたどっている)かなぁと想像しています。
DirectX/OpenGL などでの陰線消去のやり方は、Z バッファのみをレンダリングし(色は反映しな
い)、その上に直線を Z 値を考慮して描画します。このとき Z 値が<=の直線のみを描きます。こ
こでブチ切れ直線にならない、ってことはこのポリゴン描画と直線描画の Z 値がぴったりフィッ
トしているから、かな。
ちょっくら私のほうのポリゴン描画ルーチンを見直してみることにします。これ、何に使ってい
るのかというとセレクティブレイトレースで使ってるんです。微妙に汚れが出るんですね(直線
描画時に Z 値を少し手前に持ってくればいいのですが、奥行きがあるとつらいし)。見直さねば。
10
あ、でも、これをやるとソフトウェアのリアルタイム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 用のレイトレーシングプログラムの原稿
11
日付から見て 1995 年ごろのキャラクタエディタ仕様書
1 つ目のを見て(文書生成ソフトとして)何を使って書いたか分かった方、非常にマニアです。罫
線を見ると特徴あるのでピンと来る方もいるかもですが、今争っているジャストシステム社の
「一太郎」
「花子」の DOS 版で書いてました。DOS 時代は結構お世話になったので、ぜひ裁判では
ジャストシステムにがんばっていただきたいですね(ちなみに、当時はうちの親がジャストユー
ザだったんで使ってました)。今は ATOK だけしか使ってないですが、JustSystem ユーザです、私。
12
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 です。
13
面光源の影が新聞の印刷みたいなノイズになっちゃいましたが・・・。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 のストリーミング実装、思った
よりも簡単でした。
14
まずは、基本的な音のデジタル処理の仕組みです。元々、アナログな音は 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」構造体にてこれの情報を設定することになりますが関
係としては以下のようになります。
構造体変数名
意味
wFormatTag
WAVE_FORMAT_PCM
15
nChannels
チャンネル数
nSamplesPerSec
サンプリングレート(Hz/sec)
wBitsPerSample
サンプリングサイズ(bits/sample)
nBlockAlign
nCannels * (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 はブラックボックス化された部分が多いですので、例えばミキシングなどは自
前で行ったほうが効率がいい場合もあるかもしれません(ハードウェアが効いているのなら別で
16
すが、特にストリーミングの場合は送る前に独自圧縮したい場合があります)。
とりあえず、DirectSound がネットワークのトラフィックなども加味した場合にストリーミングに
使えるのか、などなどいろいろ検証してみようと思います。
ちなみに、このためにマイク買いました(昔の SoundBlaster 付属のマイクが壊れているようで使え
なかったため)。カラオケとか司会にも使えそうなダイナミックマイクです。歌いながら実験す
るかぁ。リアルタイムストリーミングでボイスチェンジとかできても楽しそうですし。
セレクティブレイトレース その 2(2005/2/3)
先日、格段に速くなると豪語したセレクティブレイトレースですが、29 秒のが 25 秒に・・・って
あんまり変わらない・・・
(2/2 の日記にある平面に反射する球を敷き詰めたやつね)。これは、全
体的な反射と面光源(サンプリング数 10)を使っていたというのが影響してました。GI だと全体
に占める一次レイの走査の割合は少なくなるのでセレクティブレイトレのインパクトは薄いで
すね。
で、別途面光源を高速化できないかということでいろいろ試してみたのですが、シャドウマップ
が一番品質と速度共に確保しやすく感じました。しかし、メモリを食うのと広大なシーンではボ
ケボケになりますので別のアルゴリズムを考案中です。理論は固まったのですが画質はまだい
まいち。まだ研究の余地ありですが手応えはありそうです。実装すると、25 秒のが 11 秒くらいに
短縮できました。
面光源の影のエッジは緩やかになる傾向が強いため、補間が有効なはず。というのを切り口にし
てシャドウマップでないノイズのない面光源の影、ぜひ実現したいところです。
セレクティブレイトレース(2005/2/2)
日記でちらっと話題にしていたのですが、改めて実装中ですので記載。セレクティブレイトレー
スとは、レイトレースするときに一次レイを「はしょる」ことにより高速化を図る手段です。
この一次レイを求めるときに、スキャンラインまたは Z バッファで「オブジェクト番号・ポリゴ
ン番号・Z 値」によって塗りつぶします(これはラスタライズ的に)。
それを色つきで可視化したもの。
17
上記は 64x64 ピクセルのブロックごとに処理しているため、メモリとしては最大 64x64 ピクセル
分を保持するといいことになります(レンダリング画像全体だとさすがにメモリを食いますの
で)。Z バッファで書いています。
ここのバッファに存在するピクセルは、
「そのオブジェクト番号・ポリゴン番号」の組み合わせで
のみ交差判定を行えばいいことになり、反射・透過しない物体のレイトレースでは格段に速度
アップします(実際、レイトレースしてないわけですし)。2 次レイ以降は普通のレイトレースに
なります。
以下、レイトレースの最終結果と合成してみました。
この手法の場合、込み入ったシーンほど速度アップが見込まれます。これは、CALLISTO と Shade
でテストしてみると一目瞭然で違いが分かると思います(複雑になればなるほど。例えば枝が多
18
数分かれている木とか、髪の毛をポリゴンで作ってレイトレレンダリングするとわかりやすいで
す)。
ただ、GI になるとすべてが反射するようなものですので効果が薄いです。ですが、少しは足しに
はなるかなぁ。
問題はアンチエイリアスの処理なんですが、これは基本はオーバーサンプリングで行うといいと
思います。アンチ処理ではちょっと複雑にはなりますね。
ちなみに、上記画像は 48002 ポリゴンのシーンで 320x240pixel のセレクティブレイトレースで、こ
の Z バッファ描画の前処理は 800ms 程度(Athlon 1100MHz の Win2000 にて)、と負荷は無視でき
るレベルです。このために、BMP にブロック書き出しするルーチンを作って組み込んでみまし
た。それ込みで(ブロックごとのアフィン変換・ファイル書き出し込みで)800ms なんで実用には
使えそうですね。(ブロックごとにいちいち計算を発生させるので遅いかと思ったけど大丈夫み
たい)
たぶんですが、Carrara とか MentalRay とかって このタイプかなぁと思ってまねてます (^_^;;。
19