radium.png
HOME | ARCHIVE | PRODUCTS | ABOUT | RSS

Modchip

2002-07-01

020701s.png

仮想 CD ソフトの導入を試みるも,ドライブとの相性が悪くて使い物にならない。仮想ディスクの作成に2時間以上かかるとのたまわれる。むう,これだから安物はいかん。

とかなんとかいってる間に, Take2 から GTAIII ver1.1 パッチがリリースされたようだ。

http://gta3.zoo.co.jp/main.html

このパッチでは,普段は CD から読み込まれるオーディオファイル類も HDD にインストールしておくことができるようになっている。ぬう,最初からそうしといてもらえればこんな苦労せずともよかったのに。

ともかく,これでやっとまともに GTAIII をプレイすることのできる環境が整った。一応念には念を入れて CD ドライブは旧式のものに換装しておく。これなら万が一 CD を読みに行っても大丈夫だ。

RADEON 8500 LE の調子もいい感じ。ややもたつき気味になることもあるけれど,オリジナル版でもこんな感じだったらしいので問題無しってことにしておこう。


こんなに苦労するんだったら,いっそのこと海外 PS2 用 GTAIII でも買えば良かったかも……って思ったんだけど, PS2 でリージョンの壁を突破するのはかなり難しいことのようだ。 Modchip にまで手を出さなくてはいけないらしい。

http://www.lik-sang.com/catalog/product_info.php?category=26...

さすがにこれは大変だ。ていうか家に半田コテ無いし。 DC なんかは ActionReplay だけで行けたんだけど。

http://www.lik-sang.com/catalog/product_info.php?category=32...


ダメ生活の始まり

2002-07-02

020702s.png

突然だけど,今週は仕事を休むことになった。ちょっと早い夏休み,ていうか梅雨休みだなこれじゃ……。つまり,また忙しくなる前に休んでおけってことらしい。ふうむ。

んでもう GTAIII を中心に,やりかけのゲームやらなんやらをプレイしまくり。ほんと自堕落な生活。休みぐらい,休みにしかできないことをやるべきだと思うんだけど……。まあ,ある意味これがそうなのかもしれないな,って思う。

けっきょくのところ, GTAIII は期待以上の出来だった。まず第一に,できることの幅がものすごく広い。本編のミッションだけでも大した量なんだけれど(いまだに最初の島を抜け出せないでいる),サブミッションとかを含めるととんでもない量になる気がする。ミッションをしていなくとも,道端の通行人をバットで殴って小銭稼ぎしてみたり,タクシーに乗ってクレタクもどきをやってみたりと,まったくもって暇潰し要素に事欠かないゲームだ。隠しの多さも含めて,この辺りが外国人受けしやすいところなのかもなあ,と思う。

車やら暴力やら犯罪やら,向こうで受けそうな要素がしこたま詰まっていながら,それでいてグロや過剰な表現に走らずにいるのが,わりといいバランス感覚だな,と思う。ギャグになるぐらいのノリで殺人犯罪,って感じ。


まあそんなわけで,しばらくゲームばっかのダメ生活が続きそうだ。


ISA なんて挿さりも

2002-07-03

020703s.png

自堕落デー2日目。半日を寝て過ごし,あとは GTAIII やったり IRC 行ったり,松屋行ったり本屋行ったり,とか……。当初はもうちょっとどっか出かけたりとかしようかなあ,とも思っていたんだけれど,中途半端にダラけるのもなんなので,集中的にダラけ生活実施中。

いちおう部屋の中の掃除などもしてみる。クローゼットの中に溜まっていた古着やガラクタなどを容赦無く処分していく。ガラクタは,ほんともうガラクタばかり。 SoundBlaster16 やら S3 Virge やら出てきて……,何のためにとってあったんだかわからんものばかり。いまどき ISA なんて挿さりもしねーよ,って感じでぽいぽい処分。整頓とは捨てることと見つけたり。


GTAIII はやっと2つ目の島に渡ったところ。サブミッションやらタクシーごっこやらにうつつを抜かしているおかげでちっとも前に進まない。この調子じゃクリアは遠いな……。

2つ目の島は全体的に建物が高く,道路も立体的な構造が多くなっている。1つ目の島がダウンタウン風で比較的平坦な構造だったのに比べると,より都市的なデザインに切り替わっている感じだ。もちろん,道を覚えるのはこちらの方が難しい。地図とにらめっこしながらだんだんと道と地名を覚えていく感覚はなかなか面白いと思う。レーダーを見ずに目的地の名前だけでドライブできるようになった瞬間,この街を制覇したような気分になる。なかなか楽しい瞬間だ。


FTGL

2002-07-04

020704.png

あいかわらず集中的ダメ生活実施中。ほげ……。


GLFW (OpenGL framework) はなかなか便利なんだけれど,単純に GLUT なんかから移行した場合にまず困るのが文字表示の手段が用意されていないこと。 OpenGL は標準でフォント描画の機能は持っていないので,なんらかの手段を自前で用意しなければならない。実験なんかのときはたいてい GLUT のフォント描画機能を使っていたんで苦労しなかったんだけどね。

そんなわけで,どこからともなく拾ってきたのが FTGL - "Freetype for OpenGL"

http://homepages.paradise.net.nz/henryj/code/index.html#FTGL

FTGL は TrueType フォントに対応した OpenGL 用フォント描画ライブラリ。ただし TrueType ファイルの解析には FreeType ライブラリを使用しているので,まずはこれを導入しておかなければならない。

http://freetype.sourceforge.net/

FreeType はたいていの Linux ディストリビューションに付属されているので,それをインストールすれば準備完了。 Redhat だったら freetype2-devel とか,そんな感じのパッケージが用意されているはずだ。

Windows の場合はソースからビルドすることになる。ただし,僕が試してみた限りでは configure && make ではうまくいかなかったので, configure は使わずにいきなし make するのがいいかもしれない。そんでアーカイブファイルとヘッダファイルを手動でコピーするわけ。

FTGL の方は,展開したディレクトリの中にある "linux" ディレクトリで make するだけいい。 Windows の場合も cygwin/mingw ならば linux ディレクトリ内で make すれば問題無し。ふむ。


んな感じで,とりあえず "Random Attractors" に Lyapunov 値の表示を追加してみた。 FTGL はただ TrueType をレンダリングするだけでなく,アンチエイリアシングやビットマップ化,「押し出し」なんかにも対応していて,わりと高機能なライブラリだ。なかなかいいかもしれない。

ただ文字を表示するにしても TrueType フォントを使用できるのは面白いことかもしれない。 TrueType ならば既存のリソースが数多く存在するからだ。


ぜんぜん異なるわけだし

2002-07-05

あいかわらずぐだぐだ生活しながら,夕方になると食料を調達しに仕方なく日に一回の外出をするような,そんな日々。近場の本屋が知らぬ間に強化されていたんで,なにげに本など買ってみたりする。買ったのは「闘うプログラマー」と「あずまんが大王」。どっちも,何をいまさら,って感じの本だけれど,読んだことないんだからしょうがない……。

おなじ本屋で "Numerical Recipes" の日本語訳版を発見。訳本があったんだ……そういえばこの表紙には見覚えがあるような気がする。

http://www2.gihyo.co.jp/books/bookinfo.asp?ID=518

すごく重たい本なんで,買うなら amazon で注文したほうがいいかもな,と思って書名から検索してみるんだけれど,1冊も引っかからない。そんなはずは……ってことで ISBN から検索すると,なんとかそのものを当てることができた。

http://www.amazon.co.jp/exec/obidos/ASIN/4874085601

「ニューメリカルレシピ・イン・シー」って,あんた……。


単純な範囲処理 − 例えば「配列 A の全要素に対して処理 B を適用する」なんてのを実行する場合, C では for や while などのループ構文を使って記述するわけだけれど, C++ ではテンプレートを利用することによってこれらの構文を汎用的な手続きとして定義することが可能になった。具体的には STL の for_each とか transform とかのアルゴリズム・テンプレートと関数オブジェクトの組み合わせによって実現するわけだけれど,このような汎用的な手段によって実装されたコードと,もとの「ベタな」ループによって実装されたコードにおいて,生成コードに関してどの程度の差異があるのか,ちょっと気になるところだ。

もちろん,生成コードなんて処理系によってぜんぜん異なるわけだし,同じコンパイラでもライブラリやバージョンの違いによってまた差異が生じてくる。だから,とりあえず生成コードを覗いておけば安心,なんてのはとても浅はかな考えではあるんだけれど,やはり現状としてどのような結果が得られるのか興味はあるわけで……あーっ,もう,つまり調べておいても損はないっしょ,ってこと。


テストに使用したコードのメイン部分はこんな感じ。

#include <iostream>
#include <algorithm>
#include <boost/array.hpp>
#include <boost/lambda/lambda.hpp>
using namespace boost::lambda;

typedef boost::array<int, 8> Array;

int main()
{
  Array a = {{1, 2, 3, 4, 5, 6, 7, 8}};
  Array b = {{10, 20, 30, 40, 50, 60, 70, 80}};
  Array c;

  test_func(a, b, c);

  std::for_each(c.begin(), c.end(), std::cout << _1 << ' ');
  std::cout << std::endl;

  return 0;
}

boost::array<int, 8> を "Array" としてエイリアスして,2つの入力 (a, b) と1つの出力 (c) を持つ関数 test_func に渡しているだけ。とりあえず関数 test_func には, a と b の各要素を加算して c に出力する,というような単純な処理をさせることにする。


最初に試したは,イテレータのループを使ったもっとも単純なバージョン。

void test_func_loop(const Array &a, const Array &b, Array &c)
{
  Array::const_iterator ai = a.begin();
  Array::const_iterator bi = b.begin();
  Array::iterator ci = c.begin();

  for (; ai != a.end(); ai++, bi++, ci++)
  {
    *ci = *ai + *bi;
  }
}

いちばん簡単な組み方だけど,ちょっと記述がまどろっこしい。こいつの生成コードは以下のようになった。

test_func_loop:
    pushl %esi
    pushl %ebx
    movl  12(%esp), %edx
    movl  16(%esp), %ebx
    movl  20(%esp), %ecx
    leal  32(%edx), %eax
    movl  %eax, %esi
L10:
    movl  (%ebx), %eax
    addl  $4, %ebx
    addl  (%edx), %eax
    addl  $4, %edx
    movl  %eax, (%ecx)
    addl  $4, %ecx
    cmpl  %esi, %edx
    jne L10
    popl  %ebx
    popl  %esi
    ret

かなりすっきりしたコード。完全に処理が展開されているあたり boost::array の優位性が現れているところだと思う。 C でベタな記述をしても,ほぼ同じようなコードが生成されるだろう。これはすごく望ましい例。


二つ目のはアルゴリズム・テンプレートを使用したバージョン。

void test_func_template(const Array &a, const Array &b, Array &c)
{
  transform(a.begin(), a.end(), b.begin(), c.begin(), plus<int>());
}

かなり簡潔な記述になった。これの生成コードは以下のようになる。

test_func_template:
    subl  $26, %esp
    movl  30(%esp), %eax
    pushw $0
    movl  40(%esp), %ecx
    pushl %ecx
    leal  32(%eax), %edx
    movl  40(%esp), %ecx
    pushl %ecx
    pushl %edx
    pushl %eax
    call  __ZSt9transformIPKiS1_PiSt4plusIiEET1_T_S6_T0_S5_T2_
    addl  $44, %esp
    ret

    .linkonce discard
