OpenMSX用TVフィルタ改造版

導入と使用方法

OpenMSXのTVフィルタが微妙なので、NTSCにじみフィルタのThemaister's NTSC shaderを移植しました。

ファイルを2つ、所定の場所に置くだけで簡単に利用できますので良ければお試しください。

 

github.com OpenMSX_TV_Shader←こちらからどうぞ

セットアップや使用方法はgithubにまとめてあります。

 

tv_ntsc_vividフォルダには彩度協調版もあります。

 

Themaister's NTSC shaderとは?

表示時に一度NTSC信号に変換し、クロスカラー(色の干渉)やドット妨害(暗いドット)の処理を施した後にRGBに戻して表示する物です。

クロスカラー(Cross color)は色の滲みだし(白黒のエッジに虹色が出たりする現象)で、ドット妨害(Cross Luminance)はドットが暗くなる現象(文字の一部や左右が暗くなるなど)です。

Cross Color

 

Cross Luminance

ブラウン管エミュレーションや本体側の信号特性による違いは再現されず、一般的なNTSCの信号の仕組みで発生する現象のみを再現しています。

NTSCの映像信号はY/C信号といって、明るさは可変周波数、色は固定周波数で2つの波を合成して送っているので、お互いに干渉することがあるという事のようです。

p6ers.net

 

調整可能項目

スキャンラインはCatapultで調整可能です。個人的には75%ぐらいが良いかと思います。

その他は、シェーダーを直接弄る事で少しは調整できます。

  • ぼかしの調整:
       tv.vert 13行目
       #define BLUR_MILTIPLE   (10.0/32.0)
       ※小さいほどくっきりする。大きいほどぼやける。0.5未満がよさそう。
  • ドット妨害の調整
       tv.frag 40行目
       #define FRINGING    0.75
       ※大きいほどドット妨害が強くなる。0.0~1.0の範囲
  • クロスカラーの調整
       tv.frag 39行目
       #define ARTIFACTING 1.0
       ※小さいほどクロスカラーが弱くなる。0.0~1.0の範囲
  • 簡易的な彩度調整
       tv_ntsc_vivid\tv.frag 16行目
       #define vSATU(x)  (x * 1.25)  // 彩度を強調する
       ※tv_ntsc_vividにあるtv.fragを使用する場合、彩度調整ができます。

彩度強調あり (tv_ntsc_vividにあるtv.fragを使用)

彩度強調なし (OpenMSX_TV_Shader直下のtv.fragを使用)


各自お好みの設定で遊んでみてください。

実際のコンポジットビデオ接続程ではないにせよ見づらくなります。が、謎にカラフルな色の滲みなどが懐かしくも不思議な美しさがあるように思います。

 

課題

仮実装となった理由としていくつか問題点があります

 

1.OpenMSXから渡されるパラメータが少ない

OpenMSXは表示側にスキャンライン、ブラー等の調整値をCatapult等で変更してリアルタイム渡せるようになっていて、それで好みの映像に調整したりできるのですが、TVスケーラーのシェーダーにはブラーが送られず、スキャンラインの値しか渡されないため、にじみを調整できないのです。

 

本来であればBlurスライドバーの値で動的ににじみを調整したいのですが、値を渡してくれませんので出来ません。

やろうとするとOpenMSX本体側のプログラムを弄る必要が出てきてしまいますので、なかなか大変です。

 

2.OpenMSXのシェーダーが1パスしかない

本来であれば

  1. 全画面分をNTSC信号情報に変換して書き出し(*1)
  2. 書き出された(*1)を見ながら全画面分をRGBに戻して書き出し(*2)
  3. 書き出された(*3)を見ながらぼかしやコントラストやシャープネス調整

と分けて行わないととんでもない計算量と見づらいシェーダープログラムになります。

OpenMSXのシェーダーでは1パスですが、1パスで出来る事には限度があるので、今回は1と2の処理だけまとめて1パスで行っています。

 

3.波干渉周期や範囲の調整にはThemaister's NTSC shaderの深い理解が必要

Themaister's NTSC shaderがやっている処理は記述はシンプルですが原理が難解で、一部だけ弄ってしまうと意図しない変な映像が出来上がってしまいます。

処理的には

  1. ドット毎に一度色信号を周期的振幅を持つ情報に変換し、輝度と色を干渉(特定の計算式で合成し)それに再び周期的振幅を付ける。(*1)
  2. (*1)で変換されたピクセルを複数参照し、振幅に合わせた重みづけで合成して1ドットのRGBとして復元する(*2)

なのですが、(*1)の振幅周期と(*2)の合成フィルタが密接な関係にあり、自分からすると知識不足で魔法にしか見えないので、振幅周期を調整できないのですよね。

MSXの映像信号にわせた干渉に近づけるのはこの部分の調整も必要なのですが、知識不足により保留としました。

周期は変更できないので、マルチサンプルの幅変更によるにじみの調整にも限界があります。(細かい調整が出来ない&妙なエッジがでたりする)

 

おまけ:GV-USB2でキャプチャしたCASIO MX-10の映像

GV-USB2はY/C分離処理があまり良く無くてグラディウス2の画像だと右下の「SPEED」や「ENABLE」が変なつぶれ方をしていますね。テレビだともっとちゃんと文字が見えるのですが。シャープネス処理によるエッジのジラつきも目立ちます。

実際のテレビでもGV-USB2と同じつぶれ方をする方もおられるみたいなので、この辺もなかなか奥が深いです。

 

与太話

今回は教えて頂いたシェーダーを移植してみる実験という事でこのあたりで。
突き詰めるにはもう少し勉強が必要そうですし。

 

自分のはコードが汚いのですが、元のシェーダーは2ステージ以上に分けた簡潔な記述です。Themaister's NTSC shader や RetroArchの処理 glsl-shaders/ntsc at master · libretro/glsl-shaders · GitHub などを参照いただくと良いかもしれません。

 

OpenMSX本体もシェーダーを数ステージに分けられるならもう少し気楽にできるんですけども。