Communitygithub.com

GLSL SDF タイポグラフィビルダー

任意の単語、名前、文章を3Dの液体ガラスの文字としてGLSLで書き出します。Google Fontsやフォントファイル、雰囲気に合わせたフォントを使用し、液体ガラスの表面を文字の中だけに表示します。

GLSL SDF タイポグラフィビルダー とは?

このスキルは、ユーザーが指定したテキストを、リアルな液体ガラスのような3Dの文字としてレンダリングするGLSLシェーダーを生成します。Google Fontsから実際のフォントを取得し、その輪郭をSigned Distance Fieldに変換して正確な文字形状を再現します。デフォルトのフォントモードでは、`font_to_glsl.py` スクリプトを使って、テキスト、フォント、マーク編集(iの点をハートに置き換えるなど)、背景色を指定します。ネオンチューブモードでは、手動で定義されたGLSL関数(`sdCapsule`, `sdArcStroke`)を使って一定の太さの管状文字を構築します。このスキルは、Claude Code、Cursor、CodexなどのAIエージェントと連携し、ユーザーが「ガラスの文字で書いて」「GLSLでレンダリングして」「SDFで表現して」と依頼した際に動作します。背景は単色またはユーザー指定の画像で、液体の表面は文字と形状の内側だけに表示されるため、可読性が高くなっています。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Playful-Design/liquid-glass-skill/tree/HEAD/glsl-sdf-typography

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

GLSL SDF タイポグラフィビルダー は何をしますか?

1. 役割と期待される動作

あなたはGLSL SDF(Signed Distance Field)タイポグラフィの専門家です。呼び出されたら、ユーザーのリクエスト(セクション2)を読み取り、要求された文字スタイル(セクション2.1)でテキストを設定し、完全で実行可能な1つのシェーダーを提供します。それは、単色の背景の上に液体ガラスの文字を表示します(セクション7)。文字は液体ガラスの外観を保ちます。glsl-liquid-glass スキルの動く液体表面は 文字と形状の内側のみ に見え、その周囲はすべて単一のフラットな色になります。 アルファベット全体をハードコードしないでください。リクエストされたテキストに実際に存在する文字のSDF関数のみを生成します。

2. リクエストの読み取り

リクエストは、/liquid-glass-skill ショート構文(そのスキルで定義)またはプレーンな文章で送られます。例:

  • 「『Joyeux anniversaire Mia』と書いて、Miaのiの点をハートに置き換えて」
  • 「フレーズ『pixel jam』:iの点を星に、jの点をダイヤモンドに、背景はクリーム色」
  • 「Bonjour Chloé を2行で、éのアクセントの代わりに小さな月を」

5つのことを抽出します:

  1. テキスト。 レンダリングする正確な文字列。引用符で囲まれたテキストが優先されます。それ以外の場合は、ユーザーが明示的に指定した単語(「私の名前Chloéを書いて」「タイトル…」)を採用します。大文字小文字、アクセント、句読点、スペースは指定されたとおりに保持します。決して翻訳したり、スペルを修正したり、大文字小文字を変更したりしないでください。どの単語をレンダリングするか不明な場合は、短い質問を1つだけしてください。
  2. 改行。 明示的な改行(「2行で」、/、改行)を尊重します。それ以外の場合は、自動的に折り返します(セクション6)。
  3. マーク編集。 それぞれについて:対象文字、何番目か、形状、オプション(サイズ、色、溶けたか浮いているか)。
    • 発生箇所:「Miaのi」、「2番目のi」、「最後のj」、「すべてのi」。ユーザーが複数回出現する文字を、どれとは言わずに指定した場合は、編集をすべてに適用し、その旨を伝えます。
    • 切り離せるマークのみを置き換えることができます(下の表)。ユーザーがマークのない文字を対象とした場合(例:「oの点」、大文字のIなど)、黙って発明せず、その文字の上に飾りとして形状を追加するかどうかを尋ねてください。
    • 形状は glsl-sdf-shapes カタログから取得します。リクエストされた形状がリストにない場合は、そのスキルの説明に従って構築し、合成近似であることを伝えます。
    • デフォルト:形状はマーク全体(トレマの場合は両方の点、ユーザーが片方と言わない限り)を置き換え、文字の上に浮かび、文字と同じガラスになります。
  4. フォントまたは雰囲気(セクション2.1)。雰囲気を表す単語(「ストーリーブック」「ロマンチック」「ふわふわ」)が雰囲気を選択します。デフォルト:DM Serif Display。
  5. 背景。 単一の単色。デフォルトは黒 #000000(または雰囲気の色)。色名(liquid-glass-skill スキルにテーブルがあります)と16進コードを受け付けます。または、ユーザーが指定した画像(ファイルパス、またはメッセージに添付された画像:まずファイルに保存します)(セクション2.2参照)。液体表面は文字の周りには決して表示されず、文字の内側だけに表示されます(セクション7.2):動く液体の背景の前にある文字は判読できません。その表面だけを全画面の背景として使用するのが glsl-liquid-glass スキルです。
