月別アーカイブ: 2006年10月

ソフトバンクの新料金

ブルーとかオレンジとかゴールドとか
料金プランの種類があまりに多くて複雑で混沌としているので、
その中からどれが自分の使い方で一番安くなるか
シミュレートしながらいろいろ計算してみるのが結構楽しいです。
アセンブラの最適化をしているような感じです。

Vista で install~ のファイル名

自分で作ったコマンドについ install~ の名前をつけてしまってあせりました。

Windows Vista ではどうやら名前に instal がついたプログラムはインストーラと
判断して UAC の監視対象になるようです。そのため起動すると毎回確認のための
ダイアログがでてしまいます。
エラー終了時にもインストール失敗なのかどうかきかれます。

よく見るとアイコンにも4色の盾のマークがついてるし。

リアルタイム 3D レンダリングで半透明描画が重い話 (2)

ゲームなどリアルタイム 3D のレンダリングでは、フィルレートがますます厳しく
なります。これはもう当たり前の状態だといえます。

Xbox360 であれ PS3 であれハードウエアの性能は向上したものの、より高い
解像度が求められるようになっているからです。

しかも開発者側も、フィルを無尽蔵に消費できた特殊な PS2 の開発に長いこと浸り
きってしまっていました。

Xbox360 や PS3 の開発がかなり進行している今となっては、実作業を経験すれば
もうこの問題は十分理解できているでしょう。4~5年前の Xbox の開発では
PS2 系デザイナーとプログラマとの間で何度も衝突することがありました。

コンシューマでは、PC 向けビデオカードよりもさらにバス帯域が限られてくるので
さらに描画ピクセル数をきちんと管理する必要が生じます。

なお、Wii に関しては次の記事を見る限り、シェーダーが無く描画機能も非常に
限られている可能性があります。フィルや描画のバランスがどのように設計されて
いるのかはわかりません。
http://pc.watch.impress.co.jp/docs/2006/0920/kaigai301.htm

古くはリアルタイムレンダリングの場合、データ仕様をポリゴン数で切りました。
トランスフォームやクリッピング、ライティング、スキニングなど、ジオメトリ
演算の方が負荷が高かったからです。
もっと厳密に言えばデータ負荷の目安はポリゴン数よりも頂点数です。

今のハードの場合、呼び出し方を間違えなければ頂点数はそれなりに出るし、
一度ストリームに乗せてしまえば GPU だけで全部やってくれます。

むしろシェーダーによって重いピクセルが多いので、如何に描画ピクセルを減らす
かが負荷の目安となります。なので、データ仕様はどちらかといえばシェーダー
毎のピクセル負荷と面積で切ることになります。

もちろん面積はオクルージョンカリングが有効な条件を満たしているかどうかが
鍵です。あらかじめ Z バッファを作っておくか、常にカメラの手前から描画する
ことでレンダリングするピクセル数はほぼ一定量になり、ピーク負荷も求まります。

例えばフルにノーマルマップを使うなど重い背景データがあったとします。
この背景のマップオブジェクトのシェーダーが一番重いとわかっているなら、背景が
画面いっぱいに描画されいてるケースで最も負荷が高くなります。

キャラがカメラの手前ぎりぎりまで近寄って、どんなにアップで表示されようとも
負荷は上がりません。むしろ描画すべき背景の面積が減って相殺され、かえって
負荷が軽くなるわけです。

ただしこの負荷の計算はあくまで「alpha 値を含まない不透明ポリゴン」にのみ
当てはまります。カメラアングルや状況によってめまぐるしくピクセル負荷を上げる
要因となるのは「影」と「エフェクト」です。

影は今のハードウエアと描画アルゴリズムではとにかく(ひたすら)重い処理です。
機会があったら解説します。

またエフェクトでは煙や光物など、半透明のオブジェクトが画面いっぱいに重なって
描画されるともう終わりです。処理落ちどころではありません。

この2つのピクセル負荷は一定のピーク値として計算できないので、非常に苦しい
ところです。

またエフェクトのようにあとから乗せるパーティクル系のオブジェクトでなくても、
マップとして配置する半透明のガラス等でも別の原因で負荷が高くなります。
さらに木々の葉っぱなど、Alpha や texkill でピクセルを捨てるケースがあると
オクルージョンカリングが無効になることがあります。