__ZSt9transformIPKiS1_PiSt4plusIiEET1_T_S6_T0_S5_T2_:
    pushl %esi
    pushl %ebx
    movl  12(%esp), %edx
    movl  16(%esp), %esi
    movl  20(%esp), %ebx
    movl  24(%esp), %ecx
    cmpl  %esi, %edx
    je  L166
L164:
    movl  (%ebx), %eax
    addl  $4, %ebx
    addl  (%edx), %eax
    addl  $4, %edx
    movl  %eax, (%ecx)
    addl  $4, %ecx
    cmpl  %esi, %edx
    jne L164
L166:
    popl  %ebx
    movl  %ecx, %eax
    popl  %esi
    ret

ちょっと予想していたのとは違う結果になった。 std::transform 内の処理は全て展開されたあと,別関数としてまとめられている。多少まどろっこしい流れになっているけれど,ループ内部はちゃんと展開されているのでパフォーマンス的にはそれほど悪い影響は無いはずだ。ループ回数が多ければ test_func_loop とほとんど変わらない処理時間になるものと思われる。

また transform 以下のコードは linkonce 擬似命令によって,他の生成コードに同様の記述があった場合には選択的なリンクがなされるような指定になっている。この辺りはテンプレート関数のお約束だ。

ここで, test_func_template の派生として自前の関数オブジェクトを使用したバージョンを試してみたんだけれど……

struct add_func
{
  int operator()(int a, int b)
  {
    return a + b;
  }
};

void test_func_functor(const Array &a, const Array &b, Array &c)
{
  std::transform(a.begin(), a.end(), b.begin(), c.begin(), add_func());
}

これは test_func_template と全く同じ結果となった。おそらく,アダプタとかを利用してもうちょっと込み入った組み合わせを作ったとしても,生成コードはそれほど変わらないものと思われる。コンパイル時間は長くなるかもしれないけどね。


最後に試してみたのが boost::lambda を使用するバージョン。

void test_func_lambda(const Array &a, const Array &b, Array &c)
{
  std::transform(a.begin(), a.end(), b.begin(), c.begin(), _1 + _2);
}

処理内容が十分に単純なものならば boost::lambda を利用することによって記述の大幅な簡略化が望める。別途にファンクタ・クラスを用意する必要はなく,即席に関数オブジェクトを生成して渡すことができるからだ。また lambda 関数による記述は, "std::plus<int>" のようなものよりかは,なにをしているのか明確で,よりシンプルな記述であると思う。少なくとも lisp 愛好家なら喜んでこの記述を受け入れるはずだ。

ただし,生成コードはだいぶ込み入ったものになってしまうようだ。

test_func_lambda:
    subl  $60, %esp
    movl  64(%esp), %eax
    leal  32(%esp), %edx
    subl  $12, %esp
    leal  32(%eax), %ecx
    pushl %edx
    movl  88(%esp), %edx
    pushl %edx
    movl  88(%esp), %edx
    pushl %edx
    pushl %ecx
    pushl %eax
    call  __ZSt9transform...lambda_functor_baseINS4_17arithm
    addl  $92, %esp
    ret

    .linkonce discard
__ZSt9transform...lambda_functor_baseINS4_17arithm:
    pushl %ebp
    pushl %edi
    pushl %esi
    pushl %ebx
    subl  $12, %esp
    movl  32(%esp), %ebx
    movl  36(%esp), %ebp
    movl  40(%esp), %esi
    movl  44(%esp), %edi
    cmpl  %ebp, %ebx
    je  L194
L192:
    pushl $__ZN5boost6lambda...1vGAhb18constant_null_typeE
    pushl $__ZN5boost6lambda...1vGAhb18constant_null_typeE
    pushl %esi
    pushl %ebx
    call  __ZN5boost6lambda...tuples9null_typeES6...
    addl  $16, %esp
    pushl $__ZN5boost6lambda...1vGAhb18constant_null_typeE
    pushl $__ZN5boost6lambda...1vGAhb18constant_null_typeE
    pushl %esi
    pushl %ebx
    call  __ZN5boost6lambda...tuples9null_typeES6...
    movl  (%ebx), %edx
    movl  (%esi), %eax
    addl  $4, %ebx
    addl  %edx, %eax
    addl  $16, %esp
    movl  %eax, (%edi)
    addl  $4, %esi
    addl  $4, %edi
    cmpl  %ebp, %ebx
    jne L192
L194:
    addl  $12, %esp
    movl  %edi, %eax
    popl  %ebx
    popl  %esi
    popl  %edi
    popl  %ebp
    ret

transform 以下が別関数にまとめられるところまでは前までの例と同じだけれど, lambda 関数の処理でだいぶ混乱してしまっている。原因は boost::lambda が boost::tuple を使って引数・返値のやりとりをしていることにあるようだ。

boost::tuple は引数や返値のやりとりを柔軟に解決するための機構らしいんだけど,まだドキュメントをあまり読んでみていないので詳しい内容についてはわからない。便利そうな雰囲気なんだけれど,使用の際にはそれなりに気をつける必要があるのかもしれない。


横浜中華街

2002-07-06

020706.png

以前同じチームにいた方々とつるんで横浜方面へと遠征。「少林サッカー」なぞ観たあとに中華街へと移動。紹興酒をロックで飲みながらエビチリやら春巻やらをたんまりといただく。横浜中華街って横浜駅じゃなかったんだねえ,ってことで,また新たなスキルを習得した。横浜中華街は京浜東北線・石川町駅が最寄の駅だ。そこからは看板の通りに歩いていけばいい。

そんなわけで,久々に遠出して休日らしい休日だった日。家に帰ってから,なおも酔っ払った状態でなぜか MSX の「グラディウス2」なぞをプレイしてみたりする。なぜいまさら……。

MSX エミュレータと言えば,昔は fMSX なんかが有名だったけれど,最近は "NLMSX" がかなりいい再現度をキープしているようだ。 UI が若干寂しいのと,ステート保存機能が無いのが弱み。グラフィックとサウンドの再現度はかなりいいと思う。

http://nlmsx.generation-msx.nl/

「グラディウス2」では,カートリッジ・スロット2に "Q*bert" を挿入しておくことによって「装備のバックアップ」が可能になる。この頃コナミが良く使っていたスロット2ギミックだ。どのゲームも何故か "Q*bert" に固執していたような記憶がある。このゲームは,このチートと "UP LASER" さえあれば,前半はほとんど無敵状態だ。しかし,アルコールが入った状態で弾避けなんてできるはずもなくて,自分から弾に当たりに行っては F5 キー(コンティニュー)を連打するようなプレイだった。


2002-07-07

020707.png

突然,通販で注文していた机が届いた。在庫が無いとやらで,もう1週間ぐらいかかるのかと思っていたものだから,ずいぶん不意を突かれたような感じだった。

とりあえず机のことはわきに置いておいて,シャワーを浴びてから短パン姿で外出。一路行きつけの床屋へと向かう。前から,いつの日か超短髪ってやつを試そうと思っていたんだ。やるならば今日を置いて他にはあるまい。床屋のおばちゃんに頼んで,ざっくりと五分刈りにしてもらう。つまり丸坊主状態だ。

初めての坊主頭は,案外悪くない感じ。思ったよりも頭髪が無くなったって感覚には薄いんだけれど(爽快感がそれほど無い),これで湿気を含んだ髪がクセを帯びてうっとうしくなるようなことは無くなるはずだ。数日前から仕込んでおいた口髭と顎鬚も,既にある程度生え揃ってきている。これがもうちょっと伸びれば完成。まるで死にかけの旧陸軍三等兵みたいな風体だけれど。

あとは,明日職場で会う人達に弁明するための言葉を用意しておかなければならない。適当に,失恋したから髪を切りました,とかでいいと思う。それならば,誰もが瞬時に冗談だと解してくれるだろうからだ。

ついでに本屋に寄ってみると,たまたま Jensen 本の訳本が置いてあるのを見つけた。

http://www.amazon.co.jp/exec/obidos/ASIN/4274079503

amazon で買おうかどうか考えあぐねていたんだけれど,その場のノリで購入。まあそんなに高い本でもないし。

家に帰ってから,机の組み立てと部屋の掃除を開始した。この部屋に移り住んでから3年目になるけれど,これまで机無しでやってきたもんだから,この机が入ることによってずいぶんと部屋の雰囲気が変わるなあ,と思う。これでディスプレイの下にゴミのように敷いていたイエローページとスタイロフォームの山ともお別れだ。

せっかく机ができたんだし,そろそろ液晶ディスプレイでも導入しようかな,と思う。今は散財すべき時だ。


ていうか「スタイロフォーム」と「発泡スチロール」は微妙に物が違うってさ。

http://www.everything2.com/index.pl?node=styrofoam


Houdini 5

2002-07-08

久しぶりの出勤。社会人になってからというもの,1週間なんて休むととんでもなくダラけてしまったような気分になる。前回の仕事(正しくは前々回の仕事かな)が終わったときは,時期的に PS2 のランチと重なっていたもんだから,喜んで休みを放り投げて開発機材を触らせてもらいにいったものだけれど,今回は中だるみの時期だから,すっかり安心して休みをとっている。

SCEI (というより某K氏)の言葉を信じるならば,多分次の仕事が終わった頃に PS3 のランチが被ることになるだろうから,また次は休む暇もなく働くことになるかもしれない。もっとも,その時まで今の状態を維持していれば,という前提付きだけれど。


プロシージャ方式のインタフェースを採用していることで有名な CG ソフト "Houdini" (Side Effects) の大幅値下げが敢行されたらしい。ちょっと前の話題なんだけれど,僕が知ったのは今日が初めてだ。

http://www.cgchannel.com/story.php?story_id=719

http://www.sidefx.com/houdini/overview.shtml

正しくは値下げではなく,新バージョンとその廉価版の発表,ってとこ。従来の Houdini が $17,000 (約200万円)だったのに対して,新たにリリースされた Houdini5 のサブセット "Houdini Select" は $1999 (約24万円)で提供されるとのこと。……って,英文読み違えちゃってるのかなあ,とか勘ぐってしまうぐらいの大規模な値下げなんだけれど,実際のところどうなんだろう。ハリウッドの超プロ仕様ツールが一気にご家庭まで急降下してきてしまったような感じだ。

また Side Effects 社は Houdini 5 のランチイベントや SIGGRAPH 2002 のイベント会場にて Houdini Select の非商用向け期限付きフリーバージョンを配布するつもりのようだ。これは Maya の PLE バージョンみたいなもんだと思えばいいらしい。ただし,今の所予定されているのはイベント会場での配布のみで,ウェブからのダウンロードを開始する予定は無い模様だ。

最近,CGソフト界隈で急激なデフレが進行している。ユーザとしては嬉しい限りなんだけれど,本当に採算のあては付いているんだろうかと時々心配になることがある。多分,PCの高性能化に伴って高機能なCGソフトがご家庭でも動かせるようになっちゃったもんだから,それにあやかってコンシューマの需要を一気に取り込んでしまおうってあてなんだろうけれど……,そんなにうまくいくもんなのかなあ。そういった目論見ならば, Web3D との強力な連携を目指す "plasma" (discreet) にひとつ分があるように思える。


