世界を動かす技術を、日本語で。

Macでのゲームのぼやけた描画

概要

  • MacBookのノッチ付きディスプレイ でのフルスクリーンゲーム描画問題の解説
  • CGDisplayCopyAllDisplayModes APIの仕様と問題点
  • ゲーム開発者・ユーザー が取るべき対策
  • 主要な 影響タイトル と正しい解決策の紹介
  • Appleが改善すべき点 と今後の提案

MacBookのノッチ付きディスプレイでのフルスクリーンゲーム描画問題

  • Appleノッチ付きMacBook では、ゲームがフルスクリーン時に 誤った解像度 で描画される現象
  • 多くのゲームが CGDisplayCopyAllDisplayModes で取得した最初の解像度を採用しがち
  • この最初の解像度は 画面全体(ノッチ含む) であり、実際に描画可能な範囲(ノッチ下)とは異なる
  • 結果として 縦方向が圧縮され、ぼやけた表示 になる問題
  • AppKitやCatalyst でフルスクリーンゲームを開発する場合、 解像度選択に注意 が必要

ノッチ付きディスプレイのレイアウトの仕組み

  • 3つの領域 に注意
    • ディスプレイ全体領域 :ノッチやメニューバーを含む
    • セーフエリア(safe area) :ノッチ直下の領域、NSScreenの safeAreaInsets で取得可能
    • フルスクリーンアプリ領域 :メニューバー直下から下端まで
  • CGDisplayCopyAllDisplayModes
    • ディスプレイ全体メニューバー下の領域 両方の解像度を返却
    • リスト内で混在 しており、区別する手段が標準では用意されていない
  • 多くのゲームが リストの最初の解像度 (全体領域)を選び、 描画領域と一致せず 画面が潰れる

具体的な問題例

  • Shadow of the Tomb Raider :3456 x 2234(ノッチ含む)で起動、実際に描画可能なのは3456 x 2160(ノッチ下)
  • 74ピクセルの高さ差 が画像の圧縮・ぼやけの原因
  • safeAreaInsets はセーフエリアのみを示すため、 フルスクリーン領域と完全一致しない
  • 正しい解像度選択 には工夫が必要

解決策・ワークアラウンド

  • ゲームユーザーは 16:10解像度 を選ぶことを推奨
  • 開発者向けには safeAreaInsetsを利用しつつ、より広い解像度をフィルタリング する方法を提案
    • 例:NSScreen拡張による safeAreaResolutions メソッド
    • safeArea内に収まる解像度のみを抽出するロジック(下記サンプルコード参照)
extension NSScreen {
    func safeAreaResolutions() -> Array<CGDisplayMode> {
        let screenResolution = frame
        let safeAreaInset = safeAreaInsets
        let safeScreenResolution = CGSize(
            width: screenResolution.size.width - (safeAreaInset.left + safeAreaInset.right),
            height: screenResolution.size.height - (safeAreaInset.top + safeAreaInset.bottom)
        )
        let safeAreaAspectRadio = safeScreenResolution.width / safeScreenResolution.height
        let screenNumber = deviceDescription[NSDeviceDescriptionKey.init("NSScreenNumber")] as! CGDirectDisplayID
        guard let resolutions = CGDisplayCopyAllDisplayModes(screenNumber, nil) as? Array<CGDisplayMode> else {
            fatalError()
        }
        return resolutions.filter { resolution in
            (CGFloat(resolution.width)/CGFloat(resolution.height)) > safeAreaAspectRadio
        }
    }
}
  • この方法では 4:3解像度 など一部が除外される副作用あり
  • 根本解決はAppleによる対応が必要

影響を受ける主なゲームタイトル

  • 影響あり
    • Shadow of the Tomb Raider :デフォルトで潰れた解像度
    • Control Ultimate Edition :独自の解像度リストを生成、ネイティブ解像度が選べない
    • No Man’s Sky :潰れた解像度が初期値、両方の解像度が混在
    • Riven :潰れた解像度が初期値
    • Stray :16:10でない解像度が初期値
  • 正しく動作
    • Cyberpunk 2077 :16:10(例:1728×1080)でデフォルト起動、最大解像度も正しい
    • World of Warcraft :レガシーAPI利用でノッチ領域まで描画可能、正しい解像度