それどころか、オクルージョンカリングのために先に Z バッファだけレンダリング
する場合も、半透明や抜きのあるポリゴンは完全に先行レンダリングできません。

GPUの負荷
・エフェクトなど半透明ものは完全に追加のピクセル描画となる
・パーティクルは重なることが多く、カメラ位置によって面積が極端に変化する
・マップ配置物でも透過や抜きはオクルージョンカリングを阻害する

CPUの負荷
・加算以外の半透明オブジェクトは描画時にZソートが必要となる

だから alpha 成分を含む半透明オブジェクトは、エフェクトにしろマップ配置に
しろ大量かつアップで描画されると重いのです。

リアルタイム 3D レンダリングで半透明描画が重い話 (1)

それまでコンシューマをやっていたチームが、新たに PC系ビデオカードでゲームを
作ろうと評価を始めると、エフェクトなど半透明の描画が遅いので引っかかって
しまうことがあるようです。

でもよくよく話を聞いているとポリゴンを重ねすぎているだけのように見えます。

半透明の描画が通常のポリゴン描画よりも遅いのは当たり前です。
唯一当たり前じゃなかった特殊なハードが PS2 です。

PS2 には PixelShader どころかマルチテクスチャ等の pixel 演算系機能が無いので
表現力を上げるにはマルチパスを用いる必要がありました。

なのでエフェクトもひたすらポリゴンを重ねて半透明を大量に使う傾向があります。
PS2 は GPU (GS) にオンチップで VRAM を搭載していて、その転送バスは 2560bit
(147MHz で 47GB/sec) もあります。16 pixel/sec と並列度も高く、稀に見る
フィルレートの高さを持っていました。

これなら半透明など Pixel の Read/Write を頻繁に繰り返してもさほど速度が
落ちません。

オンチップでバスの太さを選んだ代わりに容量が犠牲になっており、VRAM はわずか
4M byte しかありませんでした。

4M byte だとフレームバッファだけでも一杯になるので、さらにインターレースを
用いて半分(640×240)で済ませたり、横の解像度を若干削ったり(512)します。

例えば 640×480 で color 32bit, depth 32bit だと 2.4M と半分以上も消費します。
512×240 まで削ると 1Mbyte くらいで収まります。

フレームバッファが小さくなるとさらにフィルの負担が減ることになります。

もちろん半透明といっても、等視点が変わるケースではソートが必要になるため
完全なコストフリーではありません。だけど他のプラットフォームに比べたら
圧倒的に(異常に)速かったわけです。

そんな作り方に慣れてしまっていると他のハードを使ったときに困ってしまいます。

半透明は極力減らすようにとデザイナーに伝えても「前はこうやって作ってたから」
となかなか理解してもらえないのです。

例えば同世代(?)の Xbox は、CPU と共有のバスで 6.4GB/sec の帯域を持っています。
その代わり 64MByte 全部に GPU が直接アクセスできます。

pixel 並列度で 1/4、バスの転送能力で 1/7.5、だけど VRAM は 16倍。そして
マルチテクスチャやプログラマブルなシェーダーを搭載しています。

この場合半透明をひたすら重ねる作り方は自分の首を絞めるようなもので、できる
限り重ね描きを減らさなければなりません。

リッチな表現はマルチテクスチャやシェーダーを使えばいいので、むしろマルチパス
など重ねて描画する必然性が少ないともいえます。

同じようにいまどきの PC のビデオカードも、メモリアクセスが無尽蔵にできる
わけではありません。GPU 自体の膨大な演算能力に比べるとバス帯域はそれなりに
限界があります。

例えば GeForce79000GTX のメモリが 256bit バスの 1600MHz だとすると
51.2GB/sec です。これでもべらぼうに速いんだけど数値上は PS2 の 47GB/sec と
それほど差がありません。

そして PC はよりハイレゾが求められるので、例えば 1920×1200 だと 32bit color,
32bit depth のフレームバッファだけで 18Mbyte です。
たったこれだけでも必要な転送量は 7~18倍 にもなってしまいます。
HDR をまじめにやると color は 64bit です。

この描画面積を考えると PS2 比の転送能力はずっと落ちていくことになります。

それだけ PS2 が特殊だったといえます。

できる限りピクセルを重ねずに、ピクセル1つにかける演算を重視します。
GC, Xbox1, Xbox360, PS3, PC (D3D9) と、その傾向は徐々に強くなっています。

