- モニターのピクセル内にあるサブピクセルをゲームのマスとして使うSnakeゲームで、小さすぎるためまともにプレイするには顕微鏡が必要
- 既存のJavaScript Snakeをベースに、列位置ごとの色と
mix-blend-mode: lightenを組み合わせ、同じ物理ピクセル内の複数のサブピクセルが同時に見えるようにしている
- 正常に動作するにはRGB stripeのサブピクセル構造と、CSSピクセル・物理ピクセルの整列が必要で、iMacではズームアウトで合わせられたが、iPadでは通用しなかった
- 顕微鏡で確認すると、sRGBの緑が緑のサブピクセルだけを点灯させるのではなく、赤・青も一緒に点灯させており、最新ディスプレイのより広い色域が原因だと判明
- Lab colorを使うとiMacで赤と緑のサブピクセルを分離できたが、ピクセル構造がRGB stripeから外れつつあり、長期的な互換性は弱い
サブピクセルをゲームボードとして使う
- このSnakeゲームは、モニターの通常のピクセルではなく、ピクセル内部の赤・緑・青のサブピクセルをゲームのマスのように使う
- 近くで見ると画面のピクセルは複数のサブピクセルで構成されており、離れて見ると人間の目にはこれらの光が混ざって1つの色に見える
- クリスマスにもらったマクロレンズで複数の画面を撮影し、ディスプレイごとにサブピクセルの形が異なることを確認した
- Chevron形状
- stripe形状
- diamondパターン
- こうした配列の違いはサブピクセル幾何構造と呼ばれ、作者のiMacはRGB stripe構造を採用している
実装方法と顕微鏡で明らかになった限界
- 15年前に作ったJavaScript Snakeをサブピクセル用に変更する基本実装は比較的単純だった
- ゲームの列数を減らす
- 特定の列のSnakeブロックが特定の色で表示されるようにする
mix-blend-mode: lightenを適用し、同じピクセル内に複数のブロックがあってもすべて見えるようにする
- 実際に動作するには、2つの条件を満たす必要があった
- ユーザーがRGB stripeサブピクセル構造のモニターを使っていること
- ブラウザのCSSピクセルが物理ピクセルと整列していること
- CSSピクセルの整列はズームアウトで合わせられたが、この方法はiMacでしか動作せず、iPadでは失敗した
- 実装はすぐに終わったものの、サブピクセル単位の表示を目で確認できなかったため、オンラインで購入した安価な顕微鏡で実際の画面を撮影した
- 顕微鏡で見ると、緑色を表示する際に緑のサブピクセルだけが点灯するのではなく、複数のサブピクセルが同時に点灯していた
- 最初はバグを疑ったが、コードに問題はなかった
- 単色の緑を確認すると、iMacでは緑だけでなく赤・青のサブピクセルも点灯していた
- 携帯電話でも緑色が赤のサブピクセルを弱く点灯させていた
- サブピクセル幾何構造ページの運営者に問い合わせた結果、原因はsRGB標準と最新ディスプレイの色域の違いだった
- sRGBは画面性能と色域がより狭かった時期に作られた
- 最新の画面で緑のサブピクセルだけを点灯させると、sRGBの緑より彩度の高い色が出る可能性がある
- 望みどおりのsRGBの緑を正確に表示するには、赤、場合によっては青も一緒に加える必要がある
- RGBの色定義をLab colorに変えると、より大きな色空間を活用してiMacで赤と緑のサブピクセルを分離できた
- ただしピクセル幾何構造はRGB stripeから離れつつあり、将来のサブピクセルは現在とまったく違う形で点灯する可能性があるため、この方式を長く維持するのは難しい
1件のコメント
Hacker Newsのコメント
リンク先のSubpixel Zooの記事を見て、PenTileが今でも非常に広く使われていることを知った
初めて使ったPenTile画面はMotorola Droid 4だったが、本当にひどかった。小さな文字は文字色と背景色によって読みにくく、色同士の間隔が大きいため、赤/緑/青の単色領域がチェッカーボードのように見えた
VRが普及してスクリーンドア効果という言葉が一般的になる前から、すでにそういう感じがあった。なのでPenTileが今でも使われていることに驚いたが、おそらく改善されたか、サブピクセル間隔が小さくなったか、より高い解像度とピクセル密度がDroid 4で見えていた弱点を隠しているのだと思う
横/縦軸で青、緑、赤、緑の順だったため、赤サブピクセル1つが緑2つと青1つ分だけ離れていた
現代のPenTileディスプレイは通常、三角形配列を使う: https://static1.xdaimages.com/wordpress/wp-content/uploads/w...
テキストレンダリングの専門家ではないが、この三角形配列なら、線形配列よりRGBサブピクセルの組み合わせをずっと近づけられそうに見える。加えてDroid 4は解像度も低かった。Appleは2010年に330ppiへ移行したが、Droid 4は2012年で275ppiだったので当時基準でも低い方で、PenTileがサブピクセルを3分の1減らしたことでさらに悪化していたはずだ
最近のGalaxy S25は416ppi、iPhone 16は460ppiなので、ピクセル数はずっと多い。ピクセル密度が最も大きく効くだろうが、現代ディスプレイの三角形配列も役立っていると思う
ヘビの動きが変なのは、サブピクセルが正方形ではないからだ
実際の画面でユーザーから見てどの方向へ進んでも同じ速度に見えるように、サブピクセル基準では縦に対する横方向の移動速度をもっと高くするとよさそう
アーケードのレトロゲームにこだわって、27インチのクアッドシンク・アナログRGB CRTを載せた高級エミュレーション筐体を自作した立場として、この動画はよかった
緑ピクセルの問題に遭遇したと説明した瞬間、何か面白いことを学べそうだとすぐ感じた。サブピクセル構造や蛍光体の色度のようなものは、掘り下げるほど面白い沼で、今日のOLEDやQLEDのようなディスプレイにもなお大きく関係している
80〜90年代のクラシックなアーケードやコンソールのレトロゲームを遊ぶなら、CRTでやる方がずっと良く、よりオリジナルに近い。エミュレーションで遊ぶならCRTエミュレーションのピクセルシェーダーを有効にすればよい(CRT Royaleが良い)。このピクセルアートは、当時の開発者やアーティストがCRTの色混合と走査線の自然なアンチエイリアシングを意図的に活用して作ったものだ。本来意図された方法で見る価値がある: https://i.redd.it/9fmozdvt6vya1.jpg
この話のせいでCRTシミュレーションの沼にはまったが、実際こういうものがある
https://github.com/blurbusters/crt-beam-simulator
CRTからLCDへ移行していた時代にゲームをしていたが、CRTのグラフィックの方を好む人はいなかった
本当の劣化は、ゲームがPCからコンソールへ移って専用サーバーが死んだ時だった。昔は遅延10msのサーバーを選んでいたのに、今では60〜100ms以上でも問題ないと見なされている
TVにつないだのか、安いモニターだったのか、高いモニターだったのかで違ったし、確実に言えるのはCRTの方がぼやけていたという程度だ。提示された比較画像は明るさが完全に違っていて誤解を招く。LCD/LED側が正しいガンマを使っていないように見える
適当なCRTを使えば肌色が緑がかる可能性もかなりあったし、CRTの色アーティファクトは深刻になり得た。エミュレーターでジャギーを減らすために画像をぼかすのは理解できるし、レトロなCRT効果も楽しい装飾だが、「ゲームが意図した見た目」だという主張は受け入れがたい。90年代の音楽は安物スピーカーと道路騒音の中で聴いてこそ「意図された方法」だと言うようなものだ。それは単に当時できた最善だっただけだ
CRTとともに育ったが、CRTで「より良く見える」ゲームはごく少なく、たいていは点滅効果を作るためにインターレースを使ったゲームくらいだった。加えて光線銃はタイミングのためにCRTが必要だ
それ以外ではCRTはレコードに似ている。優れているとする理由をいろいろ作り出す人もいるが、実際にはそうではない
本当に興味深かった。色空間と、それがサブピクセルにどう適用されるかをたくさん学べて、動画を見てよかった
ゲームプレイ面では、ボードをもっと大きくし、各サブピクセルを通過する際にヘビの速度を補正すべきだと思う。左右移動ではRからGへ行く場合、BからRへ行く場合より横方向の移動量が小さく、縦移動は横移動に比べて各ステップが非常に大きい
位置が色スペクトルのどこにあるかに応じて各アニメーションステップの速度を比率で調整すれば、かなり簡単に解決できそうで、そうすればずっと洗練された感じになるはずだ
すごい。1440pモニターでヘッドバンド型拡大鏡[1]を使い、速度を10倍遅くしたらプレイできた
ピクセル密度がもっと高いなら、本物の顕微鏡が必要になりそうだ
[1] https://www.amazon.com/ProsKit-MA-016-Personal-Headband-Magn...
QBasic NibblesもANSIの罫線描画文字で同じことをしていた
縦の「セル」の半分だけを使うテキスト文字があり、前景色/背景色をうまく組み合わせることで、テキストモードで縦解像度を2倍にできた
私のように愚かにも実際にプレイしようとするなら、Snake speedの値は逆に動作することを知っておくとよい
Windows XPでClearTypeを調整する楽しさを覚えているほど年を取った人はいる?
低解像度LCDでより滑らかなテキストをレンダリングするための優れた回避策だった
サブピクセルを見る最も簡単な方法は、ディスプレイに水滴を1つ乗せることだ。おそらくこの方法で100倍拡大くらいになるはず :)
拡大/縮小でCSSピクセルを実ピクセルに合わせる部分は、単に0.25pxのような単位を使えばいいのではないかと思う
あるいはJavaScriptで
window.devicePixelRatioで割って動的に合わせることもできそうだ