
長年の悩みだったグラデーションが汚い問題を自力救済で解決しましたよ!
この記事で紹介するのは、XREAL Air、Air 2、Air 2 Pro向けの非公式なファームウェア改造です。メーカー保証を受けられなくなる可能性があり、失敗すればグラスが起動しなくなることもあります。
注意書き
- 完全に自己責任。XREALとは一切関係のない非公式な改造である。
- XREALにこのファームウェア改造のことを知らせたり問い合わせてはいけない。内緒です。
- 公式ファームウェアも、パッチ済みファームウェアも配布しない。公式ファームウェアの入手方法も説明しない。
- 手元の公式ファイルは復旧手段になる。必ず別の場所にも保管する。
- DPブリッジとMCUは必ず対で更新する。AirとAir 2系では書き込み順が異なる。
- RGB化により消費電力が増える。表面温度は測っていないが、発熱も増えると考えられる。
- Air第1世代をBeam ProのNebulaで使う人は書き換えない。起動画面から先へ進まなくなる。
- 公式へ戻す手段は用意しているが、絶対に復旧できると保証するものではない。
- ヤバいと思ったら引き返せ。
この改造が向いている人・向いていない人
Airシリーズを通常の外部ディスプレイとして使い倒したい人、720pしか出せないゲーム機をつなぎたい人、Full-SBSを90Hzで使いたい人、そして緩やかな色の階調を少しでも素直に表示したい人向け。
Air第1世代でBeam ProのNebulaを使い続けたい人、公式アプリとの完全な互換性が必要な人、発熱や消費電力の増加を許容できない人には向きません。
はじめに
前回は、初代Airが持っている1920×1200のパネルを本来の解像度で使い、720p入力と3840×1200@90Hz、USBデータがない接続での自動DP音声を有効化しました。

その後、予告どおりAir 2を調べ始めました。
Air 2とAir 2 Proのパネル(ECX348E)は1920×1080なので、初代Airのように1200pへ拡張することはできません。その代わり、720pスケーラ、Full-SBS 90Hz、表示経路、音声、再接続処理を掘っていったところ、初代Airを含めたシリーズ全体で使えるRGB経路が見つかりました。
今回の本命はコレです。
今回の改造で何が変わるのか
先に結果をまとめます。
| 項目 | 公式ファームウェア | 改造後 |
|---|---|---|
| 2D | not RGBのOLED経路 | RGB888のままOLEDへ出力 |
| Full-SBS | not RGBのOLED経路 | 左右ともRGBで出力 |
| Airの解像度 | 1920×1080 | 1920×1200をpreferred timingとして追加 |
| Air 2 / Proの解像度 | 1920×1080 | 1920×1080のまま |
| 720p | EDIDで提示しない | 1280×720@60を提示し、全面へ拡大 |
| Full-SBS 90Hz | モードはあるが帯域不足 | HBR2を使って正常動作 |
| USBデータなしの音声 | 手動切替または対応Adapter通知 | 約5秒後にLPCM対応EDIDを再公告し、DP音声へ自動切替 |
| 給電を維持したHDMI抜き差し | 変換器によって復帰しない | 異常状態を検出して自動復旧 |
AirではFull-SBSが3840×1200、Air 2 / Air 2 Proでは3840×1080です。どちらも60 / 72 / 90Hzに対応します。
Air 2とAir 2 Proは同じファームウェア
Air 2とAir 2 Proは、公式のDPブリッジとMCUイメージを共有しています。今回のビルダも両機種に同じ出力を生成します。
ただし、USB PIDは別です。書き込みツールは接続中の機種を個別に判定し、公式入力と生成結果のSHA-256、project code、コンテナCRC、DP bank tagまで照合します。
ファームウェアが共通だからといって、project codeだけを見て雑に書き込むようなことはしてません。
EDIDのMonitor Nameも、Air 2ではAir 2、Air 2 ProではAir 2 Proのままです。
今回の主役、RGB化
これ、ずっと「できるはず」と確信していたんですがメーカーがちっとも対応してくれないままディスコンになりファームウェアのアップデートも止ってしまったので自力救済するしかないということで、自分で対応しました。
Nreal Air発売から4年ぐらい経ってますが、当初から「グラデーションが汚い」問題がありました。Diplay Portでの入力は確実にRGBなのにパネルの表示はなんかおかしい。どうにかならんのか?とずっとモヤモヤしてたわけです。