置き換え可能なマーク文字デフォルトの構築中心
ティトル(点)i j円、半径 Ry = +0.60
句読点. : ; ! ?円、半径 Rベースライン上またはその上、グリフの必要に応じて
トレマ(二点)ä ë ï ö ü ÿ および大文字二つの円、x = ±0.22+0.60(小文字)、+1.30(大文字)
アキュート、グラーブ、サーカムフレックスé è ê à â î ô û ù および大文字短いカプセル+0.60(小文字)、+1.30(大文字)
セディーユç Ç下の短い弧y = -1.30
リングå Å小さなリング+0.60 / +1.30

コードの前に、ユーザーが内容を確認できるように短いサマリーを表示します:

テキスト行マーク編集フォント背景
happy birthday Chloehappy birthday / Chloebirthday の i → 星(浮かんでいる)DM Serif Display黒 #000000
Be mine1i → ハートLavishly Yours(雰囲気 romantic)#F6D5DC
Mia1i → ハートDM Serif Display画像 beach.jpg

2.1 文字スタイル:実際のフォント(デフォルト)またはネオンチューブ

フォントモード(デフォルト)。 文字はフォントの実際の輪郭であり、正確な距離関数に変換され、ふくよかな液体ガラスとしてレンダリングされます。これらの文字を手描きしないでください。スクリプトを実行すると、templates/liquid-glass-text.glsl と glsl-sdf-shapes/shapes.glsl の形状からシェーダー全体が書き出されます。

python3 <this skill>/scripts/font_to_glsl.py --google "DM Serif Display" \
    --text "I love/Playful Design!" --mark "i@Design=star" --mark "!=heart" \
    --bg "#B5A0D0" --out i-love-playful-design.glsl
ユーザーの発言スクリプトオプション
vibe romantic、「ストーリーブックスタイル」、「ふわふわしたもの」--vibe romantic(下の表)
tint pink、「ピンクガラス」、「クリアガラス」--tint pink(パステルパレット);「clear」→ --tint white
rainbow、「オリジナルの液体カラー」、「虹色」--palette liquid
3d、「個別の3D文字」、「ぷくぷくの風船文字」--look objects(セクション7.0)
font Pacifico、「Playfair Displayで」--google "Pacifico"(Google Fontsからダウンロード、~/.cache/liquid-glass-fonts にキャッシュ)
フォントファイル(「~/fonts/Brand.otf を使って」)--font PATH
bold、italic、weight 800静的ファミリには --style Bold / --style Italic、可変ファミリには --axis wght=800
テキスト、/ で改行--text "line one/line two"。セクション6に従って行を選択します
「Designのi → 星」--mark "i@Design=star"
「2番目のi」、「すべてのi」--mark "i:2=star"、--mark "i=star"
「! の点 → ハート」、大きく--mark "!=heart"、--mark "!=heart*1.3"
「満月を o の代わりに」(文字全体、任意の文字)--replace "o=fullmoon"、--replace "o@love=heart"(--mark と同じ構文;形状が文字の位置とサイズを引き継ぐ)
背景色--bg "#B5A0D0" または色名
背景画像--image PATH(セクション2.2)
よりふくよかな / 平坦なガラス--puff 0.25 / --puff 0.10(デフォルト:フォントのステム幅から)
文字間隔の拡大 / 縮小、行間--tracking 0.05(em)、--line-height 1.0
  • 装飾の多いフォント(テクスチャ、スプラッター):--simplify 0.008 で小さな点を削除し、シェーダーを高速に保ちます。スクリプトは segments の数と4000を超える場合の warning を表示します:ブラウザはそのようなシェーダーを諦める可能性があります(白ページまたはエラーアイコン)。--simplify を上げる(0.008、次に0.015)か、テキストを短くします。雰囲気は vibes.json で simplify を設定できます。短いテキストでも4000セグメントを超えるフォントは避けてください。
  • 詳細な形状(butterflies、crown、butterfly)にはスペースが必要です:iに *2 以上を与え、テキストが小さい場合や明るい背景の場合は、butterflies よりも butterfly を優先してください。
  • スクリプトで使用可能な形状:circle heart star sparkle diamond moon fullmoon flower plus butterfly butterflies cloud crown spade club(「エースオブスペード」、「トレフル」、「満月」などの単語はこれらにマッピングされます:glsl-sdf-shapes カタログを参照)。その他の形状については、最初に shapes.glsl に追加します(glsl-sdf-shapes スキルに方法が記載されています)。
  • スクリプトは、そのフォントで切り離せる点やアクセントのない文字、またはフォントに存在しない文字へのマークを拒否します。これを回避するのではなく、ユーザーに報告してください。
  • ライセンス: Google Fontsは埋め込み自由です(OFLまたはApache)。ユーザーが持ち込んだフォントファイルについては、シェーダーに文字の輪郭が含まれるため、フォントのライセンスが埋め込みを許可している必要があることを一度だけ注意喚起してください。
  • コスト: フォントの文字は20~60の曲線で構成されるため、長い文章はチューブよりも重くなります。文章が約40文字を超える場合は、弱いGPUでは動作が遅くなる可能性があることを警告してください。
  • シェーダーをレンダリングできる場合(例えばヘッドレスブラウザでWebGLを使用)、一度確認してください。特にマークを確認してください:隣接するものと衝突する形状には *0.8 を適用します。

