Compose シェーダーのカスタマイズ
カスタムポストエフェクトを追加する最も簡単な方法は、すべてのエフェクトを合成してバックバッファへ出力する最終の compose パスをカスタマイズすることです。追加のレンダーパスが不要で、最終出力だけを変更したい場合に適しています。
概要
CameraFrame を作成する前にシェーダーチャンクを上書きすることで、カスタムシェーダーコードを注入できます。compose パスには、カスタマイズ用に空のチャンクが 3 つ用意されています。
composeDeclarationsPS— カスタムユニフォーム宣言とヘルパー関数を追加composeMainStartPS—main関数の先頭にコードを追加composeMainEndPS— 最終出力の直前、main関数の末尾にコードを追加
例:簡単なピクセル化エフェクト
ピクセル化エフェクトを追加する完全な例です。
import * as pc from 'playcanvas';
// Override compose shader chunks before creating CameraFrame
const shaderChunks = pc.ShaderChunks.get(graphicsDevice, pc.SHADERLANGUAGE_GLSL);
shaderChunks.set('composeDeclarationsPS', `
uniform float pixelSize;
`);
shaderChunks.set('composeMainEndPS', `
// Apply pixelation effect
vec2 pixelatedUV = floor(uv0 / pixelSize) * pixelSize;
color = getLinear(texture2D(sceneTexture, pixelatedUV));
`);
// For WebGPU, also set WGSL chunks
const wgslChunks = pc.ShaderChunks.get(graphicsDevice, pc.SHADERLANGUAGE_WGSL);
wgslChunks.set('composeDeclarationsPS', `
uniform pixelSize: f32;
`);
wgslChunks.set('composeMainEndPS', `
let pixelatedUV: vec2f = floor(input.uv0 / uniform.pixelSize) * uniform.pixelSize;
color = getLinear(textureSample(sceneTexture, sceneTextureSampler, pixelatedUV));
`);
// Now create the CameraFrame
const cameraFrame = new pc.CameraFrame(app, cameraEntity.camera);
cameraFrame.update();
// Set the custom uniform value
app.on('update', () => {
graphicsDevice.scope.resolve('pixelSize').setValue(0.005);
});
重要な注意
- グローバルな適用:シェーダーチャンクへの変更は、すべての
CameraFrameインスタンスにグローバルに適用されます。 - WebGPU のサポート:クロスプラットフォーム互換のため、GLSL と WGSL の両方のシェーダーチャンクを用意してください。
- タイミング:シェーダーチャンクは、
CameraFrameインスタンスを作成する前に設定する必要があります。
参考資料
- Custom Compose Shader の例 — 動作する完全なデモ
用途
この方法は次のような場合に適しています。
- 単純なスクリーンスペースエフェクト(ビネット、色調整、歪み)を追加する
- 追加のテクスチャやレンダーパスを必要としないポストプロセスを行う
- 視覚効果の迅速なプロトタイピングを行う
- 最終的に合成された画像に対して動作するエフェクトを適用する