シェーダーのデバッグ用の座標視覚化関数の作成 - Yumuru/YuzuServer_ShaderWiki GitHub Wiki

シェーダーで作品を作るときに座標系の扱いはとても重要。
最初にシェーダーを書くときや、シェーダーを書いている時にいろいろと値を調べたくて、よくそのまま値を色として出力していた。
例えば、UnityのQuad (ただの四角形)に設定された座標をそのまま色として出力すれば次のようになる
xの値をred, yの値をgreenとしている。

これよりも良いものがほしい。

完成したコードは次

float3 hsv2rgb(float h, float s, float v) {
  return ((clamp(abs(frac(h+float3(0.,2.,1.)/3.)*6.-3.)-1.,0.,1.)-1.)*s+1.)*v;
}

float debug_outerFrame(float2 st, float width) {
  float2 p = -.5 + st;
  float2 dst = abs(-.5 + abs(p));
  float d = -width+min(dst.x, dst.y);
  float l = d <= 0 ? 1 : 0;
  return l;
}

float debug_circle(float2 st) {
  float d0 = -.03 + length(st);
  float d1 = -.003 + abs(-.05 + length(st));
  float l0 = d0 <= 0 ? 1 : 0;
  float l1 = d1 <= 0 ? 1 : 0;
  return l0 + l1;
}

/* これを使う
 * st              : 座標
 * color_intensity : 色と等高線の強さ
 */
float4 debug_st(float2 st, float color_intensity) {
  float2 repst10 = frac(st*10);
  float2 repst2 = frac(st*2);
  float frame10 = debug_outerFrame(repst10, 0.02);
  float frame2 = debug_outerFrame(repst2, 0.01);
  float frame = max(frame2, frame10);
  float theta = atan2(st.y, st.x);
  float h = theta/(2*UNITY_PI);
  float s = color_intensity;
  float v = frac(length(st)) * color_intensity;
  float3 colbk = hsv2rgb(h, s, v*.5);
  float3 colline = hsv2rgb(h, .3*color_intensity, 1);
  float3 col = lerp(colbk, colline, frame);
  float circle = debug_circle(st);
  col = max(col, circle);
  return float4(col, 1);
}

とりあえず、0.1間隔毎に細い線を、0.5間隔毎に少し太めの線をいれてみた。

まあ、これだけではしょうがないので、色をつけようと思う。
ただ、xやyの座標の値をそのままrやgの値に変換しては困る。
0未満の値や1以上の値が表現できない。
そこで、座標上の角度とhsv色座標系を使ってみる。HSV色空間 - Wikipedia

(x, y)の値の範囲がそれぞれ 0~1 の座標を-0.5した値をそのまま色に出力すれば、次のようになる。

そして、この座標系による任意の点pに対して、atan2(p.y, p.x)をとると、角度が -PI~PI の範囲でとれる。

hsvをrgbに変換する関数([汎用関数]HSV2RGB 関数 - Qiita)を使い、色に変換する。
角度を色相に(Hue)、原点からの距離を明度(Value)にしてみる。

線と合わせて色を調整して、、、、こんなもん

範囲を広くすればこう、、、

原点にあたる点を追加

初期の座標だとこれ。


sinで座標を歪ませてみた。どのように歪んでいるかは白い線を見ればわかるけど、等高線のせいでややこしくなっている。

色や等高線の出力の強さを設定できるようにした。

⚠️ **GitHub.com Fallback** ⚠️