Windows Terminalの背景でレイマーチング

Raymarching in Windows Terminal

Windows Terminal 1.6から任意のHLSLのPixel Shadersを実行できるようになったので、Windows Terminalの背景でレイマーチングを実行してみました。

2021-02-16のツイート時点では、Windows Terminal 1.6はまだPreview版なので、GitHubのReleasesページから入手する必要がありました。

2021-03-07現在では、Windows Terminal 1.6からPreviewが外れてMicrosoft Storeから入手できるようになりました。

Windows TerminalのPixel Shaders機能の詳細については、公式ドキュメントをご覧ください。

任意のHLSLのシェーダーのファイルを作成して、Windows Terminalのsettings.jsonの experimental.pixelShaderPath からHLSLファイルのパスを設定するだけで、気軽に任意のシェーダーを実行できます。素晴らしい!

"profiles":
  {
    "defaults":
    {
      "experimental.pixelShaderPath": "C:\\Users\\gam0022\\Dropbox\\windows-terminal\\terminal\\samples\\PixelShaders\\Raymarching.hlsl"
    },

レイマーチング用のシェーダーはUnityで下書きしたものをWindows Terminal用に移植して実装しました。

HLSLのエラーの行番号が表示されないので、複雑なシェーダーを書くのはちょっと苦労しました。

基本的にはUnityのShaderLab用のプロパティや _LightColor0 などのビルドインのシェーダー変数を定数(static const)として宣言する修正だけで移植できました。

Windows Terminal用のPixel Shadersでは、以下のテクスチャのサンプラーや定数が定義されていました。

// The terminal graphics as a texture
// ターミナルの文字などを含んだターミナルのレンダリング結果のサンプラー
Texture2D shaderTexture;
SamplerState samplerState;

// Terminal settings such as the resolution of the texture
cbuffer PixelShaderSettings {
  // The number of seconds since the pixel shader was enabled
  // 秒単位の時間
  float Time;

  // UI Scale
  // UIのスケール
  float Scale;
  
  // Resolution of the shaderTexture
  // ピクセル単位の背景の解像度
  float2 Resolution;
  
  // Background color as rgba
  // 背景の色
  float4 Background;
};

shaderTexture はターミナルの文字などを含んだターミナルのレンダリング結果のサンプラーになるので、今回は背景に加算合成する形でシェーダーを実装しました(加算合成なので後からレイマーチングを加算しても結果は同じになるため、描画順を気にしなてくて良い)。

HLSLのホットリロードでシェーダーライブコーディング環境を実現

Windows Terminal 1.6の挙動では、シェーダーを再コンパイルして結果を更新するために以下の手順が必要だったので、ライブコーディングには不向きでした。

  • experimental.pixelShaderPath で指定したHLSLシェーダーに差分を出してファイル保存
  • Windows Terminalの settings.jsonexperimental.pixelShaderPath の値に差分を出してファイル保存

最初の動画ではシェーダーの描画結果をリアルタイムで更新するために、Vimで2つのファイルを同時編集することで、リアルタイムにライブコーディングっぽいことをしていましたが、かなり操作が忙しいので非実用的でした。

  • Vimの左側ペイン: HLSLのシェーダー
  • Vimの右側ペイン: Windows Terminalのsettings.json

そこで、HLSLの更新を検知して、Windows Terminalの settings.json を書き換えることで、HLSLのホットリロードを実現するスクリプトをnode.jsで実装しました。

これによって、Windows Terminalの背景でHLSLシェーダーライブコーディングを実現できるようになりました!

Windows Terminalの settings.json に毎回差分を出すために、HLSLファイルをコピーした一時ファイルを作成して、元のファイルのパスと一時ファイルのパスを交互に切り替えて experimental.pixelShaderPath に設定するような実装としました。

感想

Windows TerminalというMicrosoft公式のアプリ上でHLSLシェーダーライブコーディング環境を実現できるのは熱いですね!楽しい!!

comments powered by Disqus

gam0022.net's Tag Cloud

gam0022.net

Qiita