Scissorによる挙動違い(DX vs GL)

DirectXとOpenGLとで、シザーの設定時のクリア挙動が異なるようです。座標系がそれぞれ異なるってのもあるけど、
そこは上下を逆転して対処したとしても、それだけでは互換動作は不可能。

フレームバッファの縦横と、ビューポートの縦横と、シザー設定の縦横
それぞれ違う設定にしてみて、双方のAPIで実行してみるとわかりやすいかと。

DirectXではビューポートとシザー設定のお互い被っている領域でクリア
GLではシザー設定に従ってクリア。

同じような振る舞いにさせるならシザー領域とビューポートの領域のAND集合を取るようにして、
できあがった矩形でシザーテストするようにしてクリア処理を入れるようにする。

GL面倒だけど、こういうった細かいことをきちんと実装できるだけ
柔軟性はあると思う。


Vertex Texture Fetchによるスキニング

Vertex Texture Fetchを利用して、スキニングメッシュのサンプルを動かしてみました。
ひにけにxnaさんのところでは、XNAを用いての解説があったので、
ここでは、普通のDirectX SDKとC++による組み合わせでこれをやってみたいと思います。

使用するもの

  • SkinnedMeshのサンプルプログラム
  • ShaderModel 3.0に対応したグラフィックボード
    • Radeon X1000シリーズを除く。これはVTFに対応していないため。

ソースコード

各準備

まずは、ボーンのマトリックスを格納するためのテクスチャを準備します。
ここではグローバルにおいて、手抜きしました。
また、毎回書き換えるので、ダイナミックテクスチャにしています。

ボーン用テクスチャの概要

ボーン用のテクスチャは、横方向に使用したいボーンの数、縦方向に4というサイズで作成しました。
というのも、行列は4x4のfloat要素で、今回のテクスチャはRGBA32Fという形式のため、1テクセルに4要素格納できます。
そのため、4テクセル使えば、1つの行列が生成できるということを目的にしています。

横方向(U方向)はボーンのインデックスを示すことにして、
V方向には行列の行を格納することにしました。
このほうが配列っぽく見えるかなと思っています。

マトリックスパレット数調整のための変換部分

またついでに、ConvertToIndexedBlendedMesh を呼び出している部分も
これらの設定のボーン数をみるように修正が必要です。

マトリックスパレットの設定部分の修正

マトリックスパレット設定部分を次のように変更します。

テクスチャにボーンのマトリックスを格納していきます。
注意点としてはテクスチャのY方向へずらすときは、ロックしたときのピッチバイト数でずらさないといけない点です。
それと、シェーダー内ではマトリックスとしては取れず、
float4の4つの組で取れる感じになります。
そのためシェーダーに送る際に転置しておきます。
こうすることで、内積を利用して計算が可能になります。

プロジェクション用行列の設定修正

サンプルのSkinnedMeshのサンプルではmViewProjというシェーダー定数に
実はプロジェクション用の行列しか送っていないです。
ビュー行列はマトリックスパレットに対して適用していました。

この部分を変更します。
mViewProjにg_matProjを設定している部分で、g_matViewとの演算結果を格納するようにしておきます。

シェーダーコード

ほとんどの部分はサンプルのそのままです。
変更点は以下の通り

  • tex2Dlodにて該当するマトリックスパレット相当のテクセルから値を取得
  • 浮動小数用にサンプラを設定
  • VTF使うために、vs_3_0を設定。あわせてピクセルシェーダーも

実行結果

こんな感じになります。
理由はピクセルシェーダーでディフューズ用のテクスチャ等を処理せず、
単純にライトの強度を出しているからです。

しかし、これがVTF利用して動いています。

今は、横方向128でやりましたが、これを256にすることで
ボーンの上限256個までを一度に使うことが出来るようになります。


自力でがんばる人

自力で似たようなことをやっている人を発見したのでメモ。
.xの自力読み込みとかやっているっぽい。
しかも2007-2008年の色々やっている記事は本当に参考になりそうです。

みょ~りゅん☆12歳ぶろぐ

どうもこの実装記事は学生のころでやっているようですね。
(後のほうで就職したという記事があったので。)
すごいなぁと思います。