Appleへの改善要望と今後の提案

  • HIG(Human Interface Guidelines)の更新
    • ノッチ・解像度選択問題を明記し、ベストプラクティスを提示
  • Game Porting Toolkitサンプルの改善
    • 解像度選択の実装例を追加
  • CGDisplayMode APIの拡張
    • フルスクリーンCocoaアプリ向けの解像度のみをフィルタ可能に
  • ゲーム向け新APIの開発
    • 解像度リスト取得などの煩雑な処理を自動化
  • ハードコード解像度リストの回避推奨
    • コントロールのような一律リストは非推奨、 実際の描画領域に合わせて動的生成 が理想
    • レンダースケール 設定のような柔軟なアプローチも選択肢

まとめ

  • ノッチ付きMacBook でのフルスクリーンゲームは 解像度選択に注意 が必要
  • ユーザー・開発者双方 が正しい設定や実装方法を知ることが重要
  • Appleによる公式対応・ガイドライン更新 が根本解決への鍵

Hackerたちの意見

いや、Appleだけじゃないよ… これ、2008年にXbox 360でも見つけた問題なんだ。テレビにはオーバースキャンがあって、その設定によって解像度がずれちゃうんだよね。でも当時は、オーバースキャンのセーフエリアに合ったレンダリングターゲットを作れなかったんだ。XNAがScreen SafeAreaの矩形を追加して、みんなを助けようとしたけど、それでも意識して開発しなきゃいけない問題だった。今は、好きなバックバッファサイズを作れるようになったから、1:1のものを作るか、DLSSを使ってセーフエリアに1:1を目指すのがベストだね。著者が報告してくれて嬉しいけど、最終的には開発者が「画面解像度 != レンダー解像度」を理解することが大事だよ。wgpuやvulkan、AppKit、SDL、glfwなどを使ってる人はこれを知っておくべきだね。

もし私の理解が正しければ… あなたは、グラフィック計算時間を無駄にしないために、少し小さなサーフェスにレンダリングしたいってことだよね。でも、それでもHDMIのスキャンアウトのために1080にアップスケールされて、テレビのオーバースキャンでまた歪むことになる。そうなると、最初に解決しようとしていた問題よりも、もっと深刻な問題を引き起こす気がするんだ。 (それに、テレビのオーバースキャンは解決済みの問題だよ。ゲームは特定の小さなフレームをレンダリングするのではなく、ユーザーがカスタムFoVやカスタムHUD/GUIサイズを設定できるようにすれば、何も妥協せずに3つの問題を同時に解決できるんだ。)

これはMacでのゲーム市場の規模を物語ってるね。小さくて残念だよ。

実際、すごく小さいんだ。Steamのハードウェア調査によると、MacはSteamユーザーの1.88%しかいないんだ。これはLinuxよりも少ないから、ほとんどの開発者が気にしないのも納得だね。

WoWについてここで言及されてないのは、ノッチを避けるUIオプションも考慮されていたことだね。C_UIの関数を呼び出してセーフエリアを取得し、そのエリア内に収まるようにUIParentをリサイズしつつ、ゲームはディスプレイの真上までレンダリングするんだ。

WoWはmacOSを一級市民のように扱うのが本当に上手だったんだ。Blizzardが新しいゲームでmacOSのサポートをやめたのは残念だね。

これって、AppleがMacでのゲームにどれだけ無関心かを示してるよね。何千円もかけてMBPやM Studioなどの複数のMacデバイスを買ったのに、ハードウェアじゃなくてAppleのクソみたいなゲームソフトのアプローチに足を引っ張られてるのが悲しいよ。彼らがそうする理由は分かるけどね。AppleはMacゲームからiOSのように不当な30%の取り分を取れないからだよ。昔、ある先生が言ってたことが今でも真実だと思う: 「すべてはお金のこと、特に非金銭的な理由に見えるものはね。」