そういえばすっかり忘れていたけれど, Houdini (フーディーニ)と言えば19世紀の高名な奇術師の名前だ。

http://www.google.co.jp/search?hl=ja&q=%83t%81%5B%83f%83B%81...

CGソフトのネーミングとしては悪くないと思う。個人的には, "3D Studio" とか "LightWave" とか,そういう個性に薄いネーミングはあまり好きでは無い(誰もがそうだと思うけれど)。


I hate mirrors

2002-07-09

暑い日。蒸し焼きになりそう。

久しぶりに GDAlgorithms やら flipcode やらをチェック。先週は家でダレてたし,その前は修羅場で忙しかったり,で,いつもの巡回サイトをチェックしていない状態が続いていたのだ。ツケを返そう。


Pierre Terdiman 氏の "Collision detection news" より, UNC Gamma の新ネタ "Fast Penetration Depth Computation Using Rasterization Hardware and Hierarchical Refinement" 。

http://gamma.cs.unc.edu/PD/

また怪しげな研究をやってるなあ。今までのネタと比べると,デモにわりと力が入っているように思える。やたらでかい mpeg なんで,明日あたり職場でダウンロードしてチェックしてみよう……。

技術的には,今までに編み出された技の数々を複合させたような感じらしい。 "Using Rasterization Hardware" と銘打っているものの,その恩恵を受けれる部分は比較的狭いような気もする。なにより,オブジェクトをかなり無理矢理な方法で凸体に分解している辺りでかなり怪しげな匂いが漂う。むむむ。

もうちょっとちゃんと読んでみたいものだけれど,フォトンマップ本を読み終わるまではとても手を出せないな,と思う。


John Pollard 氏の "I hate mirrors" スレッド。

http://www.geocrawler.com/mail/thread.php3?subject=%5BAlgori...

鏡面画像のレンダリングにステンシルバッファを用いるのは有名なテクニックだけれど,これは「鏡の形状の『抜き』を作る」のに役立つだけで,もう1つの重要な要素「鏡面に平行な面でシーン全体をクリップする」という処理にはなんら寄与しない。実世界では鏡の向こうにあるオブジェクトが,鏡の中の世界では鏡の手前側に出てきてしまうため,そのままレンダリングするわけにはいかないのだ。

John Pollard 氏は,このポストの項目5において,これをデプスバッファのトリックによって解決するアイデアを提案している。

http://www.geocrawler.com/mail/msg.php3?msg_id=9029683&list=...

実装したことは無いので意見が欲しい,とのこと。コメントはみんなわりと肯定的だ。いけるのかもしれないなあ,と思う。


とり急ぎ必要になる予定はないんだけれど,ひょっとするとお鉢が回ってくるかもねえ,ってネタがそこここに転がっているんで,ちゃんと読まなくともメモぐらいは取っておきたいものだなあ,と思う。


Jeroen Tel

2002-07-10

朝起きると雨が降っていて驚いた。どうやら台風が来ているらしい。どうりで風が強いはずだ。


最近,懐古趣味に浸ることが多い気がする。今日は HVSC (High Voltage SID Collection) で Jeroen Tel (Maniacs of Noise) の曲を拾い集めて遊んでいた。個人的には,むしろ氏の後の活動の方に思い入れがあって, SID シーンでの活動にはあまり馴染みがない。しかし,マニアの話によれば, C64 の界隈でもそうとう名を馳せた人物だったらしい。

日本人的に親しみやすいのが,セガのゲームの移植作品の数々。

http://exotica.fix.no/tunes/archive/C64Music/Tel_Jeroen/Afte...

http://exotica.fix.no/tunes/archive/C64Music/Tel_Jeroen/Supe...

http://exotica.fix.no/tunes/archive/C64Music/Tel_Jeroen/Turb...

サンプリング音を派手に使っているものが目立つ。とは言っても, SID にはファミコン (pAPU) の DPCM のようなものが積まれていたわけでもなく,ボリュームレジスタを高速に更新することによって擬似的に PCM を再現するという単純かつ力技な方法をとっていたらしい。

http://www.joogn.de/bin/6581.pdf

SID - "The Sound Interface Device" こと MOS 6581 の仕様書を見てみると,矩形波のパルス幅を限界値に設定することによって DC 波を出力することができる,との記述がある。その状態でボリュームレジスタを高速更新すれば,力技とはいえほぼ完全な PCM が実現できるのではないかと思う。 SID のボリュームアンプは 4bit 幅の指定が可能だから,がんばれば 4bit PCM が使用可能ということだ。実際 1/2/4bit PCM がよく使用されていたらしい。

ただし,この方法は CPU に実に重い負荷を要求することになる。上の楽曲群でも,タイトル曲にはわりと派手にサンプリング音が使用されているんだけれど,ゲーム中の挿入曲にはほとんど使用されていないのが分かる。ゲーム中に使うことができるほど軽い処理ではなかったってことなんだろう。

Jeroen Tel 氏はコンポーザ/オペレータとしての仕事を数多く請け負いつつ,独立したミュージシャンとしての活動も活発に行っていたようだ。 "Remark" と名付けられた楽曲群は,おそらく C64 のデモのために作られた作品だと思われる。

http://exotica.fix.no/tunes/archive/C64Music/Tel_Jeroen/Rema...

http://exotica.fix.no/tunes/archive/C64Music/Tel_Jeroen/Rema...

SID 曲を続けて聴いていると,アルペジオ(分散和音)を多用している曲が非常に多いことに気付く。てっきり SID にアルペジオ機能かなんかが付いているのかと思っていたんだけれど,どうもそういうわけではないらしい。単に周波数を細かく更新しているだけのようだ。海外の作品だとファミコンでもやたらアルペジオを使用しているし,国民性というか向こうの文化としてそういうものがあったようだ。日本の作品ではほとんどアルペジオが使われなかったのと比較すると,対照的で面白いなあと思う。向こうは和音重視ってことなのかな……。

活動も後半期(80年代後半から91年ぐらいまで)にもなると,かなりテクニックが冴えてくる。 "Navy Moves" の音の厚みなどには,いまさらながら驚かされるものがある。

http://exotica.fix.no/tunes/archive/C64Music/Tel_Jeroen/Navy...

"Robocop3" は,単純に楽曲がお気に入り。

http://exotica.fix.no/tunes/archive/C64Music/Tel_Jeroen/Robo...

他にもお気に入りをいくつか。ここら辺のポップな曲調は,後の氏の芸風に繋がるものがあるなあ,と思う。

http://exotica.fix.no/tunes/archive/C64Music/Tel_Jeroen/Acce...

http://exotica.fix.no/tunes/archive/C64Music/Tel_Jeroen/Rubi...

http://exotica.fix.no/tunes/archive/C64Music/Tel_Jeroen/Tint...


ちなみに使用したプレーヤは "sidplay2/w" 。現状, Windows 上で動く SID プレーヤの中で,再現度と使いやすさの面で最も優れているプレーヤだと思う。

http://www.student.nada.kth.se/~d93-alo/c64/spw/


PRT Rendering

2002-07-11

020711s.png

狩野さんが Peter-Pike Sloan の "Precomputed Radiance Transfer" を元にしたデモを作成しているようだ。ゲストブックでこっそりと(?)公開されている。

http://cgi3.tky.3web.ne.jp/~tkano/cgi-bin/bbs.cgi

なんていうか,当の SIGGRAPH が開催される前に(確か今月末だったはず)ここまでやってしまうとは……,なんとも恐ろしい世界だなあ,と思った。

まだセルフシャドウのみ対応で,相互反射については今後の改良で,とのことだけれど,セルフシャドウだけでもかなり面白い効果が出ていると思う。やわらかな陰の表現がオブジェクトの造作に深みを持たせている。スタンフォードうさぎもこんな凄みのある容姿になってしまった。

なんにしろ,今後の発展に期待。やっぱり,相互反射でどのくらい見た目が向上するか,だなあ。ランタイムのコストは変化しないわけだから,実際の応用場面では相互反射を適用した状態が基本になるんだろうと思う。


スタンフォード大と言えばウサギ,ならば,コーネル大と言えば「箱」だ。「コーネル大の箱」 - "The Cornell Box" として知られるあの有名なモデルは,80年代後半にコーネル大で物理モデルCG生成の研究が盛んだった頃,実世界におけるモデルの実測値と生成された画像との間にある差異を測定するために考案されたものであるらしい。コーネル大のウェブには,ちゃんとこの "Cornell Box" についての解説ページが用意されている。

http://www.graphics.cornell.edu/online/box/

驚いたことに,ごく初期の Cornell Box には箱が配置されていなかったらしい。

http://www.graphics.cornell.edu/online/box/history.html

ほんとうにただの箱部屋だ。

「比較」のページでは,実測値と生成画像の比較検証を行っている。これにより,物理モデルがほぼ正しい結果を導き出していることが証明されている。

http://www.graphics.cornell.edu/online/box/compare.html

ちなみに "Stanford Bunny" の解説ページはこちら。

http://www.gvu.gatech.edu/people/faculty/greg.turk/bunny/bun...

> ……その店の棚にはウサギの置物がたくさん並べられていた。そのとき僕は
> レンジ・スキャンの研究のことを思い出したんだ。このウサギは大きさも形
> も素材も,レンジ・スキャンにちょうどおあつらえ向きのように見える。そ
> こで僕はこれをひとつ買うことにした。このモデルがこんなにも有名になる
> と知っていたら,もっとたくさん買ってたんだけどね。

このページの主こと Greg Turk 氏が Stanford Bunny の生みの親だ。 Stanford Bunny と呼ばれているのは, Greg 氏がスタンフォード大の Graphics Lab に在籍していた時にこのデータを作成したから,ってことらしい(Greg 氏は現在ジョージア工科大に在籍している)。


Tour de Frace

2002-07-12

020712.png

明日は WHF (ワールドホビーフェア)のお手伝いをする予定。早朝から作業が始まるため,前日から近くのホテルへと移動することになった。この職業で出張することなんてめったに無いもんだから,ホテル泊まりなんてそうとう久しぶりのことだと思う。

夜の幕張は,人の気配が妙に薄くて寂しいところだ。下手に土地が拓けているだけに,かえって人気(ひとけ)の無さが強調される。道端のバスケットコートに 3-on-3 に勤しむ高校生の一団が居て,まあ,人の存在が感じられるものと言えばそのくらいのもの。片側2車線の広い道路に沿って,とぼとぼとホテルに向かって歩いていった。

明日に備えて早く就寝。久しぶりにテレビなんて点けてみてところで特に見るものがあるわけでも無しに(「スターウォーズ・エピソード1」なんてやっていたけれど,さ……)何気なく J-Sky TV のツール・ド・フランスの中継なぞを見ながらベッドに寝転がってみた。

以前から薄々感じていたんだけれど,団体戦の自転車レースはとても奥が深い。

http://homepage2.nifty.com/dennis/tour2001/fun.htm

http://homepage2.nifty.com/merge/mess/cycle.htm

