VTF / VMT についての備忘録
Source Engine のテクスチャ形式 VTF とマテリアル VMT に関する備忘録です。
L4D 解剖シリーズ:
- HUD の改造方法について
- cfg / console について
- VTF/VMT についての備忘録(本記事)
汎用的な部分
VTF とは Valve Texture Format の略。
VTF の構造は、実際の画像データ + メタ情報(設定)になっている。 補足だが Unreal Engine では微妙に違うので注意。Unreal Engine では、Texture は正真正銘ただの画像データで、Material が Texture + メタ情報(設定)となっている。 Source Engine では Texture 自体にメタ情報が仕込まれているし、さらに Texture に情報を付加したものが Material と呼ばれている。
VTF の縦のサイズと横のサイズは、それぞれ 2 の累乗のサイズになっているべき。 32x32, 64x64, 128x128, 256x256, 512x512 とか。おそらくこれはハードウェアで高速処理するための制限で、DirectX では 2 の累乗サイズだと最適化されるようになっているのでそれが由来だと思われる。
VMT ファイルとは何か。 Valve Material Type の略。VTF(テクスチャ)に、さらに光沢や動きなどより詳細な情報を含んだものをマテリアル(VMT)という。 詳細: http://developer.valvesoftware.com/wiki/Material 簡単なプログラミングっぽいことができるし、表面のでこぼこを表現したりも出来る。
VTF は画像の格納方式を選択できる(動画ファイルで言えば Codec のようなものか)。 そのうち、DXT1 形式ではアルファ(透過)情報を含められないので注意。BGRA8888 や DXT5 なら透過情報を含めることが出来る。
Windows 向けの便利なシェル拡張について。 VTF Shell Extension というものがあり、これをインストールすればエクスプローラー上で、他の jpeg などの画像ファイルと同じようにアイコンとして表示出来るので便利。
- 参考画像:

- Download: http://www.wunderboy.org/sourceapps.php#vtf_shell
- 参考画像:
VTF Edit というソフトで各種画像形式と相互変換出来る。
normal map とは何か。 表面のデコボコ情報を含んだ画像データのこと(標準的なマップという意味ではない)。画像データ + その画像の normal map で、デコボコした表面を表現出来る。normal map は青っぽい画像データ。GIMP のプラグインに normal map を出力してくれるものがあるので、それを入れると製作が楽になる。
mipmap という用語は何か。 距離に応じてテクスチャを変更出来る仕組み。L4D では 8 段階くらいまであるっぽい。
skybox = 空(そら)の画像データ。 Source Engine では必ずプレイヤーはどこかの箱の中に居なければならない。そうしないとマップのコンパイルに失敗する。いちばん外側の箱は一般的には「空(そら)の箱」になっている。おそらく skybox という単語の語源はそこ。
vgui = HUD 関係の画像データ。
bik ファイルについて。 動画形式。ここに書くべきものではないかもしれないが、起動し終わった後の背景に流れている動画がこの形式で保存されている。RadVideoTools というソフトウェアで、各種動画形式と Bink 形式への相互変換が可能。
なおこのツールを入れておけば、Windows 上で Bink 形式をダブルクリックしたときに動画として再生されるようになるので便利。
スプレー(ゲーム内で壁などに貼る自作ロゴ画像)について
- 基本的に VTF ファイルが使える。
- VTF Flag に、No Level Of Detail(強制的に最高画質)と No Mipmaps をつけるとキレイなスプレーになる。 後者は必要条件ではないかも。
- 実際にゲーム内で表示されるときは 256x256 サイズに拡大縮小されているっぽい。
- ゲーム内には VTF でしかインポートできないが、インポートされた後は内部的には VTF + VMT で保存されているっぽい。
場所は
materials\vgui\logos。もしかしたらこれをうまく利用して、スプレーにも VMT(マテリアル)が利用できるとなると表現の幅が広がる。たとえば発光したりとか、表面がスクロールされたりするものが作れそう。またそうなれば normal map が使えるので、表面がデコボコした立体的なスプレーも可能かも。 → 訂正、VMT の使用は無理だった。クライアントはmaterials/vgui/logosの方を見ているのではない可能性がある。 ここからは推測だが、ユーザーがサーバーにログインするときにmaterials/vgui/logos/選択されている vtfがサーバーにアップロードされる。サーバー側としてはその受け取ったファイルをmaterials/tempに格納すると同時に、参加している他のユーザーにもその vtf を配布して表示出来るようにしてあげている。 - アニメーション VTF は、プレイ環境の FPS に応じて再生速度が変わるわけではない。FPS が高くても低くても一定速度。
- 距離によって変化するスプレーの作り方。
- アニメーション VTF の作り方。
- 高画質なスプレーの作り方。 512x512 で元画像を用意し、VTF Edit で import して、No Level Of Detail と No Mipmaps フラグを ON にして Save する。
- 透過スプレーの作り方。 GIMP などの透過情報を扱える画像編集ソフトで、透過情報を設定した tga 形式で出力する。その後、VTF Edit でそれを読み込んで VTF に変換するだけで OK。
Skin について
- Skin は、VMT(マテリアル)と VTF(テクスチャ)で作る。normal map データを使って表面の凹凸も表現可能。
- Tank などの Infected(L4D の敵=感染者)を発光させることはできない。おそらくチートっぽい行為対策。 そういう vpk を使っているとサーバーログイン時に弾かれる。Tank の model データを変更することも出来なくなったため、これについては対処不能だと思う。色を鮮明なものに変更させる、などは Infected でも可能。 こういったチートっぽい Addon に対するサーバー側の対策についてはあまり調査していないが、おそらく sv_pure の仕組みを使って可能で、これは変更可能な material のファイルなどをホワイトリスト方式/ブラックリスト方式のいずれかにより制限できるというもの。
- ディレクトリ名の
v_modelsは一人称視点のとき(first person)にモデルに適用されるマテリアル、w_modelsは三人称視点のとき(third person)にモデルに適用されるマテリアル。 パイプボムを手に持っているときと、地面に落ちているときでは使用されているマテリアルが違うということ。
マテリアルの定義ファイル (VMT) について
基本的に値はダブルクォート(
")で囲む。単体の数字であった場合は囲まなくても良いらしい。 構文エラーがあればvpk.exeによるコンパイルに失敗するのでわかりやすい。"100"Material に指定出来る変数。
色
"$color" "[float float float]"内部からの光
"$selfillum" "1" "$selfillumtint" "[1 1 1]"マテリアルに対応する VTF ファイルがアルファチャンネルを持っていない場合は意味がない。たとえば DXT1 形式なんかだと駄目。DXT5 とか BGRA8888 だと出来る。
より詳細について:
Proxies について。 ちょっと変わったマテリアルを作るときに必要。小さな範囲ではあるがプログラミング的なことが出来る。
Proxies は上から順番に実行されるイメージで、基本的に
srcVar= 入力元となる変数resultVar= 出力先となる変数
となっている。
これらを一時的な変数に代入したりを繰り返して、最終的にはマテリアルのパラメーター(
$alphaや$colorなどの変数)に代入することによって L4D 世界に反映させる。以下の例でいう Func1/Func2 自体に L4D 世界への影響があるものもある。Proxies { Func1 { srcVar $temp resultVar $temp } Func2 { srcVar $temp resultVar $temp } }ためしに上記例の実行手順を解説するとこんな感じ。
Func1 入力 => $temp Func1が実行される 結果 => $temp に代入 Func2 入力 => $temp Func2が実行される 結果 => $temp に代入
Proxies の例文集
テクスチャのスクロール
TextureScroll { texturescrollvar $baseTextureTransform texturescrollrate 1.0 texturescrollangle 0.00 }プレイヤーの視点情報
"PlayerView" { "scale" 8.0 "resultVar" "$dotproduct" }乱数生成
"EntityRandom" { "scale" "12" "resultVar" "$offset" }サイン(sinh/数学的な意味でのサイン/周期的な何かを実現するときに使う)
"Sine" { "sineperiod" 4 "timeoffset" "$offset" "resultVar" "$color[0]" }値の範囲を min - max に抑える
"Clamp" { "min" 0.0 "max" 1.0 "srcVar1" "$alpha_unclamped" "resultVar" "$alpha" }
詳細:
- Proxies の解説: http://developer.valvesoftware.com/wiki/Proxies
- マテリアルに指定出来る Proxies 一覧: http://developer.valvesoftware.com/wiki/List_Of_Material_Proxies