彼らの大きな問題は、ドキュメントが全然ないことだと思う。関数のシグネチャの大きなリストはあるけど、実際にどう使うかを知りたいなら、4年前のWWDCのセッションを探して、まだ正確であることを願うしかないんだよね。

でも、なぜそうするのかは分かるよ。Appleは、Macのゲームから不当に取っている30%のカットを、iOSのように取れないからね。Appleがわざと体験を妨害する理由はないよ。そこから何も得られないし。この記事で言及されているほとんどのゲームがMac App Storeにあることを考えると、その主張はさらに意味がなくなる。Appleはカットを取れるからね。 https://apps.apple.com/us/app/control-ultimate-edition/id650... https://apps.apple.com/us/app/shadow-of-the-tomb-raider/id14... https://apps.apple.com/us/app/riven/id1437437535 https://apps.apple.com/us/app/cyberpunk-2077-ultimate/id6633... https://apps.apple.com/us/app/stray/id6451498949 これは明らかにハンロンの剃刀の例だね。Appleプラットフォーム向けに開発していて、フィードバックを出したことがある人なら、Appleの無能さと無関心には気づいてるはず。

何台もMacデバイスに何千ドルも使ったんだけど… そりゃ、彼らが変える理由なんてないよね?

それが残念だよね、Mac Miniはゲーム用のしっかりしたコンピュータなのに。

確かに、Macではゲームに関してはあまり気にしてないけど、この特定の問題は「魔法」を試みてるせいだと思う。ノッチを導入すると、「ここにあるけど実際には使えない」エリアができちゃって、Appleはそれをソフトウェアのおかげでうまくいくって宣伝してる。でも、結局どのアプリも何らかの形で対処しなきゃいけないし、画面のスペースや解像度を気にするアプリはハックが必要になる。境界を押し広げるすべての機能に対して、問題を解決するための抽象化レイヤーを提供するのと同じことになるよ。

ノートパソコンでゲームをしようとは思わないし、「ゲーミングノートパソコン」って「レーシング仕様のバルカロウンジャー」に似てると思ってる。だから、Macでゲームができないって文句を言う人が多い理由が理解できないんだ。ゲームをしたいなら、コンソールかデスクトップPCを買った方がいいよ。白熱した意見だけど、PCとMacを両方持つのは全然アリだからね。物質と反物質みたいな関係じゃないし、銀河が崩壊するわけじゃないよ。

え?これは単にゲームがそのディスプレイに合った解像度にデフォルト設定されてないだけじゃない?私がプレイするゲームでは、最初に設定を確認して、解像度が画面の物理的な解像度に合ってるか確かめるのが常なんだ。もしゲームがそれを無視してるなら、私は小さい倍数を選んだり、ウィンドウモードでやったり、外部ディスプレイでプレイするよ。

数年前に、今でも真実だと思うことを言った先生がいたんだ。「すべてはお金のこと、特に非金銭的な理由に見えるものはね。」これは事実の声明というより、むしろ理想だよね。例えば、ウラジーミル・プーチンに数十億ドルを渡して戦争を始めさせないようにするためにクラウドファンディングをしたいと思ったこともある。ロシアの財政を見れば、実際にそうなったわけだし。彼(そして彼のオリガルヒたち)は、この戦争のせいで予想通りに数十億ドルの収入と利益を失ったからね。それに、貧しい国から豊かな国への移住は、労働者の給料をめちゃくちゃ上げるから、特権のために高額を請求しても、来ることで得られる利益があるんだよね。でも、有権者はそれをあまり好まないんだ。たとえその利益を「市民の配当」として分配してもね。彼らには非金銭的な理由があるんだ。興味深い歴史的な事例については、アパルトヘイトやポストアパルトヘイトの南アフリカ、マレーシア、ナチスドイツなど、いろんなソースからの資料を見てみて。

M3 UltraのMac Studio使ってるんだけど、4Kのパソコンだよ。なんでかわからないけど、StreamLabsで何かをストリーミングしようとすると(ゲームを開いてなくても)、録画がカクカクしてる。どうしてそんなことが起こるのか理解できない。

面白い記事だけど、デモ画像はあまり役に立ってないと思う。どちらの側もあんまり良く見えないな。大体同じに見えるよ。