自転車レースと他のレース競技を比べた場合に特色としてまず挙げられるのが,先頭を走る(単独で走る)ことに非常に大きなリスクが伴う,という点。このことが自転車レースに対して大きな戦術性をもたらしているように見える。

単独で走行すると空気抵抗の影響をもろに受けるため,個人が瞬間的にリードを作ったところで,じきに再び集団の中に飲み込まれてしまう。集団は先頭を交代しながら走行するため,常にトップスピードで走りつつ体力を温存することが可能だからだ。

しかし,単独で抜け駆けすることは不可能でも,数人の小集団を形成すればリードを保つことも可能になる。ここで,敵同士での高等な駆け引きが発生する。たとえ敵同士でも利益があると見れば一時的な協調関係が成立し,大集団から分離された小集団が形成されるのだ。

レース中継を見ていてまず目に付くのが,少人数の先頭集団が互いに先頭を譲り合いつつ走行する映像だ。空気抵抗の影響を受ける先頭は誰もが走りたがらないため,先頭を二番手に譲っては最後尾に付くという行動を全員で繰り返しているのだ。その姿はさながらキャタピラのようでもある。

このように「他の選手を引き離して先頭を走ること」が勝利条件あるにも関わらず,レース中ではそれがリスクに様変わりする,という背反性が,自転車レースに対して独自の要素を与えている。これに対して,例えば一般的なモータースポーツでは,先頭をキープすることが試合を優位に進めることに繋がるため,ひとたび順位が堅くなってしまうとなかなかレースに変化が出にくいという側面がある。自転車レースでは,それとはまったく逆のことが行われているというわけ。

とかなんとか考えていたら,わりとあっさりと眠れた。


WHF

2002-07-13

朝から夕方まで WHF (ワールドホビーフェア)のお手伝い。とにかくものすごい来客の量に圧倒される。てっきりゲームショーみたいなのを想像していたものだから,この人の多さにはまったくもって面食らった。最も混雑していた時間帯では,通路を普通に歩くことさえもままならないほどだった。もちろん会場は尋常じゃない熱気で満たされている。メッセの空調なんてとても間に合わない。どんどん体内の水分が奪われていく。下手すると倒れる人も出るでしょこれは……。しかし子供は元気だなあ。

これだけの人数が集まれば,いろんな個性を持ったお客を相手にすることになる。例えば,とにかくわがままなお子様,人の話を聞く意志が全く見られない親子,悪態を吐く子供,信じられないほどゲームの下手な女の子……等々。まあ,そんな感じの難敵を相手にすることが何度かあったものの,大方において,たいていのお子様はちょっとわがままで,それでいて素直な存在。説明すればちゃんと従ってくれるし,ひとたび面白さを見出せばとたんに夢中になってしまう。周囲のテンションの変化に敏感で,盛り上がっているところでは盛り上がり,盛り下がっている所には寄り付こうともしない。同じ人間なのはもちろんのことだけれど,その行動様式にはちょっと特殊な点が見られるようだ。

やはり最も人気があったのは,なんといってもマリオ。60分待ちぐらい当たりまえって状態だったようだ。隙あらば僕もプレイしてみたいなあ,なんて思っていたのだけれど,こんなに忙しい状況じゃ,とてもそんなこととてもやっていられなさそうだ。そもそも,お子様のためのイベントなのに,その中に大人が並ぶなんで犯罪じゃん,って感じ。

そしてやはり,あのイベントの中で最も努力していたのは,子供に同伴する親御様たちではないかと思う。うちらは商売でここに来ているわけだし,暑くたっていくらでも働くけれども,子供のために自らを犠牲にしてまで,こんな暑くて混んでてくたびれる所に来ている親御様たちは,本当に偉いなあと思った。


Flower, Sun, and Rain

2002-07-14

020714s.png

昨日がやたら忙しかったもんだから,今日は気が済むまで寝ていることにした。今日が WHF の割り当てだった人たちは,今ごろ会場で四苦八苦していることだろう。話によると土曜よりも日曜の方が来客数が多いとのことなんで,僕が経験したものよりももっとすごい状況に身を置いているのかもしれない。なんにしろ,二日ともフル出勤だった担当の方々はほんとにご苦労さまだ。

そんなわけで,まったりと家で休みながら,ひさしぶりにPS2でゲームなぞしていた。タイトルは grasshopper manufacture の「花と太陽と雨と」。かなり古いゲーム(PS2の初期タイトルの1つ)なんだけれど,職場の人から借りっぱなしだったのを思い出して,暇があるうちにプレイしておこうと思ったわけ。それに,今日みたいに脱力気味な日には,こんなまったりとしたゲームがもってこいだ。

http://www.grasshopper.co.jp/flower/

ゲームの内容は,ごく普通のアドベンチャーゲーム。とは言っても内容は極めて一本道に近い形態をとっているんで,「ビジュアルノベル」だかなんだかって言った方が的を得た表現なのかもしれない。いざとなれば総当りで全てが済んでしまうような内容のゲームだ。このゲームの独特なギミックになっているはずの「暗号解読」って要素も,その実体はちょっとした数字遊びみたいなもんで,それほどゲームっぽい色を与えるものではない。

このゲームのスタイルは,センスのいいムービークリップと,センスのいい音楽と,軽くてリゾートな雰囲気と,全体的に軽快で時にはアホらしく展開するテキストにのせて,ぼんやりとビジュアルを楽しむ,ってとこ。まったりと暇を潰す分には,こういうのもありなんでないの,と思う。クラシックの名曲のスムースなアレンジに乗せて,黒スーツの男がリゾートを駆けずり回りながら,夢なんだかなんなんだかわからない経験を繰り返す,そんな謎な雰囲気のゲームだ。


オープンソース・ライセンス

2002-07-15

最近,職場の空調が狂ったような温度設定になっていることがある。今日も何気に寒さを感じたので空調の設定を見に行ったところ,22度に設定されていた。あんた従業員を凍え死なすつもりか……。おかげでなんか喉が痛くなってきた気がする。げほげほ。


個人的な趣味からか,もしくは職業柄から来る習性なのか,よくわからないけれど,とにかく,オープンソースのツールやらライブラリやらを集めてきては,適当にいじくってみたり,勝手に文句をつけてみたりとか,そういった他愛もない遊びを延々と繰り返しているような気がする。

そんな繰り返しの中で,まれにライセンスの問題で頭を悩ますことがある。一般にオープンソースと呼ばれているソフトウェアにおいて,果たしてそのどこからどこまでがオープンなのか,という問題は,多くの場合非常に曖昧な要素を含んでいるように見える。特に仕事と関連付ける場合には,否がおうでも気にしなければならない問題だ。


いっそのこと GPL ならば,すんなり諦めも付くというものだ。 GPL から派生したものには全て GPL を適用することが義務付けられているのだから,もはや議論の余地などない。

http://www.gnu.org/licenses/gpl.html

http://www.opensource.jp/gpl/gpl.ja.html

GPL が侵蝕的な性質を持っているのに対して, LGPL は比較的緩やかな制限であると言われている。しかし実際には,その条件はかなり厳しいものであるようだ。

http://www.gnu.org/licenses/lgpl.html

http://www.debian.or.jp/~mhatta/lesser.ja.txt

LGPL は基本的に GPL の性質を継承したライセンスだ。ただし,本体となるソフトウェアと LGPL によってライセンスされるソフトウェア(ライブラリ)がある条件に沿った状態で協調する場合のみ,本体を非 LGPL でライセンスすることが可能となる。この条件を成立させるには幾通りかの方法があるんだけれど,最もありふれた組み合わせを要約するならば,このようなものになるらしい。

1. 然るべき方法によって著作権表示を行うこと。
2. LGPL な部分は,実行時にダイナミックリンクされること。
3. ダイナミックリンクされる部分が,入れ換え可能な状態であること。

この(2)の条件がわりと微妙で, Windows や Linux ならば DLL や共有ライブラリを使用することによってこれを実現することも可能だけれど,コンシューマゲーム機のような環境では,この条件をクリアすることはほぼ絶望的だろう。とどのつまり,仕事で LGPL に手を出すことは避けた方がいい,ってことになるらしい。


ところで, GNU の標準 C ライブラリである "GNU libc" (glibc) は,ライセンスに LGPL を採用している。

http://www.gnu.org/software/libc/

だから,例えば Linux 上で glibc をスタティックリンクしたソフトウェアは問答無用で LGPL を適用しなければならないし,共有ライブラリを使用してダイナミックリンクしたとしても,ちょっと気をつけなければならない事がいくつかあるようだ。

このような理由からか,組み込み用途などでは glibc の代わりに "newlib" を使うことが多いようだ。

http://sources.redhat.com/newlib

newlib は Redhat が管理を行っている標準 C ライブラリで, BSD ライセンスなどように比較的制限の緩いライセンスが適用されたソフトウェア群を中心として構成されている。組み込み用途をはじめとして,コンシューマゲーム機の標準ライブラリなんかでも使われることが多いみたいだ。

このように glibc が嫌厭されている状況を反映してなのか, GNU の標準 C++ ライブラリである "GNU libstdc++" (libstdc++-v3) には,ある特記事項が加えられている。

http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/license.htm...

> As a special exception, you may use this file as part of a free software
> library without restriction.  Specifically, if other files instantiate
> templates or use macros or inline functions from this file, or you compile
> this file and link it with other files to produce an executable, this
> file does not by itself cause the resulting executable to be covered by
> the GNU General Public License.  This exception does not however
> invalidate any other reasons why the executable file might be covered by
> the GNU General Public License.

つまり,実行形式を作るために使用する限りにおいては, GPL に捕われなくてもいいよ,ってことだ。これは libstdc++ を使用したソフトウェアに対して,ほぼ無制限の使用許可を与えるものになる。


GPL とは逆に,制限が緩やかなゆえに悩ましい問題もある。 BSD ライセンスは最も緩やかなオープンソース・ライセンスの一つとして有名だけれど,僕にはその解釈がとても難しいもののように思えてならない。

> 1. Redistributions of source code must retain the above copyright
> notice, this list of conditions and the following disclaimer.
>
> 2. Redistributions in binary form must reproduce the above copyright
> notice, this list of conditions and the following disclaimer in the
> documentation and/or other materials provided with the distribution.
>
> 3. Neither the name of the (ORGANIZATION) nor the names of its
> contributors may be used to endorse or promote products derived
> from this software without specific prior written permission.

これを要約すれば

1. ソースの配布にはコピーライト表記が必要
2. バイナリの配布にもコピーライト表記が必要
3. 作者の名前を勝手に利用することはできない

となるだろう。ここで問題となるのが, BSD ライセンスが適用されたライブラリをあるアプリケーションからリンクして使用した場合,そのアプリケーションの配布の際にコピーライト表記は必要になるのか,という点だ。上の(2)の項目を最大限に解釈するならば,アプリケーションにも表記は必要なように思える。しかし,実際にそうしている例は,僕の知る限りでは存在しない。


この辺りの問題は,ただ法律に詳しい人に聞けばいいというわけでもないので,余計に悩ましい。オープンソースの概念と,その周辺の現状を把握している人でないと,正しい解釈を下すことは難しいだろうからだ。


スクリーンセーバをちょっと

2002-07-16

うー,やっぱちょっと風邪っぽい……。


