本文へスキップ
503 bad gateway ロゴ
X YouTube
実装解説

はじめての人にも分かる FontEffectTools 実装解説

・ 読了目安 約16分 ・ 503 bad gateway

はじめての人にも分かる FontEffectTools 実装解説

炎・ネオン・水滴・グリッチなど20種類以上の文字演出を、1つのソースに載せる仕組み。OBSプラグイン FontEffectTools の中身を、ソースコードを引きながら解説します。演出の規格化、文字のマスク化、Windowsのフォント探索、FreeTypeの落とし穴まで——作り手自身による技術ドキュメント。

入力した文字に「炎」「ネオン」「水滴」「グリッチ」など 20 種類以上の演出をかけて表示できる、OBS Studio 用のプラグイン FontEffectTools の中身を、ソースコードを引きながら解説します。

OBS Studio は配信や録画に使われる定番ソフトです。画面に映すもの(カメラ、画像、文字など)を「ソース」と呼び、その種類はプラグインで増やせます。FontEffectTools は「文字に派手な演出をかけて映す」新しいソースを 1 つ追加するプラグインです。OBS の「ソースを追加」メニューに「Font Effect Tools」 という名前で出てきます。

この記事は、

  • グラフィックスプログラミングの専門家でなくても流れがつかめること
  • でも「実際どう作るのか」の勘所と、つまずきポイント(落とし穴)は省かないこと

を目標にしています。専門用語は出てくるたびにかみくだいて説明します。


0. 前提とする開発環境

まず、このプラグインをビルド(ソースコードから実行ファイルを作ること)するための環境を挙げておきます。FontEffectTools は Windows 専用で、次のツールを前提にしています。

項目内容
OSWindows 10 / 11(64bit)
コンパイラVisual Studio 2022(または 2026)の C コンパイラ
ビルド構成ツールCMake 3.28 以上
Windows SDK10.0.22621 以降(手元の構成は 10.0.26100)
依存ライブラリ①OBS Studio 31.1.1 のソース・ライブラリ
依存ライブラリ②FreeType(文字を描くためのライブラリ。vcpkg 経由で導入)
言語C 言語(C++ ではありません)

用語をかみくだくと:

  • CMake … 「どのファイルをどうコンパイルして 1 つのプラグインにまとめるか」の手順書を書くツール。CMakeLists.txt がその手順書です。
  • vcpkg … ライブラリ(部品)を自動でダウンロード・準備してくれる仕組み。ここでは FreeType を入れるのに使います(vcpkg.json に書いてあります)。
  • FreeType … フォントファイル(.ttf など)を読み込み、文字を点の集まり(ビットマップ)に変換してくれる定番ライブラリ。後で何度も登場します。

実際のビルドは付属の build.bat を実行するだけで、

  1. CMake で構成(configure)
  2. ビルド(コンパイル)
  3. 配布用フォルダ package\ に成果物をコピー

までを自動でやってくれます。出来上がるのは font-effect-tools.dll という1 つのファイル(プラグイン本体)と、演出ごとの設定ファイル群です。

プラグインのモジュール名(DLL のファイル名)は font-effect-tools です。OBS にインストールする際は、データフォルダ名も DLL と同じfont-effect-tools にそろえる必要があります(README 参照)。この記事では製品としての呼び名を「FontEffectTools」、内部のファイル名をfont-effect-tools と書き分けます。


1. OBS プラグインの「骨格」

プラグインは「コールバックの登録」でできている

OBS のプラグインは、「こういう時にこの関数を呼んでね」という関数を OBS に登録することで動きます。こうした「OBS から呼ばれる関数」をコールバックと呼びます。

入口のコードは驚くほど短いです(src/plugin-main.c)。

bool obs_module_load(void)
{
    flametext_register_source();   /* 自作ソースを OBS に登録する */
    obs_log(LOG_INFO, "font-effect-tools loaded (version %s)", PLUGIN_VERSION);
    return true;
}