そうだよね?縦に潰れてるなら、せめて仕切り線も縦に引いて、違いが見えるようにしてほしい!でも、両方の画像はアンチエイリアスされた円のちょっと変なレンダリングに見えるね。

左下はアーティストが作った粗いテクスチャの円を表示してるね。右上は、そのエッジの効いたシャープなテクスチャがアンチエイリアスで柔らかくなってるのがわかる。

でもWorld of Warcraftは古いゲームで、レガシーCoreGraphicsのフルスクリーンAPIを使ってるんだ。そのAPIのおかげでWorld of Warcraftはノッチに描画できるんだ。Macについてあまり知らないけど、ゲームは没入感を得るためにノッチの周りでフルスクリーンでレンダリングするべきだと思ってたけど、UIやゲームプレイのためにセーフエリアを尊重するべきなんだよね。macOSにメニューバーを残すべきなのかな? > Controlはその問題を、自分で解像度を作ることで回避してるんだ。それって面白いね、解像度を列挙するのに苦労して諦めたのか、それとも単に面倒だったのかな。

macOSにメニューバーを残すべきなの? ゲームの実装によるけど、よくそのエリアは黒くてアクセスできないんだ。つまり、カーソルをそこに移動させることもできない。ノッチの上のエリアは、画面に含まれてないみたいな感じで、ノッチがなかったらどうなるかっていうと、M1 Airみたいな感じになるよ。

既存のソフトウェアを壊さずにこれをどう修正できる? リストの順番を入れ替える?

Windowsがやったように、実行中のアプリケーションが既知のレガシーゲームかどうかをチェックするOSコードを作って、ゲームに対してさまざまな機能を偽るっていうのもアリだと思う。どれくらいその手法が残っているかは分からないけど、何年も広まっていて、Windowsのゲーム成功の鍵だったんじゃないかな。

丸みを帯びたコーナーやノッチのある画面が本当にバカみたいだと思うのは私だけ? CRTやその変なジオメトリと何十年も格闘してきたのに、やっと完璧なジオメトリのディスプレイが手に入ったと思ったら、またそれを台無しにして…かっこよく見せようとしてるの?

ノッチを画面面積を奪うバカなものだと思わないで。全体の画面面積を増やすためのものだと思ってみて。ベベルが小さくなることでね。そして、画面のコーナーがノートパソコンの角に近くて、ノートパソコンの角が丸いと、画面の角が丸くないと変に見える。まるで四角いペグを丸い穴に入れようとしてるみたいだね。幸いなことに、これはコンテキスト依存なんだ。だから、Macで本質的に長方形の動画を見ているときは、それが優先される。ノッチの下にだけ表示されて、下の丸いコーナーは消えちゃう。だから、実際の作業用には丸いコーナーの大きな画面(ノッチはメニューバーでは特に気にならない)で、動画用には角が四角い少し小さな画面(ゲームもそうだと思うけど)って感じで、いいとこ取りだね。

スクリーンはOLEDなの?スマホは…個人的にはノッチは意味ないと思うけど、前面カメラのスペースは必要だよね。OLEDなら、アプリに合わせてピクセルをオフにできるから、結局大きなベゼルみたいになるんだよね。

いや、ほんとにバカだと思う。

ノッチ付きのMacBook使ってるけど、全然気にならないよ。これ、MacBookユーザーの間ではよくある意見なんだ。ノッチについて文句言ってる人、ほとんど見ないし。確かにいるけど、少数派だね。

この理由から、LCDでアンチエイリアスなしのフォントの見た目が好きなんだ。ピクセルのシャープな四角い角がはっきり見えるし、でも多くの人は、画面をCRTみたいにするためにアンチエイリアスのぼやけた滑らかさが好きなんだよね。

League of Legendsをボーダーレスモードでやると、BetterDisplayで設定した解像度でレンダリングされて、実際の解像度よりもぼやけちゃう。フルスクリーンだと正しく表示されるから、フルスクリーンを使わざるを得ないんだ。

NSScreenのsafeAreaInsetsを通じて、どうして曖昧な「安全」が単純なrect_below_notchよりも良いの?