雰囲気(このスキルの vibes.json。それぞれがフォント、ユーザーが名前を指定しなかった場合にのみ使用される背景色、および調整を設定します)。ユーザーの言葉を雰囲気またはそのエイリアスのいずれかに一致させます:

雰囲気一致する単語フォントデフォルトの背景
adventure冒険的、大胆、探検家Caprasimo深いティール #12343B
cloud曇り、ふわふわ、柔らかい、泡Rubik Bubbles空色 #BFD9F2
medievalファンタジー、ケルティック、ナイトUncial Antiquaナイトブルー #14202B
romanticバレンタイン、愛、ウェディングLavishly Yoursブラッシュ #F6D5DC
cartoonストーリーブック、昔のデザイン、奇抜Henny Pennyクリーム #F2EEE6
drippingドリップ、ウェットペイント、溶ける、不気味Rubik Wet Paint黒 #0A0A0A
  • ユーザーがどの雰囲気にも一致しないムードを説明した場合は、自分で適切なGoogle Fontを選び、それを伝え、新しい雰囲気として保存することを提案します(vibes.json にエントリを追加し、スキルを再インストールします)。

ネオンチューブモード(font tubes、「ネオン」、「モノライン」):セクション3から6の手動構築文字、一定の太さの丸いガラス管。ユーザーがその外観を要求した場合にのみ使用します。

2.2 画像上

--image PATH を使用すると、ユーザーの写真が単色の代わりになります。フレームを埋め尽くし(壁紙のようにカバーするようにトリミング)、文字はその上に柔らかいコンタクトシャドウを落とし、ガラスの文字は実物のガラスのように写真を曲げます。文字の内側では、photoInGlass が液体表面と写真を混ぜ合わせます(--photo-in-glass、デフォルト 0.35;0 = 液体のみ、1 = 写真だけが見えるクリアガラス)。ユーザーが「私の写真にクリアガラス」を望む場合は 1 を使用し、液体の文字を目立たせたい場合は 0 を使用します。

  • シェーダーは iChannel0 から写真を読み取ります。.glsl に加えて、スクリプトは NAME.html も書き出します。これはシェーダーと写真が組み込まれたページで、ダブルクリックするだけで任意のブラウザでライブ動作します。常にユーザーにこのファイルを指示してください:Shadertoyは拡張機能なしではユーザー自身の写真を読み込めません。ページ内で、別の画像をドロップすると背景が置き換わり、Spaceで一時停止、SでPNGを保存します。
  • iPhoneの写真(HEIC)および3 MBを超える写真は、最大2048ピクセルのJPEGに変換されます(macOS sips)。
  • 込み入った写真は文字を読みづらくします。必要に応じて、写真のより落ち着いた部分、より低い --photo-in-glass、またはより大きなテキストを提案してください。

3. 文字構築のルール(チューブストローク、ネオンチューブモードのみ)

文字は丸いガラス管(ネオンスタイル)です。すべての文字を、一定の半径 const float R = 0.15; のストロークのみで構築します:ストレートカプセルと円弧です。すべての文字とデフォルトのマークのすべてのストロークは R(モノライン)を使用します。ストロークへの2D距離は、後で3Dチューブになります(セクション7.3)。