flametext_register_source() の中身は、たくさんのコールバックを 1 つの表(構造体)に詰めて OBS に渡すだけです(src/flametext-source.c:472)。表の一部を抜き出すと:

static struct obs_source_info s_flametext_source_info = {
    .id             = "flame_text_source",          /* このソースの内部 ID */
    .type           = OBS_SOURCE_TYPE_INPUT,        /* 入力ソースですよ     */
    .output_flags   = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW,
    .get_name       = flametext_get_name,           /* 表示名を返す関数      */
    .create         = flametext_create,             /* ソース作成時に呼ばれる */
    .destroy        = flametext_destroy,            /* 削除時に呼ばれる       */
    .update         = flametext_update,             /* 設定が変わった時       */
    .video_tick     = flametext_video_tick,         /* 毎フレーム(時間進行)  */
    .video_render   = flametext_video_render,       /* 毎フレーム(描画)     */
    .get_width      = flametext_get_width,          /* 横幅を返す            */
    .get_height     = flametext_get_height,         /* 高さを返す            */
    .get_properties = flametext_properties,         /* 設定画面を組み立てる    */
    .get_defaults   = flametext_defaults,           /* 初期値を決める         */
    .show           = flametext_show,               /* 画面に出た瞬間         */
};

「ソースが作られたら flametext_create を呼ぶ」「毎フレーム描画のたびにflametext_video_render を呼ぶ」というように、OBS が適切なタイミングでこれらを呼び出してくれます。プラグイン作りの大半は「この表の各関数を埋めていく」作業です。

早速の勘所① 「自分で描く」宣言

output_flags にある OBS_SOURCE_CUSTOM_DRAW は、「描画は全部こちらでやります、OBS の自動処理は使いません」という宣言です。

FontEffectTools は炎をにじませたり、火の粉を加算合成(光を足し合わせる描き方)したりと、描画方法を細かく自分で切り替えます。OBS 任せにするとこれが成り立たないので、「自前で描く」フラグを立てています。

早速の勘所② 横幅・高さに「0」を返してはいけない

OBS は get_width / get_height でソースの大きさを聞いてきます。FontEffectTools はここで「文字を描いた画像の大きさ」を返します(src/flametext-source.c:264)。

static uint32_t flametext_get_width(void *data)
{
    const struct flametext_source *s = data;
    return (s->mask && s->mask->width) ? s->mask->width : 1u;   /* 最低でも 1 */
}

落とし穴: 文字がまだ無い(未入力やフォント未確定)ときにうっかり 0 を返すと、OBS 側で「幅 0・高さ 0」の計算が走って警告が出たり、ソースが消えたように見えたりします。だから何があっても最低 1 を返します。地味ですが実際にハマる定番ポイントです。

早速の勘所③ 「時間を進める係」と「描く係」は別

毎フレーム呼ばれる関数が 2 つあります。

  • video_tick(dt)dt は前フレームからの経過秒数。状態を進める役。たとえば火の粉を少し上に動かす、など。
  • video_render … 実際に画面へ描く役。

この 2 つは別々のタイミング・別々の前提で呼ばれます。特に重要なのが「グラフィックスロック」を持っているかどうか。グラフィックスロックとは、GPU(描画担当のハードウェア)をいじってよい「順番待ちの権利」のようなもの。描画系の関数(後述の gs_〜 で始まる関数)はこの権利を持っている間しか呼べません。

  • video_render・作成・破棄 … 権利を持った状態で呼ばれる → GPU を触ってよい
  • video_tick・設定更新 … 権利を持たない状態で呼ばれる → GPU を触ってはいけない

この区別を間違えて、権利が無いのに GPU を触ると即クラッシュします。コード側でも、どの関数が権利を持つかをコメントで明記しています(src/effect-base.h:38)。


2. 「1 つのソースに演出を 20 個以上」載せる仕組み

