render-textures について
オフスクリーンテクスチャの描画、合成、読み取りを扱う Phaser 4 向けスキルです。RenderTexture と DynamicTexture の違いや、コマンドバッファー、プロシージャル生成、ミニマップの実装パターンを説明します。
主な機能
- 01RenderTexture と DynamicTexture の使い方
- 02コマンドバッファーによる描画
- 03テクスチャの描画、塗りつぶし、消去
- 04テクスチャのスナップショットとピクセル読み取り
- 05プロシージャルテクスチャとミニマップのパターン
活用シーン
- 01複数のゲームオブジェクトをテクスチャに合成
- 02タイル模様や星空のテクスチャを生成
- 03カメラに固定したミニマップを作成
- 04テクスチャ領域やピクセルデータを読み取り
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ phaserjs/ phaser --skill render-texturesインストール後、Claude Code で/render-texturesを入力して読み込まれたか確認します。
詳細
レンダーテクスチャとダイナミックテクスチャ
Phaser 4 でゲームオブジェクトをオフスクリーンテクスチャに描画する -- RenderTexture ゲームオブジェクト、共有テクスチャ用の DynamicTexture、Stamp ヘルパー、コマンドバッファレンダリング、スナップショット、プロシージャル生成、ミニマップパターン。
主要なソースパス: src/gameobjects/rendertexture/、src/textures/DynamicTexture.js、src/gameobjects/stamp/、src/textures/typedefs/StampConfig.js、src/textures/typedefs/CaptureConfig.js
関連スキル: ../sprites-and-images/SKILL.md、../loading-assets/SKILL.md、../cameras/SKILL.md
クイックスタート
// In a Scene's create() method:
// 1. RenderTexture -- a visible game object with its own DynamicTexture
const rt = this.add.renderTexture(400, 300, 256, 256);
rt.draw('player', 128, 128); // draw a texture by key at center
rt.fill(0x222244, 0.5); // semi-transparent fill
rt.render(); // flush the command buffer
// 2. DynamicTexture -- a shared texture in the Texture Manager
const dt = this.textures.addDynamicTexture('composite', 512, 512);
dt.stamp('coin', null, 64, 64, { scale: 2, angle: 45 });
dt.render();
this.add.image(400, 300, 'composite'); // any game object can use it
// 3. Stamp game object -- lightweight Image that ignores camera scroll
const hud = this.add.stamp(10, 10, 'heart');
基本概念
RenderTexture と DynamicTexture
Phaser 4 ではテクスチャ描画が 2 つのレイヤーに分かれています:
| RenderTexture | DynamicTexture | |
|---|---|---|
| 何であるか | Image ゲームオブジェクト + 自動生成される DynamicTexture | Texture Manager 内のテクスチャ |
| 生成方法 | this.add.renderTexture(x, y, w, h) | this.textures.addDynamicTexture(key, w, h) |
| 単体で表示可能か | はい(Image を継承) | いいえ(ゲームオブジェクトに割り当てる必要あり) |
| オブジェクト間で共有 | saveTexture(key) で可能 | はい、キー経由で可能 |
| シーンをまたいだ使用 | いいえ(1 つの Scene に属する) | はい(テクスチャはグローバル) |
| position/scale/alpha を持つか | はい(すべての Image コンポーネント) | いいえ(Texture であり GameObject ではない) |
どちらを使うべきか:
- 描画先となる単一の可視サーフェスが必要な場合(ペイントキャンバス、トレイル効果、複合スプライト)は RenderTexture を使用します。
- 多くのゲームオブジェクトが同じ生成テクスチャを共有する場合、マスクやシェーダー用のテクスチャが必要な場合、またはシーンをまたいだアクセスが必要な場合は DynamicTexture を使用します。
RenderTexture は薄いプロキシです。draw()、stamp()、fill()、clear()、erase()、snapshot() といったメソッドはすべて、その基盤となる this.texture(DynamicTexture)に委譲されます。
origin に関する注意: RenderTexture は Image を継承するため、origin はデフォルトで (0.5, 0.5) になります。左上を基準に配置したい場合(全画面やミニマップの RT でよくある)は、rt.setOrigin(0, 0) を呼び出してください。
コマンドバッファ(v4 アーキテクチャ)
Phaser 4 では、描画呼び出し(draw、stamp、fill、clear、erase、repeat、capture)は即座には実行されません。これらの呼び出しはコマンドを commandBuffer 配列にプッシュします。バッファをフラッシュして実行するには .render() を呼び出す必要があります。
rt.clear();
rt.fill(0x000000);
rt.draw(sprite, 128, 128);
rt.render(); // REQUIRED -- nothing appears without this
RenderTexture ゲームオブジェクトの場合、renderMode プロパティが自動レンダリングを制御します:
| モード | 動作 |
|---|---|
'render'(デフォルト) | 毎ティック、テクスチャの内容をフレームに描画します。内容が変わったときに手動で render() を呼び出します。 |
'redraw' | 毎フレーム自動的に render() を呼び出しますが、自身は表示しません。他のオブジェクトから再利用されるテクスチャに便利です。 |
'all' | 毎フレーム render() を呼び出し、かつ自身をフレームに描画します。 |
rt.setRenderMode('all'); // auto-render + display every frame
rt.setRenderMode('all', true); // same, plus preserve the command buffer
プリザーブモード
デフォルトでは、コマンドバッファは render() の後にクリアされます。preserve(true) を呼び出すとレンダリング間でコマンドを保持し、同じ描画が毎フレーム再生されるようになります:
rt.preserve(true);
rt.clear();
rt.draw(sprite);
// On every subsequent render(), clear + draw will repeat
Stamp ゲームオブジェクト
Stamp(this.add.stamp(x, y, texture, frame))は、レンダリング時にカメラのスクロールとトランスフォームを無視する軽量な Image サブクラスです。DynamicTexture の描画操作で内部的に使用され、HUD 要素にも便利です。カスタムレンダーノード(DefaultStampNodes)で Image を拡張します。
stamp() メソッドと Stamp ゲームオブジェクトの違い
これらは別物です:
rt.stamp(key, frame, x, y, config)-- RenderTexture/DynamicTexture のメソッドで、トランスフォームオプション(alpha、tint、angle、scale、origin、blendMode)を指定してテクスチャフレームをサーフェスに描画します。this.add.stamp(x, y, texture, frame)-- Scene のディスプレイリストに追加される Stamp ゲームオブジェクトを生成するファクトリです。
よくあるパターン
スプライトとゲームオブジェクトの描画
const rt = this.add.renderTexture(0, 0, 800, 600);
// Single game object at an offset
rt.draw(sprite, 100, 100);
// Array of objects
rt.draw([sprite1, sprite2, sprite3]);
// Group or Container (only visible children are drawn)
rt.draw(enemyGroup);
rt.draw(myContainer, 50, 50); // offset added to children positions
// Entire Scene display list
rt.draw(this.children);
// Texture by string key
rt.draw('explosion', 200, 200);
// Don't forget to flush
rt.render();
draw() メソッドは、描画可能なゲームオブジェクト、Group、Container、Display List、他の RenderTexture/DynamicTexture、テクスチャフレーム、テクスチャキー文字列、またはこれらの配列を受け付けます。
注意: draw() の alpha および tint パラメータはテクスチャフレーム/文字列にのみ適用されます。ゲームオブジェクトは描画時に自身の alpha と tint を使用します。
設定を使用したテクスチャのスタンプ
stamp() メソッドは、完全なトランスフォーム制御でテクスチャフレームを描画します。フレームはデフォルトで x/y 位置を中心に配置されます(原点 0.5)。
rt.stamp('bullet', null, 100, 100, {
alpha: 0.8,
tint: 0xff0000,
angle: 45, // degrees (takes precedence over rotation)
scale: 2, // uniform scale
scaleX: 1.5, // overrides scale for X
scaleY: 0.5, // overrides scale for Y
originX: 0, // top-left origin
originY: 0,
blendMode: 0
});
rt.render();
capture -- オーバーライドを使用した描画(v4)
capture() メソッドは、一時的なプロパティオーバーライドを適用してゲームオブジェクトを描画し、その後で元の状態に復元します:
rt.capture(player, {
x: 64,
y: 64,
scale: 0.5,
alpha: 0.8,
rotation: Math.PI / 4,
transform: 'world', // 'local', 'world', or a TransformMatrix
camera: someCamera // optional camera override
});
rt.render();
これは、オブジェクト自体を変更せずに、異なる位置/スケールでオブジェクトを描画するのに便利です。
塗りつぶしとクリア
// Fill entire texture with color
rt.fill(0xff0000); // solid red
rt.fill(0x000000, 0.5); // semi-transparent black
// Fill a region
rt.fill(0x00ff00, 1, 10, 10, 100, 50); // green rect at (10,10) size 100x50
// Clear everything (transparent)
rt.clear();
// Clear a region
rt.clear(10, 10, 100, 50);
rt.render();
消去
消去は ERASE ブレンドモードを使用してテクスチャに穴を開けます:
rt.fill(0xffffff); // white background
rt.erase(circleSprite, 100, 100); // punch a hole shaped like the sprite
rt.render();
テクスチャのリピート / タイリング
// Fill the entire RenderTexture with a tiled pattern
rt.repeat('grass', null); // tile the whole surface
rt.repeat('brick', null, 0, 0, 256, 128); // tile a specific region
rt.repeat('tile', 'frame2', 0, 0, 512, 512, {
tileScaleX: 2,
tileScaleY: 2,
tilePositionX: 16,
alpha: 0.8
});
rt.render();
スナップショット(ピクセルキャプチャ)
スナップショットはフレームバッファからピクセルデータを読み取ります。高コストでブロッキング処理です -- 使用は控えめにしてください。
// Full texture snapshot -- callback receives an HTMLImageElement
rt.snapshot(function (image) {
document.body.appendChild(image); // or use as texture source
});
// Area snapshot
rt.snapshotArea(0, 0, 128, 128, function (image) {
// image is 128x128 region from top-left
}, 'image/jpeg', 0.8);
// Single pixel -- callback receives a Phaser.Display.Color
rt.snapshotPixel(64, 64, function (color) {
console.log(color.r, color.g, color.b, color.a);
});
他のオブジェクトのテクスチャソースとして使用
const rt = this.add.renderTexture(0, 0, 256, 256);
rt.draw(complexScene);
rt.render();
// Register in the Texture Manager under a key
rt.saveTexture('composited');
// Now any game object can use it
this.add.image(400, 300, 'composited');
this.add.sprite(100, 100, 'composited');
// Updates to the RenderTexture automatically reflect on all users
DynamicTexture の場合、キーは作成時に設定されます:
const dt = this.textures.addDynamicTexture('terrain', 1024, 1024);
dt.repeat('grass', null);
dt.render();
this.add.image(512, 512, 'terrain'); // already keyed
プロシージャル生成
const dt = this.textures.addDynamicTexture('starfield', 800, 600);
dt.fill(0x000011);
for (let i = 0; i < 200; i++) {
const x = Phaser.Math.Between(0, 800);
const y = Phaser.Math.Between(0, 600);
const brightness = Phaser.Math.FloatBetween(0.3, 1);
dt.stamp('star', null, x, y, { alpha: brightness, scale: Phaser.Math.FloatBetween(0.5, 1.5) });
}
dt.render();
this.add.image(400, 300, 'starfield');
ミニマップパターン
create() {
// Small RenderTexture as minimap
this.minimap = this.add.renderTexture(700, 50, 150, 100);
this.minimap.setScrollFactor(0); // fixed to camera
this.minimap.setRenderMode('all'); // auto-render every frame
this.minimap.preserve(true);
}
// In update or a callback:
this.minimap.clear();
this.minimap.fill(0x111111);
// Draw scaled-down versions of world objects
this.minimap.capture(player, { x: px * 0.1, y: py * 0.1, scale: 0.1 });
// render() is automatic in 'all' mode
コマンドバッファ内のコールバック
render() 中に実行される描画コマンドの間にロジックを挿入します:
rt.clear();
rt.draw(background);
rt.callback(() => {
// Runs during render, after background is drawn
sprite.setTint(0xff0000);
});
rt.draw(sprite);
rt.callback(() => {
sprite.setTint(0xffffff); // restore after drawing
});
rt.render();
リサイズ
// Resize erases all content and recreates the framebuffer
rt.resize(512, 512);
// Optional: disable force-even rounding
rt.resize(513, 513, false);
内部カメラ
RenderTexture と DynamicTexture の両方に .camera プロパティがあり、描画時にゲームオブジェクトがどのように配置されるかを制御します。このカメラをスクロール、ズーム、回転させて、描画内容を変換します。注意: stamp() はカメラを無視します。カメラを尊重するのは draw() とゲームオブジェクトのレンダリングのみです。
rt.camera.setScroll(100, 50);
rt.camera.setZoom(2);
rt.draw(sprite); // sprite drawn with camera transform applied
rt.render();
API クイックリファレンス
RenderTexture(Image を継承)
| メソッド | シグネチャ | 説明 |
|---|---|---|
draw | (entries, x?, y?, alpha?, tint?) | ゲームオブジェクト、テクスチャ、グループなどを描画 |
capture | (entry, config) | 一時的なプロパティオーバーライドを使用して描画 |
stamp | (key, frame?, x?, y?, config?) | トランスフォーム付きでテクスチャフレームをスタンプ |
erase | (entries, x?, y?) | ERASE ブレンドモードを使用して描画 |
fill | (rgb, alpha?, x?, y?, w?, h?) | 色で塗りつぶし |
clear | (x?, y?, w?, h?) | 透明にクリア |
repeat | (key, frame?, x?, y?, w?, h?, config?) | 塗りつぶしパターンとしてテクスチャをタイリング |
render | () | コマンドバッファをフラッシュ |
preserve | (bool) | レンダリング間でコマンドバッファを保持 |
callback | (fn) | コマンドバッファにコールバックを挿入 |
resize | (w, h?, forceEven?) | リサイズ(内容は消去されます) |
saveTexture | (key) | Texture Manager に登録 |
setRenderMode | (mode, preserve?) | 'render'、'redraw'、または 'all' を設定 |
snapshot | (callback, type?, quality?) | Image へのフルスナップショット |
snapshotArea | (x, y, w, h, callback, type?, quality?) | 領域スナップショット |
snapshotPixel | (x, y, callback) | 単一ピクセルを Color に |
DynamicTexture(Texture を継承)
RenderTexture と同じ描画メソッド(draw、stamp、erase、fill、clear、repeat、capture、render、preserve、callback、snapshot、snapshotArea、snapshotPixel)に加えて:
| メソッド/プロパティ | 説明 |
|---|---|
setSize(w, h?, forceEven?) | テクスチャをリサイズ |
camera | 描画位置指定用の内部カメラ |
commandBuffer | 保留中の描画コマンドの配列 |
drawingContext | フレームバッファ付きの WebGL DrawingContext |
getWebGLTexture() | 基盤となる WebGLTextureWrapper を返す |
StampConfig(stamp() の config パラメータ用)
| プロパティ | デフォルト | 説明 |
|---|---|---|
alpha | 1 | アルファ値 |
tint | 0xffffff | ティントカラー(WebGL のみ) |
angle | 0 | 度数(0 以外の場合、rotation を上書きします) |
rotation | 0 | ラジアン |
scale | 1 | 均一スケール |
scaleX / scaleY | 1 | 軸ごとのスケール(scale を上書きします) |
originX / originY | 0.5 | 原点 |
blendMode | 0 | ブレンドモード |
CaptureConfig(capture() の config パラメータ用)
| プロパティ | 説明 |
|---|---|
transform | 'local'、'world'、または TransformMatrix |
camera | レンダリング用のカメラの上書き |
x、y、alpha、tint、angle、rotation | ゲームオブジェクトのプロパティを一時的に上書きします |
scale、scaleX、scaleY | スケールの上書き |
originX、originY、blendMode | 追加の上書き |
ファクトリメソッド
this.add.renderTexture(x, y, width?, height?) // default 32x32
this.add.stamp(x, y, texture, frame?)
this.textures.addDynamicTexture(key, width?, height?, forceEven?) // default 256x256
注意点
-
必ず
render()を呼び出す必要があります。 Phaser 4 では、描画メソッドはコマンドをバッファリングします。render()が呼び出されるまで何も表示されません(renderMode: 'all'または'redraw'を使用している場合を除く)。 -
自分自身には描画できません。 DynamicTexture/RenderTexture は、自分自身を参照するエントリを黙ってスキップします。
-
コマンドバッファは render 後にクリアされます。 同じコマンドを毎フレーム再生する必要がある場合は、描画する前に
preserve(true)を呼び出してください。 -
stamp()は内部カメラを無視します。draw()またはcapture()で描画されたゲームオブジェクトのみが.cameraプロパティに従います。テクスチャスタンプは絶対位置に配置されます。 -
デフォルトのサイズが異なります。 RenderTexture のデフォルトは 32x32 です。DynamicTexture のデフォルトは 256x256 です。
-
forceEvenは寸法を切り上げます。 デフォルトでは、レンダリング品質のために幅と高さが偶数に丸められます。正確な奇数寸法が必要な場合は、最後の引数にfalseを渡してください。 -
スナップショットは高コストです。 これらは
readPixels(WebGL)を使用し、GPU パイプラインをブロックします。毎フレームのスナップショットは避けてください。snapshotPixelは完全なsnapshotよりも低コストです。 -
WebGL1 ではフレームバッファにアンチエイリアスがありません。 RenderTexture に描画されたシェイプや Graphics はギザギザのエッジになる場合があります。代わりに事前レンダリングされたスプライトテクスチャを使用してください。
-
resize()は内容を消去します。 リサイズするとフレームバッファが破棄され、再作成されます。 -
saveTextureはリネームであり、コピーではありません。saveTexture(key)を呼び出すと、そのキーで DynamicTexture が Texture Manager に割り当てられます。別のキーで再度呼び出すと、名前が変更されます。先に保存せずに RenderTexture を破棄すると、テクスチャが破棄されます。 -
draw()の alpha/tint パラメータは Texture Frame にのみ影響します。 ゲームオブジェクトを描画する場合、それらは自身の alpha 値と tint 値を使用します。draw()のalphaおよびtintパラメータは、テクスチャ文字列または Frame インスタンスを描画する場合にのみ適用されます。 -
WebGL コンテキストロスト。 DynamicTexture の内容はコンテキストロスト時に失われます。再描画するには
restorewebglイベントをリッスンしてください。 -
Group/Container: x, y オフセットは加算されます。
rt.draw(group, x, y)で Group または Container を描画する場合、x/y オフセットは各子の位置に加算されます。(100, 50) にある子をオフセット (10, 10) で描画すると、テクスチャ内では (110, 60) に表示されます。
ソースファイルマップ
| ファイル | 説明 |
|---|---|
src/gameobjects/rendertexture/RenderTexture.js | RenderTexture ゲームオブジェクト(Image を継承し、DynamicTexture にプロキシします) |
src/gameobjects/rendertexture/RenderTextureFactory.js | this.add.renderTexture() ファクトリの登録 |
src/gameobjects/rendertexture/RenderTextureRender.js | RenderTexture の WebGL/Canvas レンダー関数 |
src/gameobjects/rendertexture/RenderTextureRenderModes.js | 列挙型: RENDER、REDRAW、ALL |
src/textures/DynamicTexture.js | コアとなる DynamicTexture クラス(コマンドバッファ、描画、スナップショット) |
src/textures/DynamicTextureCommands.js | コマンド定数(CLEAR、FILL、STAMP、DRAW、ERASE など) |
src/textures/typedefs/StampConfig.js | stamp() 用の StampConfig 型定義 |
src/textures/typedefs/CaptureConfig.js | capture() 用の CaptureConfig 型定義 |
src/gameobjects/stamp/Stamp.js | Stamp ゲームオブジェクト(軽量な Image で、カメラのスクロールを無視します) |
src/gameobjects/stamp/StampFactory.js | this.add.stamp() ファクトリの登録 |