0
0

ブラウザ用Signed Distance Field (SDF)生成ライブラリを作ってみた

Posted at

WebGLでSigned Distance Field (SDF)生成ライブラリを作ってみた

はじめに

WebGLを使って画像からSigned Distance Field (SDF)を生成するライブラリを作成しました。WebGLを内部的に使ってはいますが、高速化のためで、非WebGLアプリでも利用可能です。

SDFは文字のレンダリングや特殊効果の生成などに使われる便利なテクニックです。今回はこのライブラリの紹介と、開発中に得られた知見をお伝えします。

ライブラリの概要

基本的な使い方

npmからインストール:

npm install fastsdf

基本的な使用例:

import { generateSDF } from 'sdf-generator';

const srcImg = new Image();
srcImg.onload = () => {
  const sdfImg = generateSDF(srcImg, 10 /*maxDist*/, 0.25 /*dstAlphaThreshold*/);
  document.body.appendChild(sdfImg);
};
srcImg.src = 'path/to/your/image.png';

リファレンス

generateSDF(srcImg: HTMLImageElement, maxDist: number, dstAlphaThreshold: number): HTMLImageElement

Signed Distance Field画像を作ります。 出力imgのRGBは白で、Aは以下の説明のようにパラメータによって変わります。

  • srcImg: 入力となるアルファ付きイメージ。アルファ以外は無視します
  • maxDist: distanceを計算するときの最大距離
  • dstAlphaThreshold: アルファ値の閾値(t)。出力アルファは以下のように計算されます
    • tの指定がない場合
      • 符号付き距離を距離を0~1に正規化した値(+maxDist→0、0→0.5、-maxDist→1.0)
    • tの指定がある場合
      • t < srcα: 1.0
      • srcα < t: 0.0
  • return: dstImage

出力例

上:元画像(背景が白なのでわかりづらいですが、アルファは設定されています)
下:dstImageを水色で表示して、その上に元画像を乗せたもの

GShzvZZagAAixzS.png

コード的にはこんな感じです。

const sdf = generateSDF(img, 10, 0.25);
const canvas = document.querySelector<HTMLCanvasElement>('#canvas')!;
const ctx = canvas.getContext('2d')!;

ctx.save();
ctx.drawImage(sdf, 0, 0);
ctx.globalCompositeOperation = 'source-in';
ctx.fillStyle = 'cyan';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.restore();

ctx.drawImage(img, 0, 0);

まとめ

GPUの並列処理能力を活用することで、高速なSDF生成が可能になりました。今後も継続的に改良を加えていく予定です。

皆さんも是非試してみてください。フィードバックお待ちしています!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0