FontEffectTools の最大の特徴は、1 つのソースの中に炎・ネオン・水滴…と20 種類以上の演出を同居させ、ドロップダウンで切り替えられることです。しかも「文字」「フォント」「行間」「字間」などの基本設定は、どの演出を選んでも共通で使えます。

これを素直に作ると「もし炎なら…、もしネオンなら…」という巨大な分岐の山になってしまいます。そこで FontEffectTools は、演出 1 つを「部品」として規格化しました。

演出の「共通の型」を決める

すべての演出は、次の同じ形(struct text_effectsrc/effect-base.h:42)に従います。いわば「演出プラグインの差込口の規格」です。

struct text_effect {
    const char *id;        /* 設定に保存する名前。例 "flame"           */
    const char *name_key;  /* 選択メニューに出す表示名のキー            */

    void *(*create)(void);                         /* 部品を用意する     */
    void  (*destroy)(void *state);                 /* 後始末             */
    void  (*load_graphics)(void *state);           /* GPU 資源を読み込む  */
    void  (*update)(void *state, obs_data_t *s);   /* 自分の設定を読む    */
    void  (*tick)(void *state, ..., float dt);     /* 状態を進める       */
    void  (*render)(void *state, ...);             /* 1 フレーム描く      */
    /* …ほか、必要に応じて埋めるコールバック… */
};

ここに並んでいる void (*render)(...) のような書き方は 「関数を指す変数(関数ポインタ)」で、「この欄に自分の描画関数を入れておいてね」という意味です。各演出は自分専用のファイルでこの欄を埋めるだけ。炎ならfx_flamesrc/effect-flame.c:275)、跳ねる文字なら fx_hop、という具合に1 ファイル 1 演出で完結します。

演出を一覧に並べるだけ

用意した演出は、src/effect-registry.c の配列に並べておきます。

static const struct text_effect *const k_effects[] = {
    &fx_none, &fx_flame, &fx_rainbow, &fx_neon, &fx_bloom, /* …28 個… */
};

この設計の何が嬉しいか: 新しい演出を足すとき、やることは

  1. 演出ファイルを 1 本書く
  2. この配列に 1 行足す
  3. ビルド手順書(CMakeLists.txt)に 1 行足す

の 3 つだけ。本体(ホスト)側のコードには一切触りません。「機能追加のために既存コードをいじらない」という、保守しやすいソフトの理想形を、特別なフレームワークなしの素の C で実現しています。

ちょっと贅沢な割り切り: 全演出ぶんの状態を同時に持つ

面白いのは、ソースを 1 つ作ると、登録された全演出ぶんの作業領域を一度に確保することです(src/flametext-source.c:158)。

s->states = bzalloc(sizeof(void *) * (n ? n : 1));
for (size_t i = 0; i < n; ++i)
    s->states[i] = fx[i]->create ? fx[i]->create() : NULL;

つまり、今は炎を表示していても、ネオンや水滴の作業領域もこっそり全部メモリに置いてあります。設定が変わったときの読み込み(update)も全演出に対して行います(src/flametext-source.c:147)。

なぜそんな贅沢を? こうしておくと「炎をいじって、ネオンに切り替えて、また炎に戻したら設定が消えていた」が絶対に起きないからです。演出ごとの作業領域は小さい(せいぜい数十バイト + 描画資源 1〜2 個)ので、20 個ぶん持っても実用上まったく問題にならない、という計算に基づいた割り切りです。

設定画面は「全部用意して、選んだ分だけ見せる」

OBS の設定画面では、演出ごとの専用設定をいったん全部用意しておき、今選ばれている演出のものだけを表示します(src/flametext-source.c:332on_effect_changed)。ドロップダウンで演出を変えると、見せる設定グループを切り替えて画面を更新します。

落とし穴: この「変更時に呼ばれるコールバック」は、設定値そのものを書き換えるためではなく、他の項目の見え方を変えるためのものです。戻り値の true は「画面を作り直してほしい」の合図で、値の保存とは無関係。ここを混同すると「コールバックで値を変えたのに保存されない」と悩みます。