感心したポイント

  • mqoから自力読み込み
  • 自力でのスキニングメッシュ処理
    • および、自力アニメーションコントローラ作成
  • 各種シェーダー
    • LiSPSM(Light space perspective shadow map)
    • 各ライト
  • 同人で本格3D目指すってところ

やっぱり居るところには同じ考えを持っている人はいますね。
自分もがんばろうって励みになります。


ESXiでのディスク上限

今までやってなかったVMwareESXi4でのiSCSIの実験やNFSマウントの実験をやってみました。

これで2TBの壁を越えられるかという点に興味があります。

準備編

2TB以上のiSCSIターゲット

WindowsServer2008を用意して、その中でiSCSIターゲットを準備します。
以前SoftwareTargetでは2TB以上のVHDを作れなかったと思い、iSCSIの上限は2TBだ!と思って作業をやめてしまっていました。
実際にはそんな上限はありません。
RAIDを組んで2TB超えるディスクをフォーマットの際にMBRからGPTにして、
その中でiSCSIターゲット用のvhdファイルは2TB以上に設定出来ました。

NFS共有

WindowsServer2008がNFSサーバーとなるように、
NFS共有の機能を有効化しました。

iSCSI検証

色々と躓くポイントはありましたが、VMwareESXiでのiSCSIを認識させる部分までは出来ました。
しかしながら、datastoreの作成で失敗してしまいます。
「Failed to get disk partition information」というエラーが出てしまいます。

ストレージアダプタの追加でiSCSIを設定し、2TB以上を見えるところまでは出来たのですが、
上記の問題のためそれ以上はテストできませんでした。

考察

VMware側の問題で、LUN1つあたり2TBまでしか対応していないというのが
マニュアルに記載されているようです。
そのため、この非対応部分に引っかかって、前述のエラーが発生するのではないかと考えられます。

NFS検証

iSCSIでの設定が嘘のように簡単にVMwareESXi側でマウント出来ます。
NFS共有の設定をしているドライブは2TBオーバーですが、それでも問題なく出来ました。

仮想マシンのディスクに2TB以上の設定を出来るかと試みましたが、
これについては出来ないようです。

結論

個人的な結論ですが、複数台使っての環境構築ではNFS共有の利用のほうが有効な気がします。
性能面でいえば、iSCSIのほうが良いのかもしれませんが、
巨大なデータストア(2TB over)を持ちたい場合にはNFSのほうがいいでしょう。


すでにVMwareWorkstation 7.1

VMwareWorkStation 7.1

いつの間にかVMwareWorkstation 7.1が出ていたようです。
大きな機能は7から変わっていないですが、このVer 7はやっぱり凄いなと思います。

嬉しい機能

  • 仮想ディスク 2TBまでサポート
    • 今までが 950GBという上限だったようです。知らなかった。
  • 仮想マシン内でのOpenGL/DirectXの使用
    • 内部からシェーダー使えるようになります。
    • 情報によると、VTFの機能は使えないようです。

7は買おうと思っているのに、未だに買えず。
この7.1では、Intel Core i3,5,7等に最適化も進んだと言うことなので、
PC新調したタイミングで同時に入れたいかも。


シェーダー定数(GLSL)

ボーンの行列60個

どこかのブログでボーン用マトリックスパレットが60個くらいまでしか使えなかったと見たので、その理由を書いてみます。
実はその制限は単純なもので、ShaderModel3系までだと、シェーダー定数は256個のレジスタが使えることになっています。
マトリックスだとfloatの16個分なので、float4に換算すると4つ使うことになります。

そして、Matrixが60個の場合 240個の定数レジスタを使ってしまうことになります。
頂点変換用のViewやProjectionのマトリックスも使うことを考えると、
この時点で250個くらいは使っていることになるので、約60個までボーン使えたという結果に合致していると思います。

ずいぶん前の記事だったようで、もうすでに解決しているかもしれません。

GLSLとHLSLとの違いで嵌った

DirectX(HLSL)の行列型は実はfloat4の設定APIを呼んでも設定が可能だったりします。
しかしながらOpenGL(GLSL)の行列型はそのような設定を許さないようです。それぞれで共通のシェーダーを作る場合には、この部分に注意が必要そうです。


