Yearly Archives: 2010

2010-09-16

ピクセルシェーダからレンダーターゲットを参照する(Direct3D9)

最近ピクセルシェーダをいじっているのですが、GPU方面はどうにも分からないことが多くて困っています。

ピクセルシェーダからレンダーターゲットのピクセルを参照したくなるのですが、そういうことってやっても良いのでしょうか。試しにD3DUSAGE_RENDERTARGETなテクスチャを作ってレンダーターゲットとサンプラーの両方にセットしてピクセルシェーダから読み書きしてみたのですが、手元のGeForceでは一応ちゃんと動いているみたいです。ただ、読み込む位置を間違えると書き換え後の値を参照したり・しなかったり不定になります。ピクセルの処理順はGPUの都合で決まっているのでしょうからこれは当然でしょう。ピクセルシェーダにおいて結果が書き込まれるだろう位置から読み込む場合は常に問題なく書き換え前の値を読み込めました。描画対象範囲外であるピクセルを読み込む場合も問題ありませんでした。

問題はこのような処理をするコードに移植性があるのかということです。上のように動作しない環境があるのならば、描画範囲矩形を算出して、その部分をいったん作業用テクスチャへコピーするような実装が必要になります。……望み薄いんだろうなぁ。

2010-09-15

冷たい風

朝、外の空気が冷たいのに気がつく。緩やかな風が肌をすり抜けると冷気がとても心地よい。

もう九月も半ば。あと少しで十月。

このまま寒くなると布団や衣類が心配だなぁ、と憂鬱になる。

風邪などをひかないように注意。

2010-09-14

乗算済みアルファ

画像の合成処理において、乗算済みアルファ(premultiplied alpha)はとても有用な考え方です。単純な例では Fa*Fc+(1-Fa)*Bc が Fm+(1-Fa)*Bc で計算でき、乗算が一つ減ります(FはForegroundのF、BはBackgroundのB、aはAlpha、cはColor、mはMultiplied colorの意)。しかしこの式の場合は乗算済みアルファを使わなくても Bc+(Fc-Bc)*Fa と変形できるので、それほどメリットにはならないかもしれません。有用なのは共にアルファ(不透明度)を含む二つのピクセル同士を合成または補間するような場合です。このようなときの合成処理は不透明度付きピクセルのブレンドモード付き合成方法に書きましたが、不透明度を含むピクセル同士を合成してストレートアルファで結果を得ようとすると、どうしても最後に不透明度でカラー値を割る必要が出てきます。ピクセルごとに除算を行うのは処理速度上大変不利なので、できれば回避したいところです。乗算済みアルファでの合成結果は「カラー値×不透明度」が得られればよいので、最後に不透明度で割る必要がありません。また、不透明度を含めた双線形補間サンプリングにおいても乗算済みアルファは同様に力を発揮します。

このように色々とメリットのある乗算済みアルファですが、残念ながら私は普段使っていません。理由は二つ。一つはただでさえテンプレートで組み合わせ爆発気味の既存の合成処理ライブラリにもう一つピクセルフォーマットを追加してメンテナンスしきる自信がないこと。もう一つはピクセルごとに除算してもぎりぎり許容範囲内の速度が出てしまう昨今のPC事情。つまり、労多くして功少なしな感じがして、とてもやる気が起きないといったところでしょうか。

しかし時々猛烈に乗算済みアルファが使いたくなるときがあるのです。う゛ー。

2010-09-06

ゴミ

あー、また燃やさないゴミを出すのを忘れた。この種のゴミは二週間に一回しか回収しないので困る。再来週は忘れないようにしないと。

2010-08-27

JavaScriptからバイナリファイルを読む

JavaScriptからバイナリファイルが読めると知った( Handling binary data - XMLHttpRequestの利用 - MDC )ので、色々試しているところです。

flash(flex)のURLLoaderByteArrayに似せたクラスがあればflashとの相互移植がやりやすくなりそうだなと思い、作ってみたり。

いくつか直面した問題を列挙。

  • Google Chromeでローカル・同一ディレクトリ下のファイルにアクセスできない。

    どうもセキュリティ上の都合のようです。コマンドラインオプション –allow-file-access-from-files で回避できました。(参考: Maginot-line: Error: NETWORK_ERR: XMLHttpRequest Exception 101)

  • IE8のXMLHttpRequestでローカル・同一ディレクトリ下のファイルにアクセスできない。

    ActiveXObject("Msxml2.XMLHTTP")ならアクセスできました。

  • IEでバイナリが取得できない。

    Msxml2.XMLHTTPにはoverrideMimeTypeは無く、responseTextでは正しくバイナリが取得できません。0のところで列が切れてしまうみたいです。responseBodyを使うと取得できるのですが、これはJavaScriptからはアクセスできず、VBScriptを経由してアクセスするものらしいです。(参考: JavaScriptによるLZHの解凍サンプル)

    私は以下のようなコードでresponseBodyの中身をJavaScript文字列へ変換しました。かなり遅いです。

    execScript("Function vbBinaryToText(bin)n"+
    	   "  Dim in"+
    	   "  Dim sn"+
    	   "  s=""n"+
    	   "  For i=1 to LenB(bin)n"+
    	   "    s = s & ChrW(AscB(MidB(bin, i, 1)))n"+
    	   "  Nextn"+
    	   "  vbBinaryToText = sn"+
    	   "End Functionn"+
    	   "n", "VBScript");
    str = vbBinaryToText(xhr.responseBody);
    
  • 文字列の文字エンコーディング変換が難しい。

    ByteArray.readMultiByte()のようなことをするのは難しそうです。Escape Codec Library: ecl.jsでやっているようなことをすれば実装できるのだとは思いますが、とりあえずUTF-8さえデコードできれば十分なので、readUTFBytes相当だけ実装しました。手元にあったC++の変換コードを移植。JavaScriptの内部エンコーディングはUTF-16っぽいのでサロゲートペアは分割。

  • 浮動小数点数バイナリの読み書きが難しい。

    NaN(JavaScriptにqNaNとsNaNの区別ってあるの?)、±無限大、±0、非正規数、正規化数をそれぞれ自分で分解・組みたてするしかないんでしょうね。powを使うのかな。

2010-08-25

Dropbox

Dropboxを導入してみた。

Dropboxの存在は前々から知っていたのだけど、普段cvsやgit、scp、ange-ftp(tramp)などを使っているとあまり必要性を感じることはなく、導入していなかった。

しかし、今日ハードディスクを整理しているときに、開発に使う資料(pdfや参考になる第三者のソースコード等)はDropboxで共有するのが良さそうだと思うに至った。これらのファイルはそれなりに容量が大きく、ネットワーク越しに閲覧するにはややストレスを感じる。ローカルでさくさく閲覧したい。それでいていつでもどこでも見たくなったときに見ることができるようにしたい。見たくなったときにいちいちダウンロードするのは手間だし時間がかかる。新しく手に入れた資料をアップロードし忘れるのも心配。「あ、あの資料自宅のPCの中だ……」なんてことは避けたい。バックグラウンドで自動的に同期されることが望ましい。Dropboxはそんな用途にはぴったりではないだろうか。