3. 文字を「型抜き画像」に変換する

20 種類以上の演出すべてが共有する素材があります。それが、入力した文字を焼き付けた 1 枚のモノクロ画像です。コードでは「マスク」と呼びます(flametext_masksrc/flametext-text.h:39)。

「マスク」とは何か

ここでいうマスクは、色を持たず「その点が文字に覆われているか」だけを記録したモノクロ画像です。料理の「型抜き」や、塗り絵の「下絵の輪郭」を想像してください。各点は 0〜255 の 1 つの値(被覆率)だけを持ち、

  • 255 … 完全に文字の中
  • 0 … 文字の外
  • 中間 … 文字の縁(なめらかに見せるためのぼかし部分)

を表します。色・光・歪みといった「見た目」は一切焼きません。それらは各演出が後からこのマスクを見て付け足します。マスクは「文字の形」という情報だけを担う、共通の土台なのです。

FreeType で 1 文字ずつ描いて貼り合わせる

マスク作りの本体は flametext_mask_build()src/flametext-text.c:312)。FreeType でフォントを開き、1 文字ずつモノクロのビットマップに変換して、大きな 1 枚のキャンバスに貼り合わせていきます。

貼り合わせ方に小さな工夫があります。単純な足し算ではなく、「濃い方を採る」合成(max 合成、src/flametext-text.c:67)です。

if (srow[x] > drow[cx])   /* 今ある値より濃いときだけ上書き */
    drow[cx] = srow[x];

なぜ足し算ではダメか: 字間を詰めると隣り合う文字の縁(ぼかし部分)が重なります。足し算だと重なった所だけ値が大きくなりすぎて、不自然に濃い線が出ます。「濃い方を採る」なら重なっても濃さが飽和しないので、被覆率の意味を正しく保てます。

わざと余白を大きく取る

このマスクは文字ぴったりのサイズではなく、上下左右にたっぷり余白を持ちます(src/flametext-text.c:498)。特に上方向は文字サイズの約 2.4 倍も空けます。

const int pad_top = (int)(pixel_size * 2.4f) + (int)extra_top;

理由は単純で、炎が立ち上る場所や火の粉が飛ぶ場所が必要だからです。さらに、演出が「もっと余白が欲しい」と要求できる仕組みもあります。水滴は「しずくが落ちる距離」だけ下に、光が伸びる演出は四方に余白を要求します。

これは地味ですが大事な設計です。「演出が画面の端で切れてしまう」というよくあるバグを、後から小細工で直すのではなく、最初に画像を十分大きく作っておくことで構造的に防いでいるのです。

落とし穴: 画像(テクスチャ)作成は GPU を触れる時しか呼べない

マスク作りの最後で GPU 上に画像を作ります(gs_texture_createsrc/flametext-text.c:563)。これは前述の「グラフィックスロック(GPU を触る権利)」を持った状態でしか呼べません。呼び出し側はちゃんとobs_enter_graphics()obs_leave_graphics() で囲んでいます(src/flametext-source.c:63)。この囲みを忘れると即クラッシュします。


4. フォントを探し当てる ―― Windows の地雷原

OBS のフォント選択画面が教えてくれるのは「フォント名(例: Impact)と太字/斜体の指定」だけで、ファイルの場所は教えてくれません。FreeType に渡すには「Impact の太字」→C:\Windows\Fonts\impactbd.ttf のようなファイル探しが必要です。

これが Windows では想像以上に厄介で、flametext-font-resolve-win.c というファイルがまるごとこの問題のために存在します。

2 段構えで探す

