開発者ガイド

me:DERU のMODを作ろう

me:DERU Studioに組み込めるビジュアルエフェクトを作成。EFX LABでコードをMODに変換できます。

▶ EFX LABを開く ガイドを読む ↓

01 — 概要

me:DERU — multi layer module EFX

me:DERUは2つのエディタで構成されています。レイヤースタイルのDERUとノードスタイルのNODE。MODでさまざまなエフェクトを追加できます。

📑
DERU
レイヤースタイル
+
🔀
NODE
ノードスタイル
+
MOD
エフェクトモジュール

MODとは?

me:DERUのEFXモジュール「MOD」は、Atelierのマテリアルと同じようにアーティストによって作成されたコードが格納されています。そのMODはさまざまな可能性を秘めた魔法の箱です。

ピュア処理

MODは単一の関数。入力が入り、出力が出る。DOM操作なし、状態管理なし、副作用なし。

🎛️

パラメータ

スライダーやトグルを定義。ユーザーがStudioで調整するとコードに値が渡されます。

🔌

DERUとNODEで使用

MOD化されたプログラムはDERUとNODEの両方で使用可能。MINTして作品として出力。

🔐

NFT Tokengate

MODはNFTとして販売。所有することで利用できる追加機能として提供されます。


02 — パイプライン

MODの仕組み

すべてのMODは同じ Input → Effect → Output パターンに従います。関数がピクセルデータを受け取り変換します。

🖼️
SOURCE
画像ピクセル (RGBA)
⚙️
あなたのMOD
processPixels()
📤
OUTPUT
変換後ピクセル
your-effect.js JavaScript
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;
    }
}
💡
2つのアプローチ:ピクセルフィルタはdata[]を直接変更。テキスト/描画エフェクトはcanvas/ctxに描いてdataに読み戻す。

03 — EFX LAB

開発サンドボックス

EFX LABはMODプロトタイピング用ツール。コードを書き、画像をドロップして、結果を即座に確認。

📂

1. 画像を読み込む

Sourceノードに画像をD&Dするか、クリックして選択。これがINPUTになります。

✏️

2. コードを書く

コードエディタにエフェクト関数を記述。テンプレート(Grayscale, Pixelate, Kanji)を出発点にできます。

🎛️

3. 自動パラメータ

コードにparams.xxx||defaultと書くとスライダーが正しい範囲で自動生成されます。

▶️

4. 実行 (⌘+Enter)

RUNまたはCmd+Enterで実行。MOD/Outputノードに結果が表示。クリックで拡大。

🔧
自動検出:コード入力時に自動的にパラメータがスキャンされます。params.contrast||100と書くとスライダー (0–200, default 100) が即座に表示されます。
▶ EFX LABを開く

04 — 変換

スタンドアロンコードからMODへ

既存のHTMLエフェクトからコアアルゴリズムをMOD関数に抽出する方法。

1

コアアルゴリズムを特定

ピクセル処理ロジックを見つける。UI、ファイルI/O、状態管理は無視。数学だけを残す。

2

コントロールをParamsにマッピング

document.getElementById('slider').valueparams.sliderName||defaultValueに置き換え。

3

関数を書く

アルゴリズムを以下の形式でラップ:function myEffect(data, width, height, params, canvas, ctx) { ... }

4

EFX LABでテスト

コードエディタに関数をペーストし、画像を読み込み、RUNを押す。パラメータを調整して動作確認。

変換パターン

パターン用途方法
ピクセルフィルタ色調整、コントラスト等data[i]をループで変更
空間/近傍ぼかし、シャープ、エッジ検出dataをコピーし、コピーから読みdataに書く
キャンバスオーバーレイテキスト、図形を重ねるdataをcanvasに置き描画し読み戻す
キャンバス完全置換漢字アート、ASCIIアートcanvasにゼロから描画しdataに読み込む
⚠️
削除すべきもの:DOMアクセス、イベントリスナー、ファイルI/O、グローバル変数、テーマ切替、ダウンロードボタン。MODは処理関数のみ

05 — 提出

MODを公開する

EFX LABで動作確認後、レビューとme:DERUプラットフォームへの統合のために提出。

🎨
プロトタイプ
EFX LABで作成&テスト
📨
提出
Discordでコード送信
🔍
レビュー
セキュリティ&品質チェック
🔧
統合
TSモジュールに変換
🚀
デプロイ
me:DERUで公開
🔒
セキュリティ:すべてのMODコードはデプロイ前にレビューされます。MODはユーザーのブラウザで実行されるため、外部リクエスト、DOMアクセス、ウォレット操作は禁止されています。

提出するもの

📄

エフェクトコード

function myEffect(data, width, height, params, canvas, ctx) — コアアルゴリズム。

📝

説明

MOD名、簡単な説明、アーティスト名、パラメータや使い方のメモ。

🖼️

サンプル出力

エフェクト適用のスクリーンショットまたは画像。レビューに役立ちます。


06 — リファレンス

クイックリファレンス

関数の引数

引数説明
dataUint8ClampedArrayRGBAピクセルデータ — ピクセルあたり4バイト (R,G,B,A)。出力はインプレースで変更。
widthnumber画像の幅(ピクセル)
heightnumber画像の高さ(ピクセル)
paramsobjectスライダーからのパラメータ値:{ contrast: 100, gamma: 1.0, ... }
canvasHTMLCanvasElement出力キャンバス — 入力画像と同じサイズ
ctxCanvasRenderingContext2D描画操作用のCanvas 2Dコンテキスト

自動検出パラメータ範囲

パラメータ名MinMaxStep
contrast02001
brightness02001
gamma0.150.1
fontSize2481
charWidth102001
pixelSize1641
threshold02551
opacity01001
angle03601
invert011

ピクセルデータの構造

pixel-layout.js リファレンス
// 各ピクセル = 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;

07 — Future Plan

GIF・動画対応

現在のMODアーキテクチャは1フレーム単位で処理するため、コード変更なしでGIFや動画にも対応可能です。

🎬
GIF / 動画
フレーム分解
MOD × N
各フレームに適用
📤
OUTPUT
GIF / WebP / MP4
🎞️
MODの変更は不要。既存のMODはそのまま動画に適用できます。パイプライン側でフレーム分解 → MOD適用 → 再エンコードを行います。

フレーム拡張パラメータ

将来のMODはparamsを通じてタイミング情報を受け取り、時間ベースのアニメーションが可能に:

パラメータ説明
params.frameIndexnumber現在のフレーム番号 (0, 1, 2, ...)
params.totalFramesnumber全フレーム数
params.progressnumber進行度 (0.0 → 1.0)
time-based-effect.js 将来
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を使って時間とともに変化するエフェクトを作成 — グリッチ、フェード、モーフ、リビール。