XREAL Oneシリーズではグラデーションが改善されていますが、実はこれデバンドという画像処理をX1チップ側で施していると話が後日判明します。

先日Airのファームウェアを改造していたところ色々判明しました。
公式ファームウェアには、内部でYCbCrと名付けられているパネル経路があります。
ただし、OLEDへ送られる形式のsubsamplingまでは確定できていません。YCbCr 4:2:2や4:2:0などと決めつける根拠はないため、ここでは単に「not RGB」と呼びます。
今回のビルドは、公式イメージ内に存在するRGB profileと4-lane OLED設定を組み合わせ、2DとFull-SBSをRGB888のままOLEDへ送ります。


左がRGB、右が公式ファームウェアの見え方を再現した模式図です。実際のパネルを撮影したものではありません。
違いが分かりやすいのは、緩やかに色が変わるグラデーション。公式経路では斜めに連なる鱗状の階調境界が見えますが、RGBではかなり滑らかになります。
なんと、RGB表示をすることで文字の輪郭がおかしくなる問題がかなり軽減されます。でも消費電力は増えます!
なお、720pは公式のハードウェアスケーラがRGBに対応していなかったためYCbCr経路を使います。720pまでRGBになるわけではありません。
720pしか出せない機器をつなぐ
mode 1のEDIDへVIC 4を追加し、1280×720@60を受けられるようにしました。データ上も実際の1280×720 / 74.25MHzが流れ、DPブリッジが1920×1080の全面へ拡大します。
スケーラ自体は公式イメージ内にありますが、通常の2D経路では正しく使える状態になっていません。入力判定、比率、profile、PLL、native解像度へ戻る処理をこちらで構成しています。
Air 2 / Air 2 Proだけでなく、初代Airの720p経路も更新しました。nativeから720pへ入る瞬間だけスケーラ設定を書き、720p表示中は同じレジスタを繰り返し触りません。
以前の候補で出ていたジラジラや縦筋を避けるため、Airでは720p専用のパネルタイミンググループも使っています。
専用スケーラほどの画質ではありませんが、720pしか出せないゲーム機を映す用途には十分実用的でした。
Full-SBSを90Hzで動かす
Air 2 / Air 2 Proには、公式ファームウェアにも3840×1080@90Hzのモードが存在します。しかし通常のDP link設定では帯域が不足するため、そのままでは正常に表示できません。
Full-SBS 90HzのときだけHBR2を有効化することで、3840×1080@90Hzを正常に表示できるようにしました。
初代Airも従来どおり、パネル本来の縦1200ピクセルを使った3840×1200@90Hzで動作します。
どちらもFull-SBSはRGB表示です。
USBデータがない接続でも音を出す
HDMI→USB-C変換器や一部のゲーム機との接続では、映像と給電だけでUSBデータが運ばれません。この場合、USBオーディオを使えません。
MCUはUSBのSET_ADDRESSを監視し、約5秒待ってもホストからUSBアドレスを割り当てられなかった場合だけ、DP音声へ自動的に切り替えます。
今回は内部の音声ルートを開くだけでなく、LPCM対応EDIDへ完全に切り替えてホストへ再公告します。保存済みの音量もSmartPAへ復元します。
EDIDを再列挙するため一時的な暗転があります。対象変換器では、切り替えの完了までおよそ10~11秒でした。
PCへUSB-C直結した場合はUSBアドレスが割り当てられるため、USBオーディオを維持します。
HDMIを抜き差ししても自動復旧する
HDMI変換器へ給電したまま、入力側のHDMIだけを抜き差しすると、接続済みなのに映像が壊れた状態で止まることがありました。
今回のMCUは、正常時には出ない複数の状態値が一定回数連続したときだけ、HPDに関係するB6を一度反転します。同じ異常状態で何度も再訓練を繰り返すことはありません。
Air 2 Proでは、連続したHDMI抜き差しでも数秒で映像が自動復旧しました。Air第1世代にも機種に合わせた同様の処理を入れています。
ただし、HDMI変換器ごとにEDIDやHPDの扱いは違います。すべての変換器で同じ動作を保証するものではありません。
初代Airのファームウェアも更新
今回の公開に合わせて、前回公開したAir用ビルドも大きく更新しました。
| 更新項目 | 内容 |
|---|---|
| RGB | 1080p / 1200pの2DとFull-SBSをRGB化 |
| 720p | スケーラ設定を遷移時だけ適用し、専用タイミンググループで安定化 |
| 自動DP音声 | LPCM対応EDIDを再公告する完全切替へ変更 |
| 再接続 | 給電を維持したHDMI抜き差しから自動復旧 |
| 状態追従 | 電源投入、DP再起動、解像度・モード変更後に正しいRGB / scaler状態へ再収束 |
| 検証 | RGBグラデーション、range swatch、左右パネルレジスタを追加確認 |
前回の記事を見て生成したair-dp.binとair-mcu.binは旧版です。最新版のリポジトリへ更新し、DPとMCUの両方を作り直してください。
消費電力は増える
RGB化には代償があります。
同じ入力タイミング、最低輝度でグラス全体のUSB入力電力を測定したところ、初代Airでは約0.18~0.19W、Air 2では約0.17~0.18W増えました。割合ではおよそ13~16%です。
増えた入力電力の大部分は最終的に熱になるため、同じ条件では発熱も増えると考えられます。ただし、表面温度や内部温度の上昇量は測定していません。
画質とのトレードオフとして理解してください。
どこまで検証したか
Air 2とAir 2 Proの両方へ、公開対象のDP / MCU pairを実際に書き込んで確認しました。
- 1920×1080の60 / 72 / 90 / 120Hz
- Full-SBS 3840×1080の60 / 72 / 90Hz
- 1280×720@60の全面拡大
- RGBから720p、720pからRGBへの復帰
- RGBグラデーションでの色順、縦筋、ちらつき
- USBデータのない変換経路での自動DP音声と保存音量
- 給電を維持したHDMI抜き差しからの自動復旧
- Air 2 / Air 2 ProそれぞれのAPP、BOOT USB PID
- 完全電源断後の起動とDP版数
初代Airについても、1080p / 1200p、Full-SBS、720p、RGB表示、音声、再接続を再確認しています。
詳しい測定値とレジスタはGitHubのverification文書へまとめました。
既知の制限・相性問題
- Air第1世代とBeam ProのNebulaは併用できない。純正へ戻す必要がある。
- RGB化により消費電力と発熱が増える。
- 720pはRGBではなく公式スケーラ経路を使う。補間方式や画質の定量評価はしていない。
- 自動DP音声とHDMI抜き差し復旧は、実機試験した変換器での結果。すべての変換器との互換性は保証しない。
- DP音声へ完全切替すると、純正動作と同じくUSB複合デバイスが閉じる。
- イメージの生成はWindows / macOS / Linuxで可能。実機への書き込みを確認したのはWindows。
- パッチ済みかどうかは版数表示では判別できない。生成SHAを手元で管理する。
どうやって改造イメージを検証しているか
配布しているのはファームウェアそのものではなく、利用者が自分で用意した公式イメージを手元で変換するビルダです。
ビルダとフラッシャーは、次の項目を照合します。
- 公式入力のSHA-256、project code、コンテナCRC
- すべての変更箇所の変更前バイト
- 生成結果の固定SHA-256、CRC、DP bank tag、変更バイト数
- EDIDの解像度、リフレッシュ、VIC、チェックサム
- DP helperの全状態ベクタ
- MCUの表示経路、音声、再接続policy
- 接続中の機種とUSB PID
- 対応する公式復旧イメージ
判定を無効化する--forceは用意していません。
ファームウェアの作り方と書き込み
Python 3.10以降を用意し、自分で入手した指定バージョンの公式ファームウェアを所定の場所へ置きます。公式ファイルは復旧にも使うため、必ず別の場所にもバックアップしてください。
Air 2 / Air 2 Pro:
python xreal/air2/build_dp.py --src firmware/air2/1140 --out air2-dp.bin
python xreal/air2/build_mcu.py --src firmware/air2/09.1.00.180_20240507.bin --out air2-mcu.bin
python xreal/mcu_flash.py --image air2-mcu.bin --flash
python xreal/dp_flash.py --image air2-dp.bin --flash
初代Airの更新:
python xreal/air/build_dp.py --src firmware/1140 --out air-dp.bin
python xreal/air/build_mcu.py --src firmware/07.1.02.387_20240428.bin --out air-mcu.bin
python xreal/dp_flash.py --image air-dp.bin --flash
python xreal/mcu_flash.py --image air-mcu.bin --flash
AirはDP→MCU、Air 2 / Air 2 ProはMCU→DPです。READMEに表示されるSHAと書き込み順を確認してから実行してください。
公式へ戻す・起動しなくなったとき
公式ファイルを所定の場所へ残した状態で、MCU、DPの順に戻します。
python xreal/mcu_flash.py --restore --flash
python xreal/dp_flash.py --restore --flash
DPブリッジがfallbackへ落ちた場合は、版数が1109になり、60Hz固定でモード切替不能になります。対応するDPイメージを書き直してください。
MCUが起動せずUSB接続と切断を繰り返す場合は、ボタンを保持したまま接続してbootloaderへ入り、公式MCUを全書き戻しします。
開発中には何度も壊しましたが、公式ファイルを残していたため復旧できています。失くしたら知りません。
GitHubで公開中
ビルダ、書き込みツール、診断ツール、コンテナ形式とHIDプロトコル、Air / Air 2系の設計文書、実機検証結果をnyan Real / Firmware Kitで公開しています。
公式ファームウェアとパッチ済みファームウェアは含まれません。指定された公式ファイルを利用者自身が用意し、ローカルで改造イメージを生成する方式です。
動作不良や別環境での検証結果はIssueへどうぞ。ただし、公式ファームウェアの入手方法、ファームウェアの添付、ダウンロードリンクを含む投稿には対応しません。
おまけの宣伝
XREAL Air / Air 2 / Air 2 Pro向けに写り込み防止具 Slimを公開&販売しています。バードバス光学系の宿命である下からの写り込みを防止するためのパーツです。

おしまいに
前回の記事の最後では「Air 2でも720p対応とHBR2の有効化はできた」と書きました。
そこからさらに掘ったらRGB経路まで見つかり、初代Airにも反映できました。720pと90Hzだけの予定が、Airシリーズまとめて表示経路を作り直す話になったワケ。
Air 2もAir 2 Proも、まだ本気を出してなかったということですね!
ちなみにXREAL Beam Proの裏設定の裏設定で選択できる3D SBS 3840×1080 90Hzはこの改造ファームウェアじゃないと動きません。公式がやらなかった理由は…たぶんNreal Lightでできないからだと思うけど発熱やらなんやらも関係してくるので自己責任と言うことを忘れずに!
nyan Real / Spatial Wallと組み合わせるのはもちろん、普通の外部ディスプレイ、720pゲーム機、Full-SBS用グラスとしても使い倒せますよ。
現場からは以上です。