第 1 段: Windows のレジストリ(設定の台帳)にフォント一覧があるので、そこを引きます。ただし台帳の項目名は "Impact (TrueType)" のような独特の形式で、いくつか罠があります。

  • (TrueType)(OpenType)両方の名前で試す必要がある。
  • 値がフルパスのこともファイル名だけのこともある。後者ならC:\Windows\Fonts を補う。
  • 「自分用にインストール」したフォントは別の場所(ユーザー領域)に入る。台帳もユーザー専用の棚(HKCU)に入るので、共通の棚(HKLM)と両方を調べる(src/flametext-font-resolve-win.c:128)。ここを忘れると「自分で入れたフォントだけ見つからない」という、再現しにくいバグになる。

第 2 段(第 1 段で見つからない時): フォントフォルダの中身を片っ端から開いて、名前を照合します(src/flametext-font-resolve-win.c:247)。

最大の罠: 日本語フォントは名前が 2 つある

なぜ総当たりまでするのか。日本語フォントは英語名と日本語名を両方持つからです。ユーザーが「メイリオ」を選んでも、フォントが内部に持つ代表名は英語の "Meiryo" だったりします。そこで、フォントファイルの中の「名前表」を全言語ぶん調べ、どれか 1 つでも一致すれば「これだ」と判断します(src/flametext-font-resolve-win.c:172)。

しかもその名前表の文字は、扱いにくい形式(UTF-16 のビッグエンディアン)で入っているので、バイトの並べ替えから自前でやっています(src/flametext-font-resolve-win.c:141)。

落とし穴: FreeType に日本語パスを直接渡せない

FreeType の標準のファイルオープンは、パスに日本語が混ざると開けないことがあります。そこで FontEffectTools は、自分でファイルを開いて中身を全部メモリに読み込み、それを FreeType に渡す方式にしています(flametext-ftload.c)。

FILE *f = _wfopen(path, L"rb");          /* 日本語パスでも確実に開ける */
/* …ファイル全体を読み込み… */
FT_New_Memory_Face(lib, buf, size, face_index, &face);  /* メモリから読ませる */

ただしこの方式には注意点があります。FreeType はそのメモリをずっと参照し続けるので、フォントを使い終わるまで解放できません。解放を忘れると、文字を変えるたびにフォントファイル丸ごとぶんのメモリが捨てられず溜まっていきます(メモリリーク)。コードでは「フォントを閉じたら必ずメモリも解放」をペアで徹底しています。


5. 2 通りの描き方 ―― GPU で描くか、CPU で粒を撒くか

演出の描き方は大きく 2 種類あります。炎エフェクトは両方を使う良い見本です(src/effect-flame.c)。

その前に用語を 2 つだけ。

  • シェーダ … GPU 上で動く小さなプログラム。「画面の各点をどんな色にするか」を超高速に並列計算します。
  • テクスチャ … GPU が扱う画像のこと。先ほどのマスクもテクスチャです。

描き方その①: シェーダで一気に塗る(炎本体)

炎の揺らめきは、シェーダ(data/effects/flame.effect)が担当します。やっていることをざっくり言うと:

  1. マスク(文字の形)を上方向に少しずつずらしながら 20 回読み取る
  2. 時間とともに流れる「ゆらぎ模様」(ノイズ)で揺らす
  3. 下(熱い)ほど白〜黄、上(冷める)ほど赤〜黒、というグラデーションで色づけ

C 言語側の仕事は、シェーダに「今の時間」「炎の高さ」などの数値を渡して、1 回描画を指示するだけです(src/effect-flame.c:173)。

gs_blend_state_push();                                  /* 描き方を退避 */
gs_blend_function(GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA); /* 通常の重ね方 */
while (gs_effect_loop(fe, "Draw"))
    gs_draw_sprite(mask->tex, 0, 0, 0);                 /* シェーダで描く */
gs_blend_state_pop();                                   /* 描き方を元に戻す */

ここに OBS 流の大事な作法が 2 つあります。

  • gs_blend_state_push()pop() で必ず元に戻す。「ブレンド(重ね方)」の設定は、OBS の中で全ソースが共有する 1 つの設定です。退避せずに勝手に変えると、他のソースの描画にまで悪影響が漏れます。使う前に退避、使い終わったら復元、が鉄則です。
  • 時間の値を丸めてから渡すsrc/effect-flame.c:196)。配信を何時間も回すと経過秒数がどんどん大きくなり、小数の計算精度が落ちて炎がガクつきます。fmodf で適度な範囲に丸めてこれを防ぎます。

