第4.3章: マテリアル (.rvmat)
ホーム | << 前: 3Dモデル | マテリアル | 次: オーディオ >>
はじめに
DayZにおけるマテリアルは、3Dモデルとその視覚的な外観を橋渡しするものです。テクスチャが生の画像データを提供する一方で、RVMAT(Real Virtuality Material)ファイルはそれらのテクスチャがどのように組み合わされるか、どのシェーダーがそれらを解釈するか、そしてエンジンがシミュレートすべきサーフェスプロパティ -- 光沢、透明度、自己発光など -- を定義します。ゲーム内のすべてのP3DモデルのすべてのフェースがRVMATファイルを参照しており、それらを作成・設定する方法を理解することは、あらゆるビジュアルモッドに不可欠です。
この章では、RVMATファイルフォーマット、シェーダータイプ、テクスチャステージの設定、マテリアルプロパティ、ダメージレベルのマテリアルスワップシステム、そしてDayZ-Samplesからの実践的な例について説明します。
目次
- RVMATフォーマットの概要
- ファイル構造
- シェーダータイプ
- テクスチャステージ
- マテリアルプロパティ
- ヘルスレベル(ダメージマテリアルスワップ)
- マテリアルがテクスチャを参照する方法
- RVMATをゼロから作成する
- 実際の例
- よくある間違い
- ベストプラクティス
RVMATフォーマットの概要
RVMATファイルは、マテリアルを定義するテキストベースの設定ファイル(バイナリではない)です。カスタム拡張子にもかかわらず、フォーマットはBohemiaの設定スタイルの構文を使用するプレーンテキストで、クラスとキーバリューペアで構成されています。
主な特徴
- テキストフォーマット: 任意のテキストエディタ(Notepad++、VS Code)で編集可能です。
- シェーダーバインディング: 各RVMATは使用するレンダリングシェーダーを指定します。
- テクスチャマッピング: どのテクスチャファイルがどのシェーダー入力(ディフューズ、ノーマル、スペキュラなど)に割り当てられるかを定義します。
- サーフェスプロパティ: スペキュラ強度、エミッシブグロー、透明度などを制御します。
- P3Dモデルから参照: Object BuilderのResolution LODのフェースにRVMATが割り当てられます。エンジンはRVMATとそれが参照するすべてのテクスチャをロードします。
- config.cppから参照:
hiddenSelectionsMaterials[]はランタイムにマテリアルをオーバーライドできます。
パス規則
RVMATファイルはテクスチャと一緒に、通常はdata/ディレクトリに配置されます:
MyMod/
data/
my_item.rvmat <-- マテリアル定義
my_item_co.paa <-- ディフューズテクスチャ(RVMATから参照)
my_item_nohq.paa <-- ノーマルマップ(RVMATから参照)
my_item_smdi.paa <-- スペキュラマップ(RVMATから参照)ファイル構造
RVMATファイルには一貫した構造があります。以下は完全な注釈付きの例です:
ambient[] = {1.0, 1.0, 1.0, 1.0}; // アンビエントカラー乗数(RGBA)
diffuse[] = {1.0, 1.0, 1.0, 1.0}; // ディフューズカラー乗数(RGBA)
forcedDiffuse[] = {0.0, 0.0, 0.0, 0.0}; // 加算ディフューズオーバーライド
emmisive[] = {0.0, 0.0, 0.0, 0.0}; // エミッシブ(自己発光)カラー
specular[] = {0.7, 0.7, 0.7, 1.0}; // スペキュラハイライトカラー
specularPower = 80; // スペキュラの鮮明さ(高い = タイトなハイライト)
PixelShaderID = "Super"; // 使用するシェーダープログラム
VertexShaderID = "Super"; // 頂点シェーダープログラム
class Stage1 // テクスチャステージ: ノーマルマップ
{
texture = "MyMod\data\my_item_nohq.paa";
uvSource = "tex";
class uvTransform
{
aside[] = {1.0, 0.0, 0.0};
up[] = {0.0, 1.0, 0.0};
dir[] = {0.0, 0.0, 0.0};
pos[] = {0.0, 0.0, 0.0};
};
};
class Stage2 // テクスチャステージ: ディフューズ/カラーマップ
{
texture = "MyMod\data\my_item_co.paa";
uvSource = "tex";
class uvTransform
{
aside[] = {1.0, 0.0, 0.0};
up[] = {0.0, 1.0, 0.0};
dir[] = {0.0, 0.0, 0.0};
pos[] = {0.0, 0.0, 0.0};
};
};
class Stage3 // テクスチャステージ: スペキュラ/メタリックマップ
{
texture = "MyMod\data\my_item_smdi.paa";
uvSource = "tex";
class uvTransform
{
aside[] = {1.0, 0.0, 0.0};
up[] = {0.0, 1.0, 0.0};
dir[] = {0.0, 0.0, 0.0};
pos[] = {0.0, 0.0, 0.0};
};
};トップレベルプロパティ
これらはStageクラスの前に宣言され、マテリアルの全体的な動作を制御します:
| プロパティ | タイプ | 説明 |
|---|---|---|
ambient[] | float[4] | アンビエントライトカラー乗数。{1,1,1,1} = フル、{0,0,0,0} = アンビエントなし。 |
diffuse[] | float[4] | ディフューズライトカラー乗数。通常{1,1,1,1}。 |
forcedDiffuse[] | float[4] | ディフューズへの加算オーバーライド。通常{0,0,0,0}。 |
emmisive[] | float[4] | 自己発光カラー。ゼロでない値はサーフェスを光らせます。注意: Bohemiaはemissiveではなくemmisiveというスペルミスを使用しています。 |
specular[] | float[4] | スペキュラハイライトのカラーと強度。 |
specularPower | float | スペキュラハイライトの鮮明さ。範囲1-200。高い = タイトで集中した反射。 |
PixelShaderID | string | ピクセルシェーダープログラム名。 |
VertexShaderID | string | 頂点シェーダープログラム名。 |
シェーダータイプ
PixelShaderIDとVertexShaderIDの値は、マテリアルを処理するレンダリングパイプラインを決定します。通常、両方を同じ値に設定する必要があります。
利用可能なシェーダー
| シェーダー | 用途 | 必要なテクスチャステージ |
|---|---|---|
| Super | 標準的な不透明サーフェス(武器、衣服、アイテム) | ノーマル、ディフューズ、スペキュラ/メタリック |
| Multi | マルチレイヤーの地形と複雑なサーフェス | 複数のディフューズ/ノーマルペア |
| Glass | 透明および半透明サーフェス | アルファ付きディフューズ |
| Water | 反射と屈折を持つ水面 | 特殊な水テクスチャ |
| Terrain | 地形の地面サーフェス | サテライト、マスク、マテリアルレイヤー |
| NormalMap | 簡略化されたノーマルマップサーフェス | ノーマル、ディフューズ |
| NormalMapSpecular | スペキュラ付きノーマルマップ | ノーマル、ディフューズ、スペキュラ |
| Hair | キャラクターの髪のレンダリング | アルファ付きディフューズ、特殊なトランスルーセンシー |
| Skin | サブサーフェススキャッタリングを持つキャラクターの肌 | ディフューズ、ノーマル、スペキュラ |
| AlphaTest | ハードエッジ透明度(植物、フェンス) | アルファ付きディフューズ |
| AlphaBlend | スムーズ透明度(ガラス、煙) | アルファ付きディフューズ |
Superシェーダー(最も一般的)
Superシェーダーは、DayZの大多数のアイテムに使用される標準的な物理ベースレンダリングシェーダーです。3つのテクスチャステージを期待します:
Stage1 = ノーマルマップ (_nohq)
Stage2 = ディフューズ/カラーマップ (_co)
Stage3 = スペキュラ/メタリックマップ (_smdi)モッドアイテム(武器、衣服、ツール、コンテナ)を作成する場合、ほぼ常にSuperシェーダーを使用します。
Glassシェーダー
Glassシェーダーは透明サーフェスを処理します。ディフューズテクスチャからアルファを読み取って透明度を決定します:
PixelShaderID = "Glass";
VertexShaderID = "Glass";
class Stage1
{
texture = "MyMod\data\glass_nohq.paa";
uvSource = "tex";
class uvTransform { /* ... */ };
};
class Stage2
{
texture = "MyMod\data\glass_ca.paa"; // 注意: カラー+アルファ用の_caサフィックス
uvSource = "tex";
class uvTransform { /* ... */ };
};テクスチャステージ
RVMAT内の各Stageクラスは、テクスチャを特定のシェーダー入力に割り当てます。ステージ番号がテクスチャの役割を決定します。
Superシェーダーのステージ割り当て
| ステージ | テクスチャの役割 | 一般的なサフィックス | 説明 |
|---|---|---|---|
| Stage1 | ノーマルマップ | _nohq | サーフェスのディテール、バンプ、溝 |
| Stage2 | ディフューズ/カラーマップ | _coまたは_ca | サーフェスのベースカラー |
| Stage3 | スペキュラ/メタリックマップ | _smdi | 光沢、メタリック特性、ディテール |
| Stage4 | アンビエントシャドウ | _as | プリベイクされたアンビエントオクルージョン(オプション) |
| Stage5 | マクロマップ | _mc | 大規模な色のバリエーション(オプション) |
| Stage6 | ディテールマップ | _de | タイリングマイクロディテール(オプション) |
| Stage7 | エミッシブ/ライトマップ | _li | 自己発光(オプション) |
ステージプロパティ
各ステージには以下が含まれます:
class Stage1
{
texture = "path\to\texture.paa"; // P:ドライブに対する相対パス
uvSource = "tex"; // UVソース: "tex"(モデルUV)または"tex1"(2番目のUVセット)
class uvTransform // UV変換マトリクス
{
aside[] = {1.0, 0.0, 0.0}; // U軸のスケールと方向
up[] = {0.0, 1.0, 0.0}; // V軸のスケールと方向
dir[] = {0.0, 0.0, 0.0}; // 通常使用されない
pos[] = {0.0, 0.0, 0.0}; // UVオフセット(移動)
};
};タイリング用UV変換
テクスチャをタイリング(サーフェス全体に繰り返す)するには、asideとupの値を変更します:
class uvTransform
{
aside[] = {4.0, 0.0, 0.0}; // 水平方向に4倍タイリング
up[] = {0.0, 4.0, 0.0}; // 垂直方向に4倍タイリング
dir[] = {0.0, 0.0, 0.0};
pos[] = {0.0, 0.0, 0.0};
};これは地形マテリアルや建物のサーフェスで、同じディテールテクスチャが繰り返される場合によく使用されます。
マテリアルプロパティ
スペキュラ制御
specular[]とspecularPowerの値が連携して、サーフェスの光沢の外観を定義します:
| マテリアルタイプ | specular[] | specularPower | 外観 |
|---|---|---|---|
| マットプラスチック | {0.1, 0.1, 0.1, 1.0} | 10 | 鈍い、広いハイライト |
| 使い古した金属 | {0.3, 0.3, 0.3, 1.0} | 40 | 中程度の光沢 |
| 磨かれた金属 | {0.8, 0.8, 0.8, 1.0} | 120 | 明るく、タイトなハイライト |
| クロム | {1.0, 1.0, 1.0, 1.0} | 200 | 鏡のような反射 |
| ゴム | {0.02, 0.02, 0.02, 1.0} | 5 | ほぼハイライトなし |
| 濡れたサーフェス | {0.6, 0.6, 0.6, 1.0} | 80 | 滑らかで、中程度のシャープなハイライト |
エミッシブ(自己発光)
サーフェスを光らせるには(LEDライト、スクリーン、光る要素):
emmisive[] = {0.2, 0.8, 0.2, 1.0}; // 緑の発光エミッシブカラーはライティングに関係なく最終ピクセルカラーに加算されます。後のテクスチャステージの_liエミッシブマップで、サーフェスのどの部分が光るかをマスクできます。
両面レンダリング
両側から見える薄いサーフェス(旗、植物、布)の場合:
renderFlags[] = {"noZWrite", "noAlpha", "twoSided"};これはトップレベルのRVMATプロパティではなく、使用ケースに応じてconfig.cppまたはマテリアルのシェーダー設定を通じて構成されます。
ヘルスレベル(ダメージマテリアルスワップ)
DayZのアイテムは時間とともに劣化します。エンジンは異なるダメージしきい値での自動マテリアルスワップをサポートしており、config.cppのhealthLevels[]配列で定義されます。これにより、新品から破損までの視覚的な進行が作成されます。
healthLevels[]構造
class MyItem: Inventory_Base
{
// ... その他の設定 ...
healthLevels[] =
{
// {ヘルスしきい値, {"マテリアルセット"}},
{1.0, {"MyMod\data\my_item.rvmat"}}, // 新品(100%ヘルス)
{0.7, {"MyMod\data\my_item_worn.rvmat"}}, // 使い古し(70%ヘルス)
{0.5, {"MyMod\data\my_item_damaged.rvmat"}}, // 損傷(50%ヘルス)
{0.3, {"MyMod\data\my_item_badly_damaged.rvmat"}},// ひどく損傷(30%ヘルス)
{0.0, {"MyMod\data\my_item_ruined.rvmat"}} // 破損(0%ヘルス)
};
};仕組み
- エンジンがアイテムのヘルス値(0.0〜1.0)を監視します。
- ヘルスがしきい値を下回ると、エンジンは対応するRVMATにマテリアルをスワップします。
- 各RVMATは異なるテクスチャを参照できます -- 通常、段階的に損傷した外観のバリアントです。
- スワップは自動的です。スクリプトコードは不要です。
ダメージテクスチャの進行
一般的なダメージ進行:
| レベル | ヘルス | 視覚的変化 |
|---|---|---|
| 新品 | 1.0 | きれいな、工場出荷時の外観 |
| 使い古し | 0.7 | わずかな擦り傷、軽微な傷 |
| 損傷 | 0.5 | 目に見える傷、変色、汚れ |
| ひどく損傷 | 0.3 | 重度の摩耗、錆、亀裂、塗装剥がれ |
| 破損 | 0.0 | ひどく劣化した、壊れた外観 |
ダメージマテリアルの作成
各ダメージレベルに対して、段階的に損傷したテクスチャを参照する個別のRVMATを作成します:
data/
my_item.rvmat --> my_item_co.paa(きれい)
my_item_worn.rvmat --> my_item_worn_co.paa(軽微なダメージ)
my_item_damaged.rvmat --> my_item_damaged_co.paa(中程度のダメージ)
my_item_badly_damaged.rvmat --> my_item_badly_damaged_co.paa(重度のダメージ)
my_item_ruined.rvmat --> my_item_ruined_co.paa(破壊)ヒント: すべてのダメージレベルに固有のテクスチャが必要とは限りません。一般的な最適化は、ノーマルマップとスペキュラマップをすべてのレベルで共有し、ディフューズテクスチャのみを変更することです:
my_item.rvmat --> my_item_co.paa my_item_worn.rvmat --> my_item_co.paa(同じディフューズ、低いスペキュラ) my_item_damaged.rvmat --> my_item_damaged_co.paa my_item_ruined.rvmat --> my_item_ruined_co.paa
バニラダメージマテリアルの使用
DayZは、カスタムダメージテクスチャを作成したくない場合に使用できる汎用ダメージオーバーレイマテリアルのセットを提供しています:
healthLevels[] =
{
{1.0, {"MyMod\data\my_item.rvmat"}},
{0.7, {"DZ\data\data\default_worn.rvmat"}},
{0.5, {"DZ\data\data\default_damaged.rvmat"}},
{0.3, {"DZ\data\data\default_badly_damaged.rvmat"}},
{0.0, {"DZ\data\data\default_ruined.rvmat"}}
};マテリアルがテクスチャを参照する方法
モデル、マテリアル、テクスチャ間の接続はチェーンを形成します:
P3Dモデル(Object Builder)
|
|--> フェースにRVMATを割り当て
|
|--> Stage1.texture = "path\to\normal_nohq.paa"
|--> Stage2.texture = "path\to\color_co.paa"
|--> Stage3.texture = "path\to\specular_smdi.paa"パス解決
RVMATファイル内のすべてのテクスチャパスはP:ドライブルートに対する相対パスです:
// 正しい: P:ドライブに対する相対パス
texture = "MyMod\data\textures\my_item_co.paa";
// これは次を意味します: P:\MyMod\data\textures\my_item_co.paaPBOにパックする場合、パスプレフィックスはPBOのプレフィックスと一致する必要があります:
PBOプレフィックス: MyMod
内部パス: data\textures\my_item_co.paa
完全参照: MyMod\data\textures\my_item_co.paahiddenSelectionsMaterialsオーバーライド
Config.cppはランタイムに名前付きセレクションに適用されるマテリアルをオーバーライドできます:
class MyItem_Green: MyItem
{
hiddenSelections[] = {"camo"};
hiddenSelectionsTextures[] = {"MyMod\data\my_item_green_co.paa"};
hiddenSelectionsMaterials[] = {"MyMod\data\my_item_green.rvmat"};
};これにより、同じP3Dモデルを共有しながら異なるマテリアルを使用するアイテムバリアント(カラースキーム、カモパターン)を作成できます。
RVMATをゼロから作成する
ステップバイステップ: 標準不透明アイテム
テクスチャファイルを作成します:
my_item_co.paa(ディフューズカラー)my_item_nohq.paa(ノーマルマップ)my_item_smdi.paa(スペキュラ/メタリック)
RVMATファイルを作成します(プレーンテキスト):
ambient[] = {1.0, 1.0, 1.0, 1.0};
diffuse[] = {1.0, 1.0, 1.0, 1.0};
forcedDiffuse[] = {0.0, 0.0, 0.0, 0.0};
emmisive[] = {0.0, 0.0, 0.0, 0.0};
specular[] = {0.5, 0.5, 0.5, 1.0};
specularPower = 60;
PixelShaderID = "Super";
VertexShaderID = "Super";
class Stage1
{
texture = "MyMod\data\my_item_nohq.paa";
uvSource = "tex";
class uvTransform
{
aside[] = {1.0, 0.0, 0.0};
up[] = {0.0, 1.0, 0.0};
dir[] = {0.0, 0.0, 0.0};
pos[] = {0.0, 0.0, 0.0};
};
};
class Stage2
{
texture = "MyMod\data\my_item_co.paa";
uvSource = "tex";
class uvTransform
{
aside[] = {1.0, 0.0, 0.0};
up[] = {0.0, 1.0, 0.0};
dir[] = {0.0, 0.0, 0.0};
pos[] = {0.0, 0.0, 0.0};
};
};
class Stage3
{
texture = "MyMod\data\my_item_smdi.paa";
uvSource = "tex";
class uvTransform
{
aside[] = {1.0, 0.0, 0.0};
up[] = {0.0, 1.0, 0.0};
dir[] = {0.0, 0.0, 0.0};
pos[] = {0.0, 0.0, 0.0};
};
};Object Builderで割り当てます:
- P3Dモデルを開きます。
- Resolution LODでフェースを選択します。
- 右クリック --> Face Properties。
- RVMATファイルを参照します。
ファイルパッチングまたはPBOビルドでゲーム内でテストします。
実際の例
DayZ-Samples Test_ClothingRetexture
公式DayZ-Samplesには、標準的なマテリアルワークフローを示すTest_ClothingRetextureの例が含まれています:
// DayZ-Samplesリテクスチャの例から
ambient[] = {1.0, 1.0, 1.0, 1.0};
diffuse[] = {1.0, 1.0, 1.0, 1.0};
forcedDiffuse[] = {0.0, 0.0, 0.0, 0.0};
emmisive[] = {0.0, 0.0, 0.0, 0.0};
specular[] = {0.3, 0.3, 0.3, 1.0};
specularPower = 50;
PixelShaderID = "Super";
VertexShaderID = "Super";
class Stage1
{
texture = "DZ_Samples\Test_ClothingRetexture\data\tshirt_nohq.paa";
uvSource = "tex";
class uvTransform
{
aside[] = {1.0, 0.0, 0.0};
up[] = {0.0, 1.0, 0.0};
dir[] = {0.0, 0.0, 0.0};
pos[] = {0.0, 0.0, 0.0};
};
};
class Stage2
{
texture = "DZ_Samples\Test_ClothingRetexture\data\tshirt_co.paa";
uvSource = "tex";
class uvTransform
{
aside[] = {1.0, 0.0, 0.0};
up[] = {0.0, 1.0, 0.0};
dir[] = {0.0, 0.0, 0.0};
pos[] = {0.0, 0.0, 0.0};
};
};
class Stage3
{
texture = "DZ_Samples\Test_ClothingRetexture\data\tshirt_smdi.paa";
uvSource = "tex";
class uvTransform
{
aside[] = {1.0, 0.0, 0.0};
up[] = {0.0, 1.0, 0.0};
dir[] = {0.0, 0.0, 0.0};
pos[] = {0.0, 0.0, 0.0};
};
};メタリック武器マテリアル
高いメタリックレスポンスを持つ磨かれた武器バレル:
ambient[] = {1.0, 1.0, 1.0, 1.0};
diffuse[] = {1.0, 1.0, 1.0, 1.0};
forcedDiffuse[] = {0.0, 0.0, 0.0, 0.0};
emmisive[] = {0.0, 0.0, 0.0, 0.0};
specular[] = {0.9, 0.9, 0.9, 1.0}; // 金属用の高スペキュラ
specularPower = 150; // タイトで集中したハイライト
PixelShaderID = "Super";
VertexShaderID = "Super";
// ... 武器テクスチャを使用したStage定義 ...エミッシブマテリアル(光るスクリーン)
光を発するデバイススクリーン用のマテリアル:
ambient[] = {1.0, 1.0, 1.0, 1.0};
diffuse[] = {1.0, 1.0, 1.0, 1.0};
forcedDiffuse[] = {0.0, 0.0, 0.0, 0.0};
emmisive[] = {0.05, 0.3, 0.05, 1.0}; // 柔らかい緑の発光
specular[] = {0.5, 0.5, 0.5, 1.0};
specularPower = 80;
PixelShaderID = "Super";
VertexShaderID = "Super";
// ... Stage7に_liエミッシブマップを含むStage定義 ...よくある間違い
1. ステージの順序の誤り
症状: テクスチャがスクランブルされて表示され、ノーマルマップがカラーとして表示され、カラーがバンプとして表示される。 修正: Superシェーダーの場合、Stage1 = ノーマル、Stage2 = ディフューズ、Stage3 = スペキュラであることを確認してください。
2. emmisiveのスペルミス
症状: エミッシブが動作しない。 修正: Bohemiaはemmisive(ダブルm、シングルs)を使用しています。正しい英語のスペルemissiveを使用しても動作しません。これは既知の歴史的な癖です。
3. テクスチャパスの不一致
症状: モデルがデフォルトのグレーまたはマゼンタのマテリアルで表示される。 修正: RVMAT内のテクスチャパスがP:ドライブに対する相対的なファイル位置と正確に一致していることを確認してください。パスにはバックスラッシュを使用します。大文字小文字を確認してください -- 一部のシステムでは大文字小文字が区別されます。
4. P3Dでのrvmat割り当ての欠落
症状: モデルがマテリアルなしでレンダリングされる(フラットグレーまたはデフォルトシェーダー)。 修正: Object Builderでモデルを開き、フェースを選択し、Face PropertiesでRVMATを割り当ててください。
5. 透明アイテムに間違ったシェーダーを使用
症状: 透明テクスチャが不透明に見える、またはサーフェス全体が消える。 修正: 透明サーフェスにはSuperの代わりにGlass、AlphaTest、またはAlphaBlendシェーダーを使用してください。適切なアルファチャンネルを持つ_caサフィックスのテクスチャを使用してください。
ベストプラクティス
動作する例から始めてください。 DayZ-Samplesまたはバニラアイテムからrvmatをコピーして変更してください。ゼロから始めるとタイプミスが発生しやすくなります。
マテリアルとテクスチャを一緒に保管してください。 テクスチャと同じ
data/ディレクトリにRVMATを保存してください。関係が明確になり、パス管理が簡素化されます。理由がない限りSuperシェーダーを使用してください。 95%のユースケースを正しく処理します。
シンプルなアイテムでもダメージマテリアルを作成してください。 アイテムが視覚的に劣化しないとプレイヤーは気づきます。最低限、低いヘルスレベルにはバニラのデフォルトダメージマテリアルを使用してください。
スペキュラはObject Builderではなくゲーム内でテストしてください。 エディタのライティングとゲーム内のライティングは非常に異なる結果を生み出します。Object Builderで完璧に見えるものが、DayZのダイナミックライティングの下では光りすぎたり鈍すぎたりする可能性があります。
マテリアル設定を文書化してください。 サーフェスタイプに適したスペキュラ/パワー値を見つけたら記録してください。これらの設定は多くのアイテムで再利用します。
ナビゲーション
| 前 | 上 | 次 |
|---|---|---|
| 4.2 3Dモデル | Part 4: ファイルフォーマット & DayZ Tools | 4.4 オーディオ |