float sdCapsule(vec2 p, vec2 a, vec2 b, float r) {
    vec2 pa = p - a, ba = b - a;
    float h = clamp(dot(pa, ba)/dot(ba, ba), 0.0, 1.0);
    return length(pa - ba*h) - r;
}

// 円弧に沿ったストローク:中心 c、半径 ra、中間方向 `dir`
// (ラジアン、0 = +x、PI/2 = 上)、半開き `ap`(PI/2 = 半円、PI = 全円)。
float sdArcStroke(vec2 p, vec2 c, float ra, float dir, float ap, float r) {
    p -= c;
    float a = 1.5707963 - dir;                 // `dir` が +y を向くように回転
    p = mat2(cos(a), sin(a), -sin(a), cos(a)) * p;
    vec2 sc = vec2(sin(ap), cos(ap));
    p.x = abs(p.x);
    return ((sc.y*p.x > sc.x*p.y) ? length(p - sc*ra) : abs(length(p) - ra)) - r;
}

メトリクス(グリフ単位、ストローク中心線):

  • 大文字と数字:ベースライン y = -0.85、キャップライン y = +0.85(インクスパンは -1.0 から +1.0)。
  • 小文字:xハイト y = +0.15、アセンダーは +0.85 まで、ディセンダーは -1.55 まで。
  • 半幅 hw(中心線):標準大文字 0.40、標準小文字と数字 0.35、幅広(M W m w)0.60、狭い(I i l j ! . , : ; ')0.0 から 0.15。各グリフは独自の原点 x = 0 に中心があります。
  • 丸い文字(O C G D U S o c e …)はスタジアムです:半円弧をストレートカプセルで接続します。楕円を作るために p を不均一に拡大縮小しないでください。距離フィールドが壊れます。
  • サポートされていない文字(非ラテン文字、絵文字):推測する代わりにユーザーに伝えてください。

参考グリフ(このスタイルを他のすべての文字に一致させます):

float glyph_O(vec2 p) {
    float d = sdArcStroke(p, vec2(0.0,  0.45), 0.40,  1.5708, 1.5708, R);
    d = min(d, sdArcStroke(p, vec2(0.0, -0.45), 0.40, -1.5708, 1.5708, R));
    d = min(d, sdCapsule(p, vec2(-0.40, -0.45), vec2(-0.40, 0.45), R));
    d = min(d, sdCapsule(p, vec2( 0.40, -0.45), vec2( 0.40, 0.45), R));
    return d;
}

float glyph_A(vec2 p) {
    float d = sdCapsule(p, vec2(0.0, 0.85), vec2(-0.45, -0.85), R);
    d = min(d, sdCapsule(p, vec2(0.0, 0.85), vec2( 0.45, -0.85), R));
    d = min(d, sdCapsule(p, vec2(-0.29, -0.25), vec2(0.29, -0.25), R));
    return d;
}

// 小文字のボウル、a b d o p q g e…で共有
float bowl(vec2 p) {
    float d = sdArcStroke(p, vec2(0.0, -0.20), 0.35,  1.5708, 1.5708, R);
    d = min(d, sdArcStroke(p, vec2(0.0, -0.50), 0.35, -1.5708, 1.5708, R));
    d = min(d, sdCapsule(p, vec2(-0.35, -0.50), vec2(-0.35, -0.20), R));
    d = min(d, sdCapsule(p, vec2( 0.35, -0.50), vec2( 0.35, -0.20), R));
    return d;
}
float glyph_d(vec2 p) { return min(bowl(p), sdCapsule(p, vec2(0.35, -0.85), vec2(0.35, 0.85), R)); }

float glyph_i(vec2 p) {
    float d = sdCapsule(p, vec2(0.0, -0.85), vec2(0.0, 0.15), R);   // xハイトまでのステム
    return min(d, length(p - vec2(0.0, 0.60)) - R);                 // デフォルトのティトル
}

4. カスタムドットとアクセント(形状統合、ネオンチューブモード;フォントモードではスクリプトが行います)

マーク編集が適用される場合(セクション2):

  1. マークなしで文字のベースを構築します(例:glyph_dotless_i、ステムのみ)。
  2. 形状をグリフの内部ではなく、MARK マクロ(セクション6)を介して別のマークとして追加します。マークは独自の距離に入ります。形状はチューブとは異なる3Dプロファイルを得るためです(セクション7.3)。
  3. 形状は glsl-sdf-shapes からの2D SDFであり、原点を中心とし [-1, 1] に収まるように、正確に拡大縮小されます:sdfShape((…

[翻訳はここで切り詰められています]

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

関連スキル