描き方その②: CPU で粒を撒く(火の粉)

火の粉は、CPU で 1 粒ずつ位置を計算して動かします(src/flametext-particles.c)。これを「パーティクル(粒子)システム」と呼びます。打ち上げ花火の火花が、上がって、広がって、消えていく、あの動きをプログラムで再現するものです。

毎フレーム、各粒について「速度ぶん動かす」「寿命を減らす」を繰り返します(src/flametext-particles.c:107)。ここにも実務的な工夫があります。

  • 時間刻みの上限を設ける: if (dt > 0.1f) dt = 0.1f;。ウィンドウ移動や処理落ちでフレーム間隔が一瞬大きく開くと、その間に粒が一気に進んで画面外へ吹き飛びます。刻みの最大値を抑えて、シミュレーションが暴走しないようにします。
  • 死んだ粒を効率よく回収する: 配列にできた「穴」を、末尾の生きている粒で埋めるだけ(src/flametext-particles.c:129)。並び順は気にしないので一瞬で消せます。

描画は、生きている全粒を1 回の指示でまとめて描きます。粒ごとに描画命令を分けると遅くなるので、粒の個性(明るさなど)は各頂点に相乗りさせて運びます。重ね方は加算合成(色を足し合わせる)にして、火の粉が光って見えるようにします(src/flametext-particles.c:166)。


6. 文字 1 つずつを動かす演出

「文字が 1 文字ずつ跳ねながら登場する」hop 演出(src/effect-hop.c)は、マスクに同梱された文字ごとの位置情報を使う好例です。

マスクには、文字 1 つ 1 つが画像のどこにあるかという「四角形のリスト」が入っています(glyphs[])。これがあると、1 枚のマスク画像の一部分だけを取り出して、各文字を独立した絵として動かせます。テクスチャを文字数ぶんに分割する必要はありません。

hop 演出は、文字ごとに「今どこにいるべきか(登場中/待機中/退場中)」を計算し、その位置・拡大率で部分描画します(src/effect-hop.c:142)。跳ねる前に少し縦に潰れて溜める「スカッシュ&ストレッチ」(アニメの定番のタメの表現)まで入っていて、しかも支点を文字の足元に置くので、自然な跳ね方になります。

この仕組みのおかげで、文字単位で動く演出(跳ねる・震える・スライドインなど)はどれも、マスクを作り直さず、共有の 1 枚と位置情報を読むだけで作れています。


7. 文字の後ろから光をにじませる(アウターグロー)

最後に、少し高度な「アウターグロー」を紹介します。これは、選んだ演出が描いた絵の後ろ側に、ぼんやりした光のにじみを敷く機能です。どの演出を選んでいても共通で効く、本体(ホスト)側の後処理として作られています(src/flametext-outerglow.c)。

仕組みはこうです。

  1. いったん画面ではなく、見えない別の用紙(オフスクリーン)に演出を描く
  2. その絵の輪郭をぼかして「光の素」を作る
  3. 光をシーンに敷く
  4. その上に、最初に描いた演出の絵を重ねる

「光を先に敷いて、本体を上に乗せる」順番なので、光が文字の後ろからにじみ出て見えます。手品のような順序ですが、これが定番のやり方です。