たまに趣味で作っている実験的なプログラムなどを何らかの形で作品に昇華できんものかなあ,という目論みを実現させるための手段として,いわゆる OpenGL スクリーンセーバってやつを検討してみることにした。

まずは適当なフレームワークを求めてウェブ探索。スクリーンセーバのフレームワークライブラリなんていくらでもありそうなもんなんだけど,これが意外と見つからない。ううむ。

とりあえず見つけた単純そうなのが,これ。

http://www.ite.mh.se/~danli97/opengl/

次にこれを MinGW でビルドできるようにしなければならない。ソースについては,特殊な API や MFC を使っていない限りは,そのまま g++ でコンパイルが通る可能性がある。実際,このプログラムについてはほぼ問題なくコンパイルすることができた。

リソースファイル (*.rc) については cygwin に付属の windres.exe を使用することになる。

windres.exe -o hoge.res -O coff hoge.rc

こんな感じで OK だ。ただし, VC++ のリソースエディタなんかで作成したリソーススクリプトは,たいていの場合 "afxres.h" を要求してくる。このファイルは cygwin にも MinGW にも含まれていないので,自力で調達してくる必要がある。 VC++ からパクってくるのもいいけれど,今回のように簡単なリソースならば,以下のような単純な内容でも問題無く代用することができる。

#include <windows.h>

場合によっては IDC_STATIC の定義を追加する必要もあるかもしれない。

#include <windows.h>
#define IDC_STATIC -1

まあどうせダイアログなんて真面目に作らないだろうから,アイコンの定義だけ残してあとは全部削除してしまうのもアリだと思った。設定なんて ini ファイルに書きゃいーよ,みたいな感じで。


とまあ,これをビルドするところまではできたんだけど,できればマルチスレッドにしたいし,少なくともタイマ関連は用意しないとタイミングがねえ……,とか,必要なものを見積もってみると,やっぱりぜんぜん足りない気もする。どうしたものだろう……。


path tracer

2002-07-17

020717s.png

通勤中の常読書となりつつあった Jensen 本(日本語版)を,とりあえずひととおり読み終えることができた。中盤からだいぶ流して読んでいたりしたから,正確に理解するにはもう何回か読み直してみる必要があるかもしれないけれど,だいたいどんな内容なのか把握することはできたつもりだ。

翻訳の質については,個人的にはかなりいいレベルなんじゃないかなあ,と思っている。訳について疑いを持つような個所は無く,豊富な訳注と加筆された章のことを考慮すれば,むしろ原著よりも価値は高いのではないかと思うほどだ。思わず自分の英語読解力の無さを痛感してしまうくらい,快適に読み進めることができた(原著を読むときはあんなに苦労していたのにね)。

一応フォトンマップを題材にした本ということになっているけれど,3章までは一般的な物理モデルと大域照明に関する解説書となっている。これらの概念について詳細に解説した書籍って,少なくとも僕はいままでに見たことが無い。そういった側面からも評価しても,非常に貴重な書籍なのではないかと思う。 RTR ("Real-Time Rendering") と対をなす書として座右に置いておこう。


んでまあ,せっかく読み終えたんだから,何か作ってみようと思う。気の抜けた path tracer ぐらいだったらすぐに作れるかもなあ,ってことで,簡単に作ってみることにした。その結果が上の画像。

左は無限平面の上に球が置いてあるだけのシーン,右は球の横三方を壁で囲んでみたシーン。交差判定処理をきちんと作るのがめんどくさかったので,平面と球体しか扱えていない。基本的にモノクロのみの対応で,マテリアルも純粋な拡散反射面だけ。光源に至っては一様な天球しかサポートされていないという手の抜きよう。それでも,なにげに大域照明っぽい表現ができているから不思議だ。ソースは現段階で300行ぐらい。意外とそんなもんでできるんだなあ……。

path tracing では,1ピクセルあたりに使用するパス数と,生成画像の誤差(ノイズ)との間に厳しいトレードオフが発生する。例えば,上の画像では1ピクセルあたり300パス使用している。つまり,1ピクセルレンダリングするのに300本ものレイを飛ばしているわけで(しかもそれが拡散反射によって反復される),単純なレイトレーシングと比べるとずいぶんと重いものとなっている。まあ,レンダリングで待たされる感覚ってのも,なんか懐かしくて,たまにはいいもんかもしれない。

とりあえずフォトンマップとか,ちゃんとした交差判定とか,そこら辺は置いとくとして,しばらく path tracing をいじくって遊んでみようと思う。


MSYS

2002-07-18

020718.png

最近 GDAlgorithms にぜんぜんポストが無くて寂しい。それとも Geocrawler がイカれちゃってるのかなあ。普段でも Geocrawler はちょくちょくメンテで止まってたりするんで(向こうでは深夜にメンテしているつもりでも,それはこちらでは真っ昼間のことだ),読むだけにしても一応リストに参加しておいたほうがいいのかもしれない。

http://www.geocrawler.com/lists/3/SourceForge/4856/


普段,画像ファイルの扱いには DevIL (OpenIL) を使うようにしている。昨日の実験プログラムなんかもそうだ。

http://openil.sourceforge.net/

これを Windows でも動くようにしようと思って MinGW でのビルドに挑戦したんだけれど,これがいまいちうまく行ってくれない。どうやら,シェルをはじめとする実行環境のほとんどを Cygwin に頼っているのがいけないみたいだ。 configure スクリプトが MinGW と Cygwin をごっちゃに検出してしまっているように見える。うーむ,こりゃだめかも。

そこで,以前からちょっと興味を持っていた "MSYS" を試してみることにした。

http://mingw.sourceforge.net/msys.shtml

MSYS は,わりと最近登場した MinGW スイートの一部で, bash や textutils, m4 プリプロセッサなど, configure スクリプトを動作させるために最低限必要となるツール類だけを集めたパッケージだ。 rxvt や vi も付いてくるので,これを入れれば Windows 上でちょっとしたシェル環境が動くようになる。

さっそく MSYS-1.0.7-i686-2.exe をダウンロード。うーむ,さすがに "Minimal System" と名乗るだけのことはあって,本当に最低限のものしか含まれていないようだ。

~>cd /bin
/bin>ls *.exe
basename.exe  diff.exe     gzip.exe      md5sum.exe  sed.exe    true.exe
bash.exe      diff3.exe    head.exe      mkdir.exe   sh.exe     uname.exe
bzip2.exe     dirname.exe  id.exe        mount.exe   sleep.exe  uniq.exe
cat.exe       env.exe      install.exe   mv.exe      sort.exe   vim.exe
chmod.exe     expr.exe     less.exe      od.exe      split.exe  wc.exe
cmp.exe       false.exe    ln.exe        patch.exe   tail.exe
comm.exe      find.exe     ls.exe        ps.exe      tar.exe
cp.exe        fold.exe     m4.exe        rm.exe      tee.exe
cut.exe       gawk.exe     make.exe      rmdir.exe   touch.exe
date.exe      grep.exe     makeinfo.exe  rxvt.exe    tr.exe

たしかにこれだけでも configure は動くんだろうけど, perl ぐらい入れておかないと何かと面倒なことになりそうな気がする。自分で autoconf とか使いたくなった場合はどうするんだろう……。

とりあえず vim でもビルドしてみるか(MSYS に付属の vim はバージョンが古いのだ)と,挑戦してみるものの,これがなかなかうまく行ってくれない。確かに configure は通るんだけれど,コンパイルの段階でだいぶ苦労することになる。いろいろとシステムコールが足りていないみたいだ。

/mingw/include> find . -name 'wait.h' ¥
> -or -name 'pthread.h' -or -name 'termios.h'

/mingw/include> find . -name '*.h' -exec grep fork {} ¥;

/mingw/include>
...

termio も curses も無いとなると,ターミナル操作にはかなり制限が付きそうだ。それに pthread どころか fork さえも使えないとなると,「UNIX に近い環境」って言い張るのも難しいと思う。

結局のところ,現状の MSYS では, MSYS だけでなんとかするっていう方針を貫くのは難しそうだ。やはり, MSYS の使用は「どうしても configure を使いたい」って場合のみにとどめておいて,普段は Cygwin と MinGW を混在させて使うという,従来通りの方法でしのぐのが無難なのかもしれない。


あんま関係ないんだけれど, sourceforge.net の短縮系として sf.net ってのが使えるのをはじめて知った。例えば, "tcl.sourceforge.net" だったら "tcl.sf.net" で代用することができる。

http://tcl.sf.net/

sourceforge 関連サイトには URL 直打ちで行くことが多いから,これは大いに役に立つだろうと思う。


マリサン

2002-07-19

今日はマリオサンシャインの発売日。ちょうど合わせたかのように,小学生達は明日から夏休みに突入だ(ていうか合わせたんだろうなあ)。今日は終業式を終えた子供たちでゲームショップは賑わっているのかもしれない。僕はと言えば,初回は品薄との噂もあったので,無理せずとも職場のGCで見れればそれでいいかなあ,とか思っていたんだけれど,タイミングを計ったかのように職場のGCが紛失されるという事件が発生。結局,自腹でGC本体とソフトを購入することになってしまった。まあ,いいけどさあ……。

ゲームの方は,やはりさすがに面白い。これだけやり応えのあるゲームだと,夏休みを暇で持て余している子供達にはぴったりのプレゼントになるんだろうと思う。ていうか僕の感想なんてどうでもいいから,なによりもまず,子供達の感想を聞いてみたいなあ,と思う。この難易度が彼らにどう受け入れられているのかが,最も興味のあるところなんだけれど。


もうちょっと MSYS をいじってみる。当の MSYS はどうやってソフトウェア群をビルドしているのかと疑問に思って MSYS のソースをダウンロードしてみると, newlib やら何やらを組み込むことで標準ライブラリに足りない部分を補強しているみたいだ。ふーむ……。

http://sources.redhat.com/newlib/

とりあえず newlib をダウンロードしてビルド。なんか README に書かれている方法(別のディレクトリで configure しろとか書いてある)ではうまくいかないんだけど,適当に newlib ディレクトリの中で "configure && make" してしまえば問題ないようだ。ただし, MinGW がデフォルトで立ててしまうマクロ "WIN32" が条件コンパイルに悪影響を与えてしまうようなので,環境変数 CFLAGS に "-UWIN32 -U_WIN32" を加えた。まあその他は,ほぼ問題無し。


とか色々やってみたんだけれど……,やっぱりどうにもうまくいかないや。それに,システム導入の度にこんなこと繰り返していたんじゃ,ひどくめんどくさくてしょうがない。

それで,苦し紛れに Cygwin の方を調べていると,偶然, Cygwin でも gcc のバージョンとして gcc-3.1 を選択できるようになっていることを知った。

http://sources.redhat.com/cygwin/packages/gcc/

あー,それだったら,もとより MinGW を使わなくても Cygwin ベースでいけばいいんだよな。それで,何か配布したいものを作る場合には,しょうがないから何とかして MinGW を使う方法を考える,と。なんか,それでいい気がしてきた。

ちなみに, Cygwin から生成したソフトウェアを配布する際に問題になるのは, POSIX レイヤのエミュレーションを担っているライブラリ "cygwin1.dll" が GNU のコードを部分的に含んでいるということ。つまり Cygwin システムとリンクされる実行形式は GPL の「汚染」を受けてしまい,その配布条件も GPL に従わざるを得ないという強力な制約が付きまとうことになるのだ。

