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

CLI(2) C++/CLI 面白そう

http://ch09144.kitaguni.tv/e310960.html の続き
CLI の仕様に沿っていれば、.NET Framework 用アプリケーション開発は特に言語を
選びません。C# だろうが VB だろうが。この辺が Java とは少々趣が違うところで
しょうか。

そしてもちろん C++ での開発もできます。C++ といえど CLI に従うので MSIL に
コンパイルされます。C++ なのにネイティブコードにならないのは何となく不思議
な感じがします。

CLI にさえ従っていれば他の言語でもかまわないし、さらにアセンブラを使って直接
MSIL のコードを書くこともできます。

C++/CLI で非常にユニークなのはネイティブコードとの共存ができることです。

言語仕様も拡張されており、C++ のルールにのっとりつつも C# のような言語拡張が
使えて管理された安全なコードを書くことができます。これはマネージドコードと
呼ばれるものです。MSIL です。

同時に従来の C系統のコードがそのままコンパイルできて、従来のライブラリも
リンクできます。こちらはネイティブな x86 等のバイトコードになります。

この両者が1つのバイナリに共存していることになります。

ネイティブコードの部分は .NET Framework 管理下に無いのでアンマネージドコード
と呼ばれます。

ちなみに C# でも、DLL など Win32 API 呼び出しができたりポインタを使った
メモリアクセスができるので、C++/CLI と同じように意図してアンマネージドな
プログラムを呼び出したり書いたりできるようになっています。ネイティブコード
に変換されるわけではないのですが。
(続く)

今頃 C# と C++/CLI 使い始めました

C# は C言語系の新しい言語の一種です。C# を使ってアプリを作るのは簡単だし
便利だよとよく話を聞くのですが、この場合 .NET Framework まで含まれるので
少々混乱します。

まず .NET Framework というのは Windows の新しい API セット&ライブラリの
ことです。ツールキットであってクラスライブラリです。OS のさまざまなサービス
を提供しつつ、ユーザーインターフェースやらなにやら便利な機能をたくさん
取り揃えています。

.NET Framework を利用できるのは、MSIL と呼ばれる仮想コンピュータ用の
プログラムだけです。直接ネイティブな x86 等のバイトコードではありません。
これは .NET Framework に含まれる CLR と呼ばれるランタイムが、プログラムの
実行直前にネイティブなコードに変換します。

つまり、JIT コンパイラによって MSIL から x86 へのコンパイルが行われてから
プログラムが走るので、実行時はネイティブコードとしてのパフォーマンスが期待
できます。

このように面倒なのですが

・プログラムは仮想マシンのバイトコードなので完全に管理下に置くことができる。
 不正なコードやバグを除外できる。セキュリティ強化。

・仮想コードなのでプラットフォーム依存を無くすことができる。

等のメリットが考えられます。

仮想マシンや JIT コンパイラなど、動作の流れも特徴もほとんど Java と同じです。

ただし Java は完全に言語仕様と動作環境やクラスライブラリが一体化しているの
に対して、.NET Framework はオープンです。仮想マシンのバイトコード MSIL レベル
で仕様が統一されているので、そこから上のプログラミング言語は特に限定されて
いません。この仕様が CLI になります。

プログラミング言語としての「Java 言語」に相当するのが C# です。C/C++ 言語
における、バグの原因となりやすい部分を言語仕様として改良&拡張しています。

そのため C# による開発を語る場合は、言語としての便利さと、.NET Framework
における管理された安全性やライブラリの使いやすさとしての便利さと、開発環境
として整っているツールの便利さが含まれているようです。

今後 Vista にあわせて .NET Framework 3.0 としてさらに幅広いサービスが提供
されるらしく、ワークフローにまで及んでくるそうです。今後はネイティブコードが
消滅して Windows 自体、アプリケーションも全部 MSIL で動くようになるので
しょうか。
(続く)

mipmap とフィルタリング(続き)

mipmap は pixel 毎に異なるテクスチャを参照するため、その境界がはっきりと見
えてしまうことがあります。

この境界をぼかすために 2つの level の mip テクスチャ間で線形補間を行うこと
ができます。u-v 方向にかかるバイリニアフィルタに対して mip level 方向が
加わるためトライリニアフィルタと呼ばれます。

u方向とv方向の解像度が異なる場合など、向きによって適切な mip level に大きな
差が生じる場合は少々厄介です。

例えばカメラに対して大きく傾いている地面や天井は、元のテクスチャ画像よりも
細長い形状となります。縦方向(画面の奥に向かって)は小さいテクスチャを参照
したいのですが、横方向にはもっと大きな解像度の画像が必要です。

そのため高い解像度のテクスチャを参照しつつ、縦方向(画面の奥)に向かって
縮小をかけます。これが異方性フィルタリング(Anisotropic filtering)です。

ぼけぼけだった mipmap の効果も引き締まって見えるので見栄えのいい画面に
なります。が、きれいに縮小するためには部分的に mipmap のデータを作ってるよう
なもの。重い処理となってしまいます。

傾きの大きいポリゴン以外は効果が小さいので、場所によってどの程度まで
フィルタリングするのか使い分けがいります。極端な例だとビルボードには全く
必要ないわけです。

(前の記事)
http://ch09144.kitaguni.tv/e309230.html

東プレ Realforce 買った!