ここにも落とし穴が 3 つあります。

  • ぼかし用の画像はきめ細かい形式で持つsrc/flametext-outerglow.c:127)。光のにじみは広くゆるやかなグラデーションなので、ふつうの 256 段階の画像だと縞模様(バンディング)が出ます。中間のぼかし画像だけ階調を増やすと縞が消えます。
  • 重ね方(スクリーン・乗算など)を、計算ではなく GPU の重ね設定で表現するsrc/flametext-outerglow.c:198)。Photoshop のレイヤー合成のような「スクリーン」「乗算」を、シェーダで真面目に計算する代わりに、GPU がもともと持っている「重ね方の設定」を巧みに組み合わせて再現しています。
  • 余白の連鎖: 光は文字の外へ広がるので、マスクの余白が足りないと光が切れます。そこで、光のサイズぶんの余白を、演出自身が要求する余白の上にさらに足して確保します(src/flametext-source.c:56)。

8. まとめ ―― この実装から学べること

FontEffectTools を貫く設計の考え方を、最後に整理します。

  1. 演出を「規格化された部品」にした。共通の型を 1 つ決めたことで、新しい演出は「ファイルを 1 本書いて一覧に 1 行足す」だけで増やせます。本体には触りません。
  2. 「文字の形」だけを共有の土台にした。色を持たないモノクロのマスクを作り、見た目は各演出に任せる。だからシェーダ系も粒子系も文字単位の演出も、同じ 1 枚を使い回せます。
  3. 問題を「最初の作り」で防ぐ。演出が広がるぶん画像を最初から大きく作っておくことで、「端で切れる」バグを後追いの小細工なしに潰しています。

そして、OBS プラグインを作るうえで繰り返し出てきた落とし穴:

  • GPU を触ってよい場面かを常に意識する(権利が無い所で触るとクラッシュ)。
  • 重ね方の設定は使う前に退避、後で復元(全ソースで共有しているから)。
  • 横幅・高さに 0 を返さない(最低 1)。
  • 時間の値は丸めてから使う(長時間配信での精度落ち対策)。
  • 時間刻みに上限を設ける(処理落ちでシミュレーションが暴走しない)。
  • Windows のフォント探しは奥が深い。共通とユーザーの両方の台帳、フォルダ総当たり、日本語の別名まで踏まないと取りこぼします。
  • FreeType に日本語パスを直接渡さない。メモリに読んでから渡し、そのメモリは使い終わるまで解放しない(が、忘れずに解放する)。

「似たもの(演出)をたくさん、1 つの土台に差し替え式で載せ、共通の素材を分け合いながら、それぞれ違う見た目を持たせる」――この構造は OBS に限らず、拡張できる多くのソフトに通じます。FontEffectTools はそれを、特別な仕掛けに頼らず素の C 言語で成立させている点が、読みどころです。

他の読み物

はじめての人にも分かる BadAutoAlign 解説——ボーカル自動補正の理論と設計 実装解説

はじめての人にも分かる BadAutoAlign 解説——ボーカル自動補正の理論と設計

ガイドを基準にボーカルのタイミングとピッチを一括自動補正するツール BadAutoAlign。その設計ドキュメント一式をもとに、処理パイプライン、3度の失敗を経てたどり着いたタイミング補正の理論、ケロらせないピッチ補正、検出系、GUIの分業設計、数値検証までを通して解説します。作り手自身による技術ドキュメント。

読む
配信画面の背景に煙・火の粉・キラキラを足す方法——Background Effect Tools の使い方 ハウツー

配信画面の背景に煙・火の粉・キラキラを足す方法——Background Effect Tools の使い方

OBS Studio に「背景エフェクト」ソースを1つ足すだけで、配信画面に煙や火の粉、キラキラ、音に反応するビジュアライザーを重ねられる。無料・オープンソースの自作プラグイン Background Effect Tools の導入と使い方を、作り手自身が解説します。

読む
OBSで“動く装飾テロップ”を表示する方法——FontEffectTools の使い方 ハウツー

OBSで“動く装飾テロップ”を表示する方法——FontEffectTools の使い方

グロー・アウトライン・縦書きから、スライドインや震えといった動きのある演出まで。OBS Studio 用の無料・オープンソースプラグイン FontEffectTools で、配信のテロップを見やすく・かっこよく仕上げる方法を解説します。

読む