http://cygwin.com/licensing.html

そうでないとしても, cygwin1.dll は十分に大きな dll なので,これを配布パッケージの中に含めるのは避けたい,という理由もある。まあ,ここら辺は何かと MinGW の方が都合がいいってわけ。


なにげに Cygwin の FAQ を眺めていたら fork() に関する項目があった。

http://cygwin.com/faq/faq_4.html#SEC76

うーん,なんだかややこしいことやってるんだなあ。 UNIX ではごく普通に使われている fork() だけれど,確かにその仕様はなんだか巧妙なトリックみたいで,ちょっと原始的なものを感じさせられる。今だったら,こういうのにはスレッドを使っておいた方が無難だろうな。

MinGW には pthread.h が無いため Win32API でスレッド操作を行う必要があるみたいだけれど, "POSIX Thread (pthreads) for WIN32" を使えば MinGW でも移植性の高い POSIX Thread API を使うことができるかもしれない。

http://sources.redhat.com/pthreads-win32/

必要になったら試してみようと思う。今はまだ必要じゃないから試さないけど……。


久しぶりに

2002-07-20

何もなく平和な休日。夕飯を調達しに歩く路の途中で,ふと鰻の焼ける匂いが漂ってきて,猛烈に食欲中枢を刺激された。そうか,今日は土用の丑の日なんだな……。既にその鰻屋には行列が出来ている模様。さすがに並ぶ気にはなれなくて,ただその場を後にした。

http://www.google.co.jp/search?q=%93y%97p+%89V+%95%BD%89%EA%...


久しぶりに地元のゲーセンに入ってみた。

そこはわりと大きめのアミューズメント施設なんだけれど,ここ数年でひどく様変わりしているように見える。最近の傾向として,いわゆるテーブル筐体もののゲームが徐々にスペースを失ってきており,今日などは「バーチャ4」と「バーチャロンフォース」を残して他の筐体は目立たない奥の方に追いやられてしまっていた。代わりに配置されているのがメダルゲームやプライズゲームの類。メダル式のパチンコとスロットがかなりのスペースを確保しているのは,なんか不思議な感じだ。すぐそばにパチンコ屋があるのにね……。

そんな状況で特に人気があるみたいなのが,競馬シミュレータをはじめとする大型筐体系のゲームだった。その多くが競馬やオートレースなどギャンブル系のスポーツをモチーフにしているのに対して, "WORLD CLUB Champion Football" はサッカーチームの育成をテーマにした珍しいタイプのゲームだ。

http://www.hitmaker.co.jp/game/Champion_Fb/home.html

このゲームを観察していてまず目に付くのが,トレーディングカードをボードの上に配置することで戦術の操作を行うという特殊なインタフェースの存在だ。カードに特殊な機構が組み込まれているらしく(磁気かなあ),ボード上での配置操作がゲーム内の状態に反映されるようになっている。

http://www.hitmaker.co.jp/game/Champion_Fb/site/game_rule03....

ギャラリー用モニターがやたら雰囲気出てたりして面白い。こういった演出が人目を誘うんだなあ。「ダービーオーナーズクラブ」に続く人気作になりそうな感じ。こういったゲームは比較的狭い層をターゲットとしているように見えるんだけれど,それをがっちりと囲い込む魅力を持っていることが人気の秘密なのかもしれない。


他に人気があったのが,コナミの「麻雀格闘倶楽部」。

http://www.konami.co.jp/am/mfc/

若い女性客から「いかにも」な感じのおっちゃんまで,多彩な客層を取り込んでいるようだった。特に変わった仕掛けのあるゲームでもないらしいんだけれど,雰囲気作りが上手いのかなあ,ギャラリーなんかもいたりして,人気はかなり出ているようだった。ところで,こういうゲームは,さすがにギャラリーモニタとか作るわけにはいかんのかね。

あと,何気に面白そうだったのが,これもコナミの "Monster Gate II" 。

http://www.konami.co.jp/gm/medal/project_team/m_gate/

メダルゲームと「ローグ」(ていうか「トルネコ」って言った方が近いか)を融合させたようなゲームで,クリア時のポイントがメダルとしてペイバックされる,というもの。確かにあのゲームの性質 − 反復してプレイさせることができること,ゲームが1回ごとのやり切りタイプであること − はメダルゲームとの組み合わせに向いているのかもしれない。

また,「ローグ」では「生還する」という最終目標に実はそれほど実質的な価値が無い(極端な話,あの手のゲームに死亡以外の終了条件が必要なのかどうかも疑問だ)のに対して, "Monster Gate" では,生還することによってメダルが配当されるという「見返り」が付加されるようになっている。これはなかなか面白い要素だと思う。

これによってゴールだけが最終目標ではなく「途中で脱出する」という選択肢も考えられるようになった。死亡すると全ての投資を失ってしまうのに対して,脱出を選択することによってとりあえず現時点での配当を回収する,という戦略が生まれるわけだ。もちろん,ゴールした場合の見返りはそれ以上のものになるから,ここで一種の損得勘定が発生することになる。

他のプレイヤーが支配する城に挑戦する「対戦ゲーム」もなんだか興味をそそられる。とりあえず今日は見てるだけでプレイしなかったんだけれど,いつか試しに挑戦してみたいゲームだ。


LCD

2002-07-21

020721.png

なんとなく新宿にお出かけ。ヨドバシカメラで液晶ディスプレイを購入する。

http://www.sharp.co.jp/products/llt1620/index.html

同じ値段で17インチ液晶とか,ちょっと頑張れば18インチも買えちゃうような感じなんだけれど,あまり安物を買うのも危険だしねえ,ってことで,あえてコストは無視した製品に手を出してみた。スリムなボディと,本体前面がほとんど表示領域っていうコンパクトなデザインがポイント。あと,2系統入力付きってのも重要だ。 XRGB でもってゲーム機を繋ぐからね。

家に持って帰って早速セットアップ。どうやらドット欠けの無い製品が当たったみたいだ。うむ。最近はドット欠け率も下がってきたと聞くけれど,あいかわらず保証外だから油断できない。

ところで,この製品はヨドバシのポイントサービスが13%付く製品だったので,約8万円×0.13で……実質1万円のキャッシュバックとなるようだ。うひい,ゲームソフト1本ぐらいタダで買えちゃうな……。これだからヨドバシは人気あるんだ。たとえ近場の電器屋で売ってたとしても,わざわざヨドバシまで行って買い物をするようになっちゃうんだよね。


そんなこんなで,当面は Cygwin 環境をベースに戻すことにした。その Cygwin 環境も,いろいろ実験している間にごちゃごちゃしてしまった感じがあるので,思い切って素の状態から再インストールしてみようと思う。

http://sources.redhat.com/cygwin/

Cygwin の setup.exe を実行すると,昔はデフォルトでいろいろと勝手にインストールされたような記憶があるんだけれど,最新の setup.exe では最低限の実行環境しかインストールされないような設定になっているみたいだ。 gcc さえも除外されているので,手動でポチポチと必要なパッケージを選択していく。 rxvt や python ,あと計算機代わりに bc とかも入れといたほうがいいなあ。 libpng とか realine などのようなライブラリも適当に選択しておく。 fortune なんかも入れておくといいかもしれない。

次に, Cygwin に含まれていないソフトウェアを自前でインストールしていく。例えば nkf なんかがそれだ。

http://www.google.co.jp/search?q=nkf+kanji

最後に,開発に使うライブラリ群をビルド。最近はもはや必須になりつつある boost, tvmet, DevIL, GLFW など。ここら辺はほぼ問題無し。


ところが, DevIL の最新版 (1.6.5) をダウンロードしたところ,ファイルが足りなくてビルドに失敗してしまう。ううむ,作者が慌てていたのかなんか知らんけれど,とにかくヘッダファイルがひとつ (ilu_region.h) 足りていないようだ。これは CVS リポジトリから手動でダウンロードすれば解決できる。

http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/openil/DevIL/...

もう一つ見つけたのが, Cygwin 上で DevIL をビルドすると謎のバグが混入するという問題。これは,古いバージョンの Cygwin のために用意された条件コンパイル文が,最新の Cygwin では仇となってしまうというもののようだ。なので,適当にソースを削ってやることで対処できる。

--- il_internal.c.old   2002-07-22 03:14:44.000000000 +0900
+++ il_internal.c   2002-07-22 03:15:01.000000000 +0900
@@ -22,6 +22,7 @@
/* Siigron: added this for Linux... a #define should work, but for some reason
   it doesn't (anyone who knows why?) */
 #if !_WIN32 || (_WIN32 && __GNUC__) // Cygwin