GLSLスキニング

GLSLでスキニングシェーダー書いてみた

わりとGLSLでスキニングシェーダーをやったという記事を見かけないので
ここで書いてみます。

大変だった点はGLSLでは、Cのようなキャストを受け付けない点。
そのためブレンドインデックスをどうやってint型にするかで悩みました。
実際には、下記のソースコードに示すように int( )で囲ってやる程度で済む話なのですが、
知らないと結構悩みます。

備考

マトリックスを使わずにfloat4 (すなわちvec4)でやっているのは
単に自分のスタイルなだけです。
先輩のシェーダースタイルに影響された可能性が大です。
matrix型のほうが変換がmulで書ける分だけソースコードはすっきりします。
float4の4つという表現だと、シェーダー定数設定をするコードがすっきりします。
またMatrixをfloat4x3型として使っているような場合で効率よくシェーダー定数を使うことが出来ます。

他にはライティングが適当です。
平行光源と若干のアンビエント成分いれたつもりのコードです。

ソースコード(VertexProgram)

1頂点あたり4ボーンのスキニングシェーダーです。
1回のマトリックスパレットは36個です。

36個にした理由は、tiny.xがこの個数で描けるからです。


モデル読み込み

自前で読み込んでみる

DirectXの .xファイルを自前で読み込んで表示させてみました。
以前試行錯誤しながらがんばっていたConvertToIndexedBlendedMeshのニセモノを使って表示させることが出来るようになりました。

自分で変換するため、OpenGLの描画においても使用可能です。
以下にその例を表示してみます。

画像 補足
model_draw.png DirectでもOpenGLでもスキニングメッシュを読み込んで表示できてます。
さすがにシェーダーは別々に作成の必要がありますが…
モデルはキツネもどきさん作です。ありがとうございました。

OpenGLでも .x を使えるようになったため、プログラムが組みやすくなるかなと期待しています。

色々と作ったらこのWebに公開してみたいなと考えています。


Neo9Essentials

DVDRWドライブ購入

数年使っていたプレクスターのドライブが故障したので、
新しいドライブを購入しました。
DVDRWの機能だけでよかったので、バルクで。

最近バルクのDVDRWドライブって安いですね。
3000くらいで買えてしまうことに驚きです。

でも帰ってつないでみるとやっぱり安いやつは安いなりな感じでした。
トレイの開閉時の動作が若干気になります。
また表面の質感が安いプラスチックで…微妙。
単に使う分には問題ないんですけどね

付属ソフト

Nero9 Essentialsがついてました。
付いてないやつのほうが100円安かったんですが、せっかくなので。
Windows7対応っていってるので保険のために購入
(うちの環境ではCDBurnXPがフル動作しないため)

インストール後は手持ちのBDドライブも正常に認識したので
買って良かったと思います。2層書き込みの認識もしているようだし。
CDBurnXPではBDの1層でしか認識してくれなかったんですよね。

Nero9インストールの注意点

やけにディスク読み込みを繰り返すので不安になりました。
ドライブを変更しても同じなので、ディスクそのものの問題のようです。
ピックアップ部を痛めそうな感じだったので、
ディスクイメージisoを作成してそちらからインストールするようにしました。
これで問題なく動いてます。

このisoをマウントしてインストールしたのですが、問題の読み込み部分では
30秒は待たされた感じだったので、物理ドライブでやると
どれだけ待たされるのか不安を覚えました。

購入ドライブ

TWOTOPで AD7240S というNECドライブです


ESXi仮想マシンの自動起動

同僚から相談を受けたので、書いてみました。
同じように悩んでいる人の役に立てたら幸いです。

VMware ESXi 4での仮想マシンの自動起動設定

vSphere Clientの設定で自動起動・終了を設定できます。
vSphere Clientを起動して、構成タブを開きます。
開いた中に、ソフトウェアカテゴリで、仮想マシン起動/シャットダウンという項目があります。

ここで起動設定をするのですが、画面上の仮想マシンリストの部分では出来ず、
右上のプロパティのリンクをクリックして設定ダイアログを出します。
このあたりがちょっとわかりにくいかもしれませんね。