me:DERU Studioに組み込めるビジュアルエフェクトを作成。EFX LABでコードをMODに変換できます。
▶ EFX LABを開く ガイドを読む ↓me:DERUは2つのエディタで構成されています。レイヤースタイルのDERUとノードスタイルのNODE。MODでさまざまなエフェクトを追加できます。
me:DERUのEFXモジュール「MOD」は、Atelierのマテリアルと同じようにアーティストによって作成されたコードが格納されています。そのMODはさまざまな可能性を秘めた魔法の箱です。
MODは単一の関数。入力が入り、出力が出る。DOM操作なし、状態管理なし、副作用なし。
スライダーやトグルを定義。ユーザーがStudioで調整するとコードに値が渡されます。
MOD化されたプログラムはDERUとNODEの両方で使用可能。MINTして作品として出力。
MODはNFTとして販売。所有することで利用できる追加機能として提供されます。
すべてのMODは同じ Input → Effect → Output パターンに従います。関数がピクセルデータを受け取り変換します。
function yourEffect(data, width, height, params, canvas, ctx) { // data — Uint8ClampedArray: RGBAピクセルデータ // width — number: 画像の幅 // height — number: 画像の高さ // params — object: スライダーからの値 { key: value } // canvas — HTMLCanvasElement // ctx — CanvasRenderingContext2D for (let i = 0; i < data.length; i += 4) { const r = data[i], g = data[i+1], b = data[i+2]; // ... エフェクトのロジック ... data[i] = newR; data[i+1] = newG; data[i+2] = newB; } }
data[]を直接変更。テキスト/描画エフェクトはcanvas/ctxに描いてdataに読み戻す。EFX LABはMODプロトタイピング用ツール。コードを書き、画像をドロップして、結果を即座に確認。
Sourceノードに画像をD&Dするか、クリックして選択。これがINPUTになります。
コードエディタにエフェクト関数を記述。テンプレート(Grayscale, Pixelate, Kanji)を出発点にできます。
コードにparams.xxx||defaultと書くとスライダーが正しい範囲で自動生成されます。
RUNまたはCmd+Enterで実行。MOD/Outputノードに結果が表示。クリックで拡大。
params.contrast||100と書くとスライダー (0–200, default 100) が即座に表示されます。既存のHTMLエフェクトからコアアルゴリズムをMOD関数に抽出する方法。
ピクセル処理ロジックを見つける。UI、ファイルI/O、状態管理は無視。数学だけを残す。
document.getElementById('slider').valueをparams.sliderName||defaultValueに置き換え。
アルゴリズムを以下の形式でラップ:function myEffect(data, width, height, params, canvas, ctx) { ... }
コードエディタに関数をペーストし、画像を読み込み、RUNを押す。パラメータを調整して動作確認。
| パターン | 用途 | 方法 |
|---|---|---|
| ピクセルフィルタ | 色調整、コントラスト等 | data[i]をループで変更 |
| 空間/近傍 | ぼかし、シャープ、エッジ検出 | dataをコピーし、コピーから読みdataに書く |
| キャンバスオーバーレイ | テキスト、図形を重ねる | dataをcanvasに置き描画し読み戻す |
| キャンバス完全置換 | 漢字アート、ASCIIアート | canvasにゼロから描画しdataに読み込む |
EFX LABで動作確認後、レビューとme:DERUプラットフォームへの統合のために提出。
function myEffect(data, width, height, params, canvas, ctx) — コアアルゴリズム。
MOD名、簡単な説明、アーティスト名、パラメータや使い方のメモ。
エフェクト適用のスクリーンショットまたは画像。レビューに役立ちます。
| 引数 | 型 | 説明 |
|---|---|---|
| data | Uint8ClampedArray | RGBAピクセルデータ — ピクセルあたり4バイト (R,G,B,A)。出力はインプレースで変更。 |
| width | number | 画像の幅(ピクセル) |
| height | number | 画像の高さ(ピクセル) |
| params | object | スライダーからのパラメータ値:{ contrast: 100, gamma: 1.0, ... } |
| canvas | HTMLCanvasElement | 出力キャンバス — 入力画像と同じサイズ |
| ctx | CanvasRenderingContext2D | 描画操作用のCanvas 2Dコンテキスト |
| パラメータ名 | Min | Max | Step |
|---|---|---|---|
| contrast | 0 | 200 | 1 |
| brightness | 0 | 200 | 1 |
| gamma | 0.1 | 5 | 0.1 |
| fontSize | 2 | 48 | 1 |
| charWidth | 10 | 200 | 1 |
| pixelSize | 1 | 64 | 1 |
| threshold | 0 | 255 | 1 |
| opacity | 0 | 100 | 1 |
| angle | 0 | 360 | 1 |
| invert | 0 | 1 | 1 |
// 各ピクセル = data配列内の連続する4つの値 // data[i] = Red (0-255) // data[i+1] = Green (0-255) // data[i+2] = Blue (0-255) // data[i+3] = Alpha (0-255) // (x, y) のピクセルを取得: const i = (y * width + x) * 4; const r = data[i], g = data[i+1], b = data[i+2], a = data[i+3]; // グレースケール変換: const gray = r * 0.3 + g * 0.59 + b * 0.11;
現在のMODアーキテクチャは1フレーム単位で処理するため、コード変更なしでGIFや動画にも対応可能です。
将来のMODはparamsを通じてタイミング情報を受け取り、時間ベースのアニメーションが可能に:
| パラメータ | 型 | 説明 |
|---|---|---|
| params.frameIndex | number | 現在のフレーム番号 (0, 1, 2, ...) |
| params.totalFrames | number | 全フレーム数 |
| params.progress | number | 進行度 (0.0 → 1.0) |
function fadeEffect(data, width, height, params, canvas, ctx) { const t = params.progress || 0; // 0.0 → 1.0 時間経過 for (let i = 0; i < data.length; i += 4) { // フレームごとに変化するエフェクト data[i] *= (1 - t * 0.5); // 徐々に色がシフト data[i+1] *= (1 - t * 0.3); data[i+2] *= (1 + t * 0.2); } }
フレームパラメータを使わないMODは全フレームに同じエフェクトを適用 — 即座にGIFフィルタに。
params.progressを使って時間とともに変化するエフェクトを作成 — グリッチ、フェード、モーフ、リビール。