+#if 0
    int stricmp(const char *src1, const char *src2)
    {
        return strcasecmp(src1, src2);
@@ -30,6 +31,7 @@
    {
        return strncasecmp(src1, src2, max);
    }
+#endif
 #elif _WIN32_WCE
    int stricmp(const char *src1, const char *src2)
    {

ふーむ。これでやっと pathtrace.exe が Windows 上で動くようになった。やっとここからが本番だ。


Not Twice the Same Color

2002-07-22

家のディスプレイを LCD にしてからというもの,職場の CRT がどうにも点滅しているような錯覚に陥ってしまって(いや,確かに点滅してるんだ,これは),気になってしょうがない。リフレッシュレートを上げるか解像度を下げるかすればいいんだけれど,フォントの読みやすさと画面内の情報量密度(表示文字数)を両立させるには,最低でも 1152x864 ぐらいの解像度は欲しいところ。これを超える解像度になると,チラつきを感じさせなくするのはなかなか難しいことのようだ。

ましてや, PAL モニタなんて目も当てられない状態だ。フィールド周波数 50Hz という数値は,今の自分にはあまりにも低すぎるように感じられる。画面が黒くなる瞬間が見えるような気がしてたまらない。


PAL 繋がりでちょっと調べものをしていたら,こんな資料にぶち当たった。

http://www.ite.or.jp/study/hoso/tips/tip05.html

http://www.ite.or.jp/study/hoso/tips/tip06.html

たまに, NTSC のフィールド更新周期は 60Hz (30Hz) である,なんて記述があるけれど,正式には 59.94Hz (29.97Hz) だ。ここまではよくある話だとして,問題はどうしてキリのいい 60Hz ではなく 59.94Hz などという中途半端なサイクルを選んだのか,という話だ。上記のページにある説明によれば,テレビ画像を電波放映する際の搬送波の仕様に鍵があるらしい。それぞれの信号がカチ合わないようにするために微調整を行う必要があったのだ。


ここの話をもうちょっと詳しく調べてみると, 1953 年に NTSC (National Television System Committee − 全米テレビジョン基準委員会)がカラーテレビ放送の規格を決定する際の話にまでさかのぼる。

http://www.google.co.jp/search?q=ntsc+subcarrier+dropframe

このとき NTSC は,既存の白黒テレビの放送規格に色信号を追加するために(前述のような都合から)音声信号の副搬送波をライン周波数の整数倍になるように調整することを考えたようだ。そのために選ばれた倍数が 1001/1000 で,これによって音声副搬送波はライン周波数の 286 倍,つまり 4.5045MHz になるはずだった。

ところが, FCC (Federal Communication Commission − 米国連邦通信委員会)が音声副搬送波の変更を拒んだため(ここの事情はよくわからないけれど,この周波数帯域は FM ラジオ放送と隣接する領域にあるから,何らかの既得権が絡んで変更することができなかったのかもしれない……), NTSC は当初の予定とは逆にライン周波数を (1001/1000)^-1 倍にするという手段を選ばざるを得なかった,というわけ。

こうして 60 * 1000 / 1001 = 59.94Hz という中途半端なレートが誕生してしまったということだ。


ところで,欧州を中心に普及しているテレビ信号方式である PAL (Phase Alternation Line) 方式はこういった事情とはまったく関連が無く,きっちりフィールド周波数 50Hz となっている。色信号の伝送方式に関しても NTSC とは別の方式と取っており,一般的に PAL の方が色再現率に優れていると言われている。

いつの時代も互換性は技術者にとって悩ましい問題を生じてしまうものらしい。先見のある設計を行えなかった先人達を恨むべきか,それとも消費者の短絡的な要求を切り捨てることのできない弱腰な態度を非難すべきなのか……。ともかく, NTSC が "Not Twice the Same Color" −「同じ色など出やしない」などとバカにされ続けているのも,そんな事情からくるものだったらしい。


importance sampling

2002-07-23

020723s.png

先日試しに作ってみた path tracing のサンプルプログラムを,ひとまず整理してみることにした。

ソースを整理しながらプログラムの各所を見直していると,拡散面からランダムな方向に光線を射出する処理の部分で,その「ランダムな方向」が一様な分布になっていないことに気付いた。

class ScatterVector : public Vector
{
public:
  ScatterVector(const Vector &normal)
  {
    RandGen r(-1, 1);
    Vector v(r(), r(), r());
    v = normalize(v);
    *this = dot(v, normal) < 0 ? -v : v;
  }
}

これだと正方形内に一様に分布するベクトルから内接球面への射影になってしまうから,対角線方向の周辺にサンプルが集中してしまうことになる。モンテカルロ積分をベースとした統計的な手法では,サンプルの分布によって式の意味が大きく変化してしまうから,一見重要でなさそうなこんな関数でも決して油断することはできない。この場合は,恐らく「棄却を伴うサンプリング法」を用いるのがいいんだろう。

  ScatterVector(const Vector &normal)
  {
    RandGen r(-1, 1);
    while (true)
    {
      Vector v(r(), r(), r());
      if (dot(v, v) < 1)
      {
        v = normalize(v);
        *this = dot(v, normal) < 0 ? -v : v;
        break;
      }
    }
  }

これで球面より外にあるサンプルは棄却されて,球面に一様に分布するベクトルを生成することができる。


ところで Jensen 本には,拡散面(ランバート面)における光の反射方向は, [0,1] で一様に分布する乱数 X1, X2 を用いて,次のような球面座標で求めることができる,と書かれている(式 2.24)。

( theta, phi ) = ( acos( sqrt( X1 ) ), 2 * PI * X2 )

しかしこれはどう見ても半球面上に一様に分布するベクトルではない……半球の頂点,つまり X1 = 0 の辺りに偏りが発生するはずだ。うーむ,どういうことじゃい。

脚注を頼りにいろいろ読み進めてみると(特に 11.1 式周辺),どうやらこれは重点的サンプリング法を適用した場合におけるサンプルの分布,という意味であるらしい。平面上のある点における放射照度は,放射輝度と「法線と入射角の余弦」を掛けた値を半球上で積分することで求まるのだけれど,ここから分布関数 p(theta) = PI * cos(theta) を使って重点的サンプリング法を適用すると,前述のような偏りのあるサンプリング関数が求まるようだ。

っていうのを前後せずにあらかじめ書いておいてくれれば余計な間違いもしなかったと思うんだけれど,どうだろう。式 2.24 の時点では読者は重点的サンプリング法など知らないのだから,これはちょっと誤解を招きやすい記述だと思う。脚注(訳者による追加分)が無かったらこのような思考の流れを追うことはできなかったかもしれないし,ましてや,もし原書の間違いを含んだ式を参照していたら,もっと混乱を招いていたことだと思う。ううむ……。


そして,よくよく確認してみると,どうやら僕の作った path tracer はいろんな個所で勘違いをしていたらしい。

僕は,各反射点においてランダムに反射方向を生成し,その方向から入射する放射輝度を推定した後に,その放射輝度が半球上においてあらゆる方向から入射しているものと考えて積分を行う,つまり,

L(x,o) = integ( f_r,d(x) * L_i(x) * dot(o',n) * do' )

というようなものを考えていた。 f_r,d(x) はランバート面における一定な BRDF であり,反射係数 (albedo) を PI で割った値に等しい。ここで dot(o',n) の半球における積分は PI に等しいから,結局,

L(x,o) = L_i(x) * albedo(x)

となる。ところがこれは完全な勘違いで,そもそもモンテカルロ積分になってないんだよね,これじゃ。


Jensen 本では path tracing の原理自体については寄り道程度にしか触れられていなく,その詳細については語られていない。実際のところ Kajiya の path tracing は,各反射点においてたった1サンプルのみのモンテカルロ積分を行うことでレンダリング方程式の解を求めるもの,と考えればいいらしい。つまり,

L(x,o) = 2 * PI * f_r,d(x) * L_i(x) * dot(o',n)

となる。 "2 * PI" は半球面の面積だ。半球面においての積分なので,1サンプルでの積分の近似はこういった表現になる。

メインループはこんな感じだ。

  Vector org(eye);
  Vector vec(ray);
  Real L = 1.0;

  while (true)
  {
    if (!scene.shoot(org, vec)) return L;

    org = scene.incident_coord();
    vec = ScatterVector(scene.incident_normal());

    L *= 2.0 * scene.incident_albedo();
    L *= dot(vec, scene.incident_normal());
  }

本当にこんな感じ。ただし,これだとなかなか反復が終了しないので,終了条件は適当に都合よくしてある。

これが,前述の重点的サンプリングを使用した ScatterVector になると,もうちょっと簡潔な式になる。

  while (true)
  {
    if (!scene.shoot(org, vec)) return L;

    org = scene.incident_coord();
    vec = ScatterVector(scene.incident_normal());

    L *= scene.incident_albedo();
  }

内積演算がどこかへ消えてしまった。これは重点的サンプリングで分布関数の逆数を乗ずる際に消えてしまうもので, 11.1 式の訳注に簡単な解説が書いてある。これも訳注がなかったらそうとう惑わされていただろうな……。


そんなわけで,通常の一様な分布を使用した場合と,重点的サンプリングを使用した場合の生成画像の比較を行ってみた。サンプル数を落とすことでわざとノイズを増幅してある。もちろん,右側が重点的サンプリングを行った方だ。明らかにノイズが軽減されているのが分かる。ていうかなんか根本的に画像が違っている気もするんだけれど……なんか間違ったかな。


Russian Roulette

2002-07-24

020724s.png

今日は飲みだった。なんだかちょっと特殊な会合。久しぶりに赤坂に行ってきた。

やはりこちらはハイソだなあ,と思う。普段の生活環境が中野や溝の口なわけだから,それと比べていたら,まあ無理もないのかもしれない。青山一丁目を出た瞬間から,ちょっと違う雰囲気に圧倒される。意識しすぎか……。


次は,お手軽そうな「ロシアンルーレット法」を試してみる。ロシアンルーレットは,この場合要するに,反射時に放射輝度に対して反射率 (albedo) を乗ずるのではなくて,反射率を「はずれ」の確率とした「ロシアンルーレット」を行って,「当たった」場合は反復の打ち切りを行う,というものだ。プログラム中で言えば,

Real shade(const Ray &ray, Real rad)
{
  if (!intersect(ray)) return rad * sky;
  return shade(scatter(ray), rad * albedo);
}

こんな感じで再帰的に反復している部分を,

Real shade(const Ray &ray, Real rad)
{
  if (!intersect(ray)) return rad * sky;
  return (rand(0,1) > albedo) ? 0 : Shade(scatter(ray), rad);
}

この様にしてしまう。 albedo を乗ずる替わりに, albedo より高い数が出た場合は打ち切りにより "0" を返し,その他の場合は albedo を掛けることなく再帰を行う。このとき,この関数の期待値は,

E = albedo *  Shade(scatter(ray), rad) + (1 - albedo) * 0

となるから,統計的に見れば元の式と同じ意味を持つことになる。ただし,サンプル数が十分に多いことが前提だ。

ロシアンルーレットを用いることの利点は,乱数が当たって「打ち切り」が発生した場合に,その後再帰的に呼ばれるはずだった反復処理を中断することができるということ。反復回数は処理時間のオーダーに関わってくるから,反復回数が少なくなれば全体的な処理量も減らすことができるはずだ。


それで,さっそく試してみたのが上の画像。左端のがロシアンルーレットを適用した画像,右端のがロシアンルーレットを使用しない方法による生成画像だ。両者を比較してみると,ロシアンルーレットを使用した場合に明らかにノイズが増加していることがわかる。

一般的な path tracing のアルゴリズムでは,純粋にロシアンルーレット法を用いるものらしいんだけれど,ちょっと試しに両者を織り交ぜた方法を試してみた。経路中における反射率の積が 0.5 を下回った時点で初めてロシアンルーレットに切り換えて,それ以前では通常の反射処理を行うというものだ。このバージョンで生成したのが真ん中の画像。とりあえずノイズを減らすことには成功している。だけれど,「0.5 を下回った時点で」なんてのもずいぶんいい加減な方法だから,もっと強烈な光源とか出てきたらほとんど意味が無くなってしまうかもしれない。


iichiko

2002-07-25

020725s.png

朝,起きたばかりのぼんやりした頭の状態で,何気なく,駅に貼ってある「いいちこ」のポスターを眺めていると,その右下辺りに URL が書かれていることに気が付いた。「いいちこ」のホームページだ。

http://www.iichiko.co.jp/

もちろん,あのポスターの展示ページも存在する。

http://www.iichiko.co.jp/museum/gallery/lobby.html

ああ,いいねえ,やっぱり。

http://www.iichiko.co.jp/museum/gallery/87/87_j11.html

http://www.iichiko.co.jp/museum/gallery/89/89_j6.html

http://www.iichiko.co.jp/museum/gallery/94/94_j3.html

http://www.iichiko.co.jp/museum/gallery/86/86_j8.html

ちょっと小さめの画像(しかも画質があんま良くないな……)しか無いのが残念だ。これが駅張りのB倍ポスター,つまり横1メートル半ぐらいの大きなポスターで貼られていると,何とも言えない独特な存在感を醸し出すのだ。単なる焼酎(しかも「下町のナポレオン」ですよ)の宣伝なのにね。その意外性ったら,それはもう。

どうやら,このポスターのシリーズを題材にした書籍が存在するようだ。

http://www.amazon.co.jp/exec/obidos/ASIN/4828407618

気が向いたら買ってみよう。それとも,売り切れる前に購入しておいた方がいいんだろうか。


path tracing に RGB カラーへの対応を加えてみた。カラーへの対応自体は何も難しいことではなくて,ただロシアンルーレットの扱いが微妙に違ってくるぐらいだった。各スペクトルにおける反射率の平均(平均反射率)を使ってロシアンルーレットを行った後,平均反射率と各スペクトルにおける反射率の比をかけてやらなければならない。あとはちょろっと変数書き換えたぐらいかな……。その辺りは tvmet のおかげでだいぶ楽な作業になった。

次なる改造は光源のバリエーションを増やすことかなあ,と思う。今は天球光源しかないために単純な path tracing でも比較的ノイズの少ない画像が生成できているけれど,これが少しでも特徴的な光源になると,ちょっとやっかいなことになるかもしれない。しかも今は直接照明処理を省いている分処理が軽くなっているから,これを新たに加えるとなると,またずいぶんレンダリング速度が落ちるだろうと思う。

問題をできる限り簡単なものにとどめるために(僕でも十分に扱い切れるぐらいに,だ!),しばらくの間はランバート面しか扱わないと心に決めているので,任意の BRDF への対応などには当分手を染めないだろうと思う。完全鏡面や透過処理も,よほど凝らない限りは面白くならないと思うのでしばらく無視。これは純粋に,大域照明への憧れを克服するための道程なんだ。応用なんて何も考えちゃいない……。


ひとくぎり

2002-07-26

020726s.png

今日も飲み。今日のはなにげに大規模だ。ちょっと懐かしい人たちと顔を合わせて飲む。2年前から比べると,この会社のこの部署も,ずいぶん様変わりしたものだと思う。あのときあそこでああならなかったら……とか色々と思いをしのばせながら,もしかしたら自分が今ここにいることもすごい奇跡なのかもしれないなあ,と思う。

いや,そんな大げさなもんでもないけど。


色のサポートを加えたところで何となく一区切り付いた気分。またソースを整理して,これはこれで完成ってことにしておこうかと思う。

http://www.radiumsoftware.com/files/pathtrace.cxx.1.12.txt

これで480行のソースファイル。いろいろと手抜きをしているうえに,外部ツール (tvmet, DevIL, boost) の助けを借りているから,本質的な部分しか残っていない状態に近いと思う。今回久しぶりに C++ を使ったわけだけれど,やはり,優秀なクラスライブラリ群が既に存在してる状態に限って言うならば, C から C++ に移行することによって得られる恩恵は大きいと思う。


ところが少し残念な知らせが入った。 DevIL (OpenIL) の開発終了が宣言されたようだ。

http://openil.sourceforge.net/

とても使い勝手の良いライブラリなので,これからも継続的なサポートを期待していたのだけれど……。うーむ,残念。別に作者氏本人に異変があったわけでもなく,普通に引き継ぎを希望しているようなので,誰か良き後継者が現れることを望む。

しばらくは今の DevIL でのしのげるだろうけれど,じきに不具合など出てくるかもしれない。今のうちに他のライブラリも試してみようかと思って,おそらく最も有名な画像形式ライブラリである "FreeImage" のウェブを参照してみると,なんと,時を同じくして FreeImage も開発が終了してしまったことが告知されていた。うへえ。

http://www.6ixsoft.com/

こちらについては,その存在を SourceForge に移行して,やはり後継者の登場を望んでいるようだ。


DevIL には,現時点でも明らかな問題点が一つある。

typedef char* ILstring;
ILboolean ilSaveImage(const ILstring FileName);

たぶん作者氏は

ILboolean ilSaveImage(const char* FileName);

となるのを意識してこうしたんだろうけれど,これは正しくは同じ意味にはならない。 "const char*" の const は "char" にかかるのであり,これは「char 固定値へのポインタ」という解釈になる。ところが DevIL で使われている宣言では「char へのポインタの固定値」となってしまう。これでは const の意味がほとんどない。実際, ilSaveImage を呼んでいる箇所ではほとんどの場合警告が発生してしまうので,やむなく char* にキャストしているような状態だ。


そんな状況とは対照的に, tvmet の方は新しいバージョンのリリースが相次いでいる。今年の4月頃はまだ v0.1.2 だったんだけれど,最近リリース間隔が狭まってきて,あっという間にもう v0.4.0 だ。

http://tvmet.sourceforge.net/

主な機能はそれほど変わっていないようだけれど,活気が感じられるのは良いことだ。むしろ tvmet 自体は今ぐらいの機能量で十分だと思う。ただ,その上に被せるユーティリティライブラリみたいのが欲しいかな。例えばポロっと回転行列を生成したり,ベクトルの正規化を行ったりとか……そういうのが tvmet 自体に組み込まれて設計の洗練度が下がってしまうことは望まれないと思う。


RTR と Gems3 ,実はもうとっくに発売されているみたいなんだけれど,いまだに届く気配すら感じられない。おそらく amazon.co.jp に在庫が無いんだろう。ぬう,ぬかったな amazon め……。


ひまわり

2002-07-27

かなり普通の休日。最近はなぜか就寝時間が早まってきていて,おかげで休日でも昼過ぎには起きれるようになった。

夕方のまだ暑さが引き切らないうちに,外に散歩に出た。いつもなら駅前に直行するところを,今日はちょっと遠回りしてみるような気分。駅前はあんなにごみごみしている溝の口も,ちょっと裏に入ればごく普通の閑静な住宅街だ。意外と,古い民家とか,町工場っぽい小企業とか,そういうの素朴な構造物が多い町なんだなと,ここに来て3年目を過ぎて初めて気が付いた。

コンクリで周囲をがっちりと固められた小さな調整河川の傍に,向日葵がつぼみをつけてその首をもたげていた。その隣には咲きはじめの花もある。それを見た瞬間,今年はまだ夏が始まったばかりであることに気が付いた。ここ数年,忙しくて気付けば夏が終わっているようなことばかりだったから,実はまだ僕にも夏が残されていることに気付いた瞬間が,なにげに,無性に嬉しかった。

くだらないね。


メシを食いに行ったついでにゲーセンなぞに寄ってみて,ひさしぶりにメダルゲームに興じてみた。ちょっと面白かったのが,コナミの "Fortune Orb" 。

http://www.konami.co.jp/gm/medal/project_team/fortune-orb/to...

ゲームの内容自体は,メダルがチェッカーに入ると液晶モニタのスロットが回り始めて……とかそれだけの内容なんだけれど,筐体のめちゃくちゃな華やかさと微妙なバランスの良さが相まっていい感じだった。

メダルやらボールやらスロットやらルーレットやらと,やたらなギミックの多さが見た目を楽しくしているし,まるでカジノにでも来たのかというほどのド派手な空間を演出しているのが良い手際だと思う。所詮はメダルゲーム,というか,みんなお金を掛けているわけでもなくて適当に時間を潰しに来ているだけなんだから,見た目の派手さで客を愉快にさせるということは,とても大切な要素だと思う。

でもこのゲームの場合,勝つ要素はほとんど運にかかっていると言っても過言ではないので,実力で何かを得たいと思っている人には全く向いていないと思う。逆に適当に遊び散らすんだったら,こういうのも楽しくていいかもなあ,と思った。


未読が溜まりつつある Gamasutra を消化すべく,まずは "Jak and Daxter" の Postmortem を読む。

http://www.gamasutra.com/features/20020710/white_01.htm

最も興味深かったのは, "GOAL" (Game Object Assembly Lisp) に関する記述だ。 GOAL は Naughty Dog が "Crash Bandicoot" の頃から使い続けていたインハウスのプログラミング言語で,その名が表しているように Lisp をベースにした構文を採用している。よくスクリプト言語なんかにありがちな中間コードを使用したインタプリタではなく, PlayStation 用の MIPS アセンブリコードを直接吐き出すというかなり本格的なやつだ。 Naughty Dog 的には,これを彼らなりの愉快なハックだと考えて(Lisp ってのがそもそもハッキーだよね)使いつづけてきたらしいんだけれど,それが今回,初めて否定的な面を自ら明らかにしたということが興味深かった。恐らく彼らも,次は GOAL みたいな「特殊仕様」を使わないと心に決めていることだろうと思う。

それと,記事の中でも触れている "Crash Bandicoot" との決別については,本人達の自主的な判断よりも,どちらかというと版元の権限によるところが大きいと思う。 Crash Bandicoot の "Crash" 君は米 Universal 社の権利物であり, Naughty Dog が自由にできる要素ではなかった。だからきっと,彼らは以前から,自分たちの手で自分たちに権利のあるキャラクターを作りたいと思っていたはずだ。それが今回,やっと実現されたということかもしれない。

だから, "Crash Bandicoot" の喪失によっていくばくかの損失を伴ったとしても,即ちそれが彼らにとって間違った判断だったということにはならないのだと思う。それよりも恐らく大切であろうものを,やっと手に入れることができたのだから,だ。


OpenGL 1.4

2002-07-28

020728.png

普通の日曜日。部屋でぼんやりしていると,遠くから微かに太鼓や笛の音が聞こえてくる。何やら近所で祭りが催されているようだ。そう言えば昨日は隅田川花火大会だったんだっけな。もう,花火なんて十年近く見ていない。暇な今年こそ,そういう事をやっておくべきだったのかもしれないけれど,あまりモチベーションが湧かないな……人ごみとか嫌だし。

適当にメシを食いにいったついでに,本屋でマンガとか購入。太田垣康男 "Moonlight Mile" と,高橋しん「最終兵器彼女」。よくよく考えるとすごい組み合わせ。宇宙もののくせにやけに汗臭いやつの次は,ミリタリのくせしてやけに日和ってるやつ。で,もう,大変。


なにげに OpenGL のスペック 1.4 が始動しているようだ。

http://www.opengl.org/developers/documentation/OpenGL14.html

ちょっと前に SGI からプレス発表があったんだけれど, 具体的な露出が始まったのはごく最近のことだ。今回の拡張の最大の焦点は,やはりなんと言っても ARB バーテクスシェーダ (ARB_vertex_program) の登場だろう。

http://oss.sgi.com/projects/ogl-sample/registry/ARB/vertex_p...

バーテクスシェーダの標準規格と言えば, ATI の一部のドライバでサポートを開始していた "EXT_vertex_shader" がまず思い当たる。今回の拡張も,てっきりそれにならうものだと思っていたんだけれど,これが予想を覆して NVIDIA 式,つまり "NV_vertex_program" をベースにしたものになっているようだ。

NVIDIA 式のバーテクスシェーダは,「バーテクスシェーダ言語」で記述された一連のプログラムソースを文字列としてドライバにロードし,それをレンダリングパイプラインに挿入するというもの。この方式はある種のわかり易さを伴っているものの,本来のアーキテクチャ・デザインをならべく生かした方向で拡張を進めるというこれまでの OpenGL のやり方からすると,かなり過激な実装方法のように思える。

これに対して ATI が中心になって進めていた EXT_vertex_shader では,シェーダ命令登録関数を使って1個づつオペレーションを挿入していくという方式を取っている。この方法ではドライバ内にパーサ(構文解析器)を用意する必要が無いというメリットがある。また使用する側にとってみても,登録関数の呼び方を変えるだけでシェーダプログラムの変更ができるというメリットがある(NVIDIA 方式では文字列の直接編集が必要になる)。

まあ, OpenGL 2.0 でも高級言語化されたシェーダ言語の導入が予告されていたわけだし,シェーダが高等なものになるにつれ,いずれ EXT_vertex_shader のような方