半透明が重いのは当たり前という前提でまず描画の設計を見直しましょう。

シェーダーが必要なわけ

もうすぐ PS3 が登場して、ようやくメジャーハードでハードウエアシェーダーが
当たり前になります。1年前に登場した Xbox360 を筆頭に、ShaderModel3.0 が
リアルタイムレンダリングで必須になるわけです。

本当は 2002年に発売された Xbox1 に ShaderModel1.x が搭載されており
シェーダーの時代はとっくに始まっていました。

あまり注目されなかったのは販売台数のせいもありますが、ShaderModel1.x では
機能的制約が大きかったのも一因でしょう。

特に PixelShader で使用可能なステップ数は 演算8+テクスチャ4 の 12個で、
演算制度も 9~12bit 程度の固定少数でした。

もちろん海外での事情は異なっており、Xbox も PC ゲームも人気があるので
シェーダーのノウハウの蓄積はずいぶん先行しているといえます。

シェーダーの登場によって、開発するプログラマの手間は結構増大します。
固定機能の時代はハードに設定すれば勝手にやってくれたジオメトリやライトの
演算も、まるで時代が逆行したかのように自分でやらなければいけなくなりました。

特に初期のシェーダーはアセンブリ言語で記述していたため、拒否反応を示す
人も多かったようです。

ではなぜそこまでしてシェーダーが必要なのでしょうか。

ハードウエアロジックでの実装はたいへん時間がかかると考えられます。
設計から試作、量産まで、実際に動いて使えるようになるまでどれだけの手間と
時間がかかるか想像もできません。

それでも GPU はテクノロジの進化によってさまざまな機能を実装できるように
なりました。もちろんひたすら高速化のために並列度を上げていけばいいんですが、
それだとトランジスタ数よりも先に、メモリ速度やバス帯域が限界に到達して
しまいます。

そのため、ただただ速度を上げるよりも、より美しい描画を行うために機能を割く
必要が生じます。

ただしこの分野はアルゴリズムの問題であり、どんなアルゴリズムを、どんな仕様
でハードで実装すればいいのか取捨選択するのが難しいのです。
アルゴリズムの研究の進化も早いですから。

だったらプログラマが自由に命令を選択できる方がいいのではないか、そう考える
のも自然でしょう。

ハードウエアシェーダーの登場によって、プログラマが自由にハードウエアの演算
ロジックを変更できるようになりました。

プログラマがハードの機能を選択するのに必要な時間はごくわずかです。いくらでも
設計と試行、フィードバックを繰り返すことができるのです。
ハードロジックを設計してチップを製造する時間とは比較になりません。

ハードウエアアクセラレーションの恩恵を受けつつ新しいアルゴリズムの開発が
短期間でできるようになり、一気にリアルタイムグラフィックスの分野が華やかに
なりました。

アルゴリズムを開拓する人にとってはたいへん魅力的なものです。

そしてシェーダーはハードウエアでしかできなかったさまざまなアルゴリズムを
アプリケーション化してくれます。他の人が作ったシェーダーをもらってきて
使うこともできるわけです。

もう1点、シェーダーがどうしても必要だった理由があります。

GPU の開発会社や Direct3D 等の API を設計する Microsoft 等と、実際にゲーム
等を開発する現場とはどうしてもそれなりの距離や隔たりがあります。

実際に現場が欲しい、リアルタイムレンダリングで欲しい機能と、ハードに実装
される機能は必ずしも一致していませんでした。

頂点カラーの演算方法、値の持ち方、ジオメトリブレンディングの仕様、ライティ
ングの仕様など。

固定機能の時代は、使わない機能やオーバースペックな機能であってもハードに
実装されているため使わざるを得ませんでした。また API の設計によっても
制限を受けます。

むしろ DirectX3~6 等、CPU だけでジオメトリ演算を行っていた時代の方が
ゲームにあわせて自由に頂点や演算を設計し、不要な演算は徹底的に省いて必要
最小限にすることができました。

DirectX7 世代のハードで Hardware Transform and Lighting が搭載され、
演算が極めて高速になったのは望んでいたことでした。
が、速度は速くなったのだけど、逆に使いづらい制約も増えたなと感じたものです。

DirectX8 でシェーダーが登場し、不満だった部分も全部再設計できるようになり
ました。CPU 演算時代の自由度と、GPU の速度の両方を手に入れたのだから
シェーダーは最高です!