こんなに幸せだったとは!!!
東プレ Realforce91U 買ってしまいました。
2万円近い値段のキーボードです。
値段で躊躇していたのだけれども、店頭でついつい触ってしまい、
結構うろうろしつつ悩んだ末の購入。
だけど実際に使ってみたらもう大満足。
どんなに速くキータイプしても文字がついてくるのですよ。
どんなに長くて複雑な関数名でも全部自分で最後までタイプできるのです!

http://www.topre.co.jp/products/comp/key_list.html

今までは速くタイプすると途中でキーが引っかかってしまい、無意識のうちに速度
を抑え目にしていたようです。全力疾走したいけどできなかったような感じです。

長いシンボル名では引っ掛かりを回避するために、途中までタイプしたらすぐ
テキストエディタの補完機能を使ってました。
それだけ自分のキータイプに信頼が無かったのでしょう。

Realforce ではそれが必要ありません。最後まで文字を打ち抜けます。
キーの軽さやタッチ感が高級なせいもあるのでしょうが、どうやら
「Nキーロールオーバー」おかげみたいです。

前のキーを離す前に次のキーが押されると、同時に複数のキーが押された状態に
なります。このまま次のキー入力を認識できるのは、普通のキーボードだと
3キー程度が限界だそうです。

きっとタイピング技術がもっと上手ならば、キーを離してから次の文字をしっかり
打てるのでしょう。自分は速くタイプすると4キー以上同時に押してしまっている
ようです。

Realforce は何キーでも押された順番認識できるらしいので、これが
「最後まで文字を打ち抜ける」感覚につながっているわけです。

そういえば 8bit/16bit パソコンの時代はキーボードの相性がありました。
キーボードマトリクスの関係上、直角に並んだ特定の3キーが押されるともう
1キー押されたことになってしまいます。
高速にタイプしていると知らない文字がよく混ざったりします。

マトリクスの配列に依存するので、自分のタイピングのくせとこの条件が重ならない
キーボードだと速く打てて相性がいいのです。

最近このマトリクスの話を聞かないので、特定の3キーが同時に押されるとキー入力
自体が入らないようになっているのかもしれません。
もしかしたらこれがタイピング中に感じる引っかかりの原因なのでしょうか。

とにかく東プレのおかげで幸せです。

mipmap が嫌われる

ゲーム開発ではなぜか mipmap が嫌われることがあります。

GPU のレンダリングではカメラからの距離に応じて、参照するテクスチャの解像度
を切り替えることができます。例えば 512×512 pixel のテクスチャ画像がある場合
あらかじめ縮小した画像を次のように何パターンも用意しておきます。

256×256
128×128
64×64
32×32
:

カメラから近い場合は高い解像度のテクスチャを参照しますが、遠くの場合は
高い解像度を使う必要がありません。mipmap を用意しておけばそのため遠くに行く
ほど小さいテクスチャの参照で済みます。いわゆるテクスチャ解像度の LOD の
ことです。この mip レベルの選択は pixel のレンダリング時に行われます。

正確にはカメラからの距離というよりも、レンダリングするポリゴンの面積から
計算すると効率が良いことがわかります。画面のピクセルに対してできる限り1対1で
対応する解像度のテクスチャを参照したいたいためです。

実際の実装ではピクセル間の uv の密集度から mipmap のレベルを判断します。
ピクセル間の差分は、PixelShader でも 2.x 以降なら dsx, dsy 命令で求める
ことができます。

テクスチャの拡大と異なり、縮小時のフィルタリングにはより多くの pixel 情報を
畳み込む必要があります。例えば最大まで縮小した 1×1 pixel の点には元の
テクスチャのすべての平均値が含まれます。

この計算はリアルタイムに向かないので、前処理でフィルタリングしておける
mipmap は低負荷ながら遠くのポリゴンのちらつきをおさえて画質の向上に
つながります。

もちろんテクスチャアクセス時の負担も減るので mipmap を使った方がテクスチャ
フェッチは高速です。

mipmap はできるだけ使ったほうが良いのです。

デメリットは、あらかじめ縮小した画像を含んでいる分だけテクスチャ容量が
1.34倍程度に増えることです。

コンシューマ系のゲーム開発で mipmap があまり使われないのは、ひとつは容量の
問題でしょう。Xbox1 以降なら容量に対してアクセス負荷が高いので、使用した
場合のメリットの方が大きいと考えられます。

極端にバスアクセスが速かったり、シェーダーでピクセル演算の方が重くて
テクスチャ読み込みが負担にならない場合はこの限りではありません。

もうひとつは mipmap を使ったほうが負荷が高いという思い込みがまだ残って
いることかもしれません。

そして画像が過度にぼけすぎることです。

画質がぼけすぎるのは、最適な解像度よりも下のレベルのテクスチャが参照される
ことがあるためです。

例えばテクスチャ画像とレンダリングされるポリゴンの縦横比が極端に異なると、
短い辺では最適な解像度でも、長い辺では解像度が足りなくなってしまいます。
見た目よりも低いレベルのテクスチャが参照され、引き伸ばされるが故に余計に
ぼけているように見えます。

3D 視点で描画される地面のように、カメラに対して角度のついたポリゴンはこの
傾向が強いので非常にボケボケの画質になりがちです。せっかく書き込んだ
テクスチャの詳細も失われてしまうので、これを嫌がるデザイナーも多いのです。

こんなときは mipmap を切るのではなく異方性フィルタ(Anisotropic filtering)
を活用します。
(続く)