PBRテクスチャ バリデーター · 命名・サイズ・不足マップ
テクスチャラボの検査ステージに絞った画面です。ふつうは読み込んでから気づく問題を、ファイルごとに、それを見つけた測定値つきで報告します。
PBRバリデーターは読み込み前にテクスチャセットを確認します。各マップに役割があるか、全マップのサイズが同じか、選んだワークフローの必須・推奨マップがそろっているか、サイズが2のべき乗か、グレーマップが本当にグレーか、ノーマルマップが本当に単位ベクトルにデコードされるかを見ます。1つのマテリアルのマップを入れると、ファイル名(_basecolor、_normal、_roughness、_ORMなど)から役割を決め、ワークフローを選ぶと問題ごとにファイルと測定値が出ます。JSONレポートに測定値が残り、ファイル名や中身は一切変えません。

- Channel PNGs測定確認· numpy
- Normal map測定確認· numpy
- Packed mask / ORM測定確認· Pillow
- Engine import未検証
何を、どの基準で確認するか
名前から決まる役割。ファイル名を小文字にし、区切りを_にそろえてから、具体的なものから順に最初に一致したトークンを使います。パック(orm・arm・rma・mra・maskmap・mask)、アルベド(albedo・basecolor・diffuse・colorなど)、ノーマル(normalgl・normaldx・normal・nrm・n)、ラフネス、スムースネス(gloss)、メタリック、AO(ao・occlusion・ambientocclusion)、ハイト(height・displacement・bump)、エミッション、不透明度、スペキュラーの順です。1〜2文字のトークン(_n・_m・_r)は信頼度低とします。役割はすべてプルダウンなので、ファイル名を変えずに誤った推定を直せます。
不足はワークフローが決めます。個別マップ(glTF・汎用):アルベド必須、ノーマル・ラフネス・メタリック推奨。Unity HDRP:アルベドとマスクマップが必須、ノーマル推奨。Unity URP:アルベド必須、ノーマル・メタリック推奨。Godot ORM・Unreal ORM:アルベド必須、ノーマルとORMテクスチャ推奨で、ラフネスとメタリックはあるのにORMがない場合は、単なる「不足」ではなく「パック可能」と出ます。ラフネスのマップはスムースネスの代わりになり、その逆も同様です。
推測ではなく測定。単一チャンネルの役割(ラフネス・メタリック・AO・ハイト・不透明度)がRGBで保存されているとき、どのテクセルでもチャンネル差が2以下なら「RGBで保存されたグレー」、超えれば「チャンネルが異なる」(パック済みの可能性)と報告します。ノーマルマップはテクセルごとにデコードし、長さが1から0.12より離れたサンプルを単位外と数えます。単位外が1%以下で、青が128未満(面の内側を向くベクトル)のものがなければ合格です。別の役割なのにノーマルマップの判定(単位外5%以下、負の青0.1%以下)を通るものは「ノーマルマップに見える」と警告します。
2のべき乗はエラーではなく警告です。glTF 2.0は、サンプラーがリピートやミップマップを使う場合、対応が限られるプラットフォームでは2のべき乗でないテクスチャをリサイズすべき(SHOULD)としており、UnityのインポーターにはそうしたテクスチャをスケールするNon Power of 2の設定があります。問題になるかは対象次第なので、バリデーターは報告だけして判断は任せます。
- ワークフロー
- エンジンのマテリアルが期待するマップの構成(パックの仕方を含む)。
- セット名
- ファイル名から役割のトークンを除いた残り。一度に入れたファイルのセット名が違うと「名前の不統一」が出ます。
- 単位外のサンプル
- デコードしたノーマルの長さが1から0.12より離れているサンプル。
- 2のべき乗
- 2ⁿピクセルのサイズ:256、512、1024、2048 …
例:Godot 4 ORMで確認した岩のセット
PNGを4枚まとめて入れ、ワークフローをGodot 4 ORMにしたときにバリデーターが返す結果です。
rock_basecolor.png 2048 × 2048 albedo
rock_normal.png 2048 × 2048 normal
rock_roughness.png 1000 × 1000 roughness
rock_metallic.png 2048 × 2048 metallic
error dimension-mismatch 2048x2048 と 1000x1000 (rock_roughness.png)
warn missing-recommended orm
info pack-available roughness + metallic → Godot 4 ORMプリセット
warn not-power-of-two rock_roughness.png 1000 × 1000
セット合格:いいえ(エラー1)ラフネスを2048 × 2048で書き出し直せば、エラーと2のべき乗の警告が同時に消えます。マスクパッカーでラフネスとメタリック(AOがあればAOも)をパックすれば「orm不足」も消えます。
できること
- ワークフロー別の必須・推奨マップ、「パックマップの構成要素がすでにある」。
- サイズ不一致、2のべき乗でない(任意で正方形でない)、未分類・不統一な名前。
- 測定した事実:想定外のアルファ、アルファ0下のRGB、RGBで保存されたグレーマップ、RGBが異なる単一チャンネルマップ。
- テクスチャごとの測定値入りのGame Labs形式JSONレポート。
使い方
- マテリアルのマップをドロップ。
- ワークフローを選ぶ。
- 問題の一覧を読む。
- JSONレポートをダウンロード。
結果の確認
- 修正後に新しいファイルを入れ、同じワークフローのままにします。エラーも警告もなければサマリーに✓が出ます。
texture-report.jsonをダウンロードしてissuesを読みます。各項目にid・level・ファイル・数値(サイズ、maxDeviation、ratio、minBlue)があります。- ノーマルマップでは
normalCheck.meanLengthが1に近く、blueNonNegativeがtrueのはずです。
トラブルシューティング
| 症状 | 考えられる原因 | 確認方法 | 対処 |
|---|---|---|---|
分かっているファイルなのにunclassified | 名前に既知のトークンがない(rock_03.png)、または英語の一覧にないトークン | 役割の欄が不明になっている | プルダウンで役割を選ぶ。レポートにもその選択が残る |
ノーマルマップにduplicate-role | 1つのダウンロードの_NormalGLと_NormalDXを両方入れた | 役割がノーマルのファイルが2つある | エンジンが期待する方だけ残す(Unity・GodotはGL)。もう一方しかなければノーマルマップ変換で変換 |
ラフネス・メタリックのファイルにgray-channels-differ | 単一マップの名前だが、実はパックテクスチャ(または色付きのプレビュー) | 問題の項目に最大のチャンネル差と、差のあるテクセルの割合が出る | 役割をパックマップに変えるか、チャンネル分解で分ける |
ハイト・バンプのファイルにlooks-like-normal | ノーマルマップを_bumpで保存し、名前のルールがハイトと読んだ | 単位長と青の判定を通っている | 役割をノーマルに変える |
normal-blue-negativeやnormal-not-unit | 接空間ノーマルマップではない(ハイトやオブジェクト空間のマップ、色としてリサイズしたマップ) | 問題の項目にminBlueと単位外の割合が出る | 正しいファイルを使うか、ノーマルマップ生成でハイトから作る |
ラフネス・メタリック・AOにunexpected-alpha | 書き出したソフトが、エンジンが読まないアルファを付けた | 問題の項目に最小のアルファとアルファ0のテクセル数が出る | アルファなしで書き出し直す。アルファ0の下の色はラボでは保持されるが、多くのエンジンは無視する |
ほかの方法
| 方法 | こんなときに向いています |
|---|---|
| テクスチャラボ全体 | チェックで見つかった問題の修正まで必要なとき:ノーマル変換、チャンネルの分解・パック、エッジブリード、リサイズ、一括書き出し。 |
| エンジン上で確認する | マテリアル1つ、エンジン1つのとき。インポート設定や空きスロットはマテリアルのインスペクターで分かりますが、サイズ・RGBで保存されたグレー・ノーマルの妥当性はそこでは測定されません。 |
出力ファイルと検証方法
「測定確認」は、ダウンロードしたファイルをページ外(Pillow・numpy・独立したパーサー)で開き直して性質を測ったという意味です。ゲームエンジンでの読み込みは試していません。
| 書き出し先 | ファイル | 検証 |
|---|---|---|
| Channel PNGs | <name>-r/g/b/a.png (8-bit grey) | 測定確認 numpyチャンネルごとにバイト一致。完全に透明なテクセル下のRGBも保持。 |
| Normal map | PNG · OpenGL (+Y) or DirectX (−Y) | 測定確認 numpyデコードしたベクトルは単位長(最大誤差0.0002)。OpenGLとDirectXは緑だけが異なります。 |
| Packed mask / ORM | Unity HDRP mask · URP metallic · ORM (glTF, Godot) | 測定確認 Pillowパック後のバイトを確認:ORMプリセット、AO 10 / ラフネス 80 / メタリック 220 → (10, 80, 220, 255)。 |
| Engine import | Unity · Unreal · Godot | 未検証どのエンジンでも読み込んでいません。 |
検証の根拠
チャンネル分解は4チャンネルすべてでバイト一致(最大差0)、透明テクセル2048個のRGBを保持。エッジブリードはアルファ0のテクセル448個だけを変更し、アルファは一切変更なし。OpenGL ↔ DirectXは緑(255 − g)だけが異なり、変換後の法線は単位ベクトル。
制限
- 色空間は判定しません。ICCプロファイルやガンマを読まず、エンジンが役割ごとにsRGBとリニアのどちらを期待するかと、PNGにsRGBチャンクがあるかだけを示します。
- ノーマルマップのOpenGL・DirectXの規約はここでは判定しません。判定機能はStudioのテクスチャ作業画面にあります。
- 名前のルールは英語のトークンだけで、ファイル名は決して変更しません。
- レポートは汎用JSONで、エンジンが読み込む形式ではありません。
- チャンネルのバイトを正確に扱えるのはPNGだけです。JPEG・WebPはブラウザがデコードし「バイト一致ではない」と表示します。
- インターレースPNGと16ビット出力は非対応。正確な経路は3,355万ピクセルまで。
- ノーマルマップの規約はピクセルから判定できず、変換のみ可能です。
- Unity・Unreal・Godotへの読み込みは行っていません。チャンネル順は各ドキュメントとエンジンのソースに基づきます。
バージョンと出典
チェックレポートはテクスチャラボで確認しました(docs/TEXTURE-LAB.md):schemaVersion 1、engineTarget generic、テスト用ファイルと一致するalpha.zeroPixels = 2048、exactChannels true。JPEG入力ではexactChannels: false。このページの数値はsrc/game/texture-set.jsとsrc/game/texture-normal.jsの基準値です。
参照した公式ドキュメント
よくある質問
対応ワークフローは?
個別マップのメタリック/ラフネスと、ラボのプリセットにあるパック配置(Unity HDRPマスク・URPメタリック・Godot・Unreal ORM)です。スペキュラー/グロスのワークフローはありません。
ファイル名を変更してくれますか?
いいえ。不統一な名前を報告するだけで、変更はご自身で行ってください。
無料ですか?アカウントは必要ですか?
このページの機能はすべて無料で、アカウントなしで使えます。透かしや制限された書き出しはありません。
スプライトはアップロードされますか?
いいえ。Studioはこのブラウザのタブ内でデコード・パック・書き出しを行います。プロジェクトはブラウザ(IndexedDB)に自動保存され、.nerulioファイルとして保存できます。
Asepriteやエンジンのプラグインは必要ですか?
いいえ。.asepriteファイルはブラウザで読み書きします。エンジン別のバンドルには必要なものが入っています(Godotはインポート設定とシーン、UnityとGodotのタイルセットは小さなエディタースクリプト)。