Phaser предоставляет мощный механизм для работы с графикой через WebGL, позволяя создавать кастомные пайплайны, которые обрабатывают рендеринг спрайтов и шейдеров на GPU. Кастомные пайплайны позволяют реализовать уникальные визуальные эффекты, которых невозможно достичь стандартными средствами Phaser, включая постобработку сцен, специальные фильтры и сложные анимации.
В Phaser 3 кастомный пайплайн строится на основе класса
Phaser.Renderer.WebGL.Pipelines.SinglePipeline или
MultiPipeline, если требуется более сложная обработка. Для
начала необходимо создать новый класс, наследующийся от
SinglePipeline:
class CustomPipeline extends Phaser.Renderer.WebGL.Pipelines.SinglePipeline {
constructor(game) {
super({
game: game,
fragShader: `
precision mediump float;
uniform sampler2D uMainSampler;
varying vec2 outTexCoord;
void main(void) {
vec4 color = texture2D(uMainSampler, outTexCoord);
color.r = 1.0 - color.r; // Инверсия красного канала
gl_FragColor = color;
}
`
});
}
}
Ключевые моменты:
fragShader содержит GLSL-фрагментный шейдер, который
будет выполняться на GPU.uMainSampler автоматически подставляется Phaser и
представляет текстуру рендеримого объекта.outTexCoord — координаты текущего пикселя.После создания класса пайплайн необходимо зарегистрировать в рендерере Phaser:
const config = {
type: Phaser.WEBGL,
width: 800,
height: 600,
scene: {
preload: preload,
create: create
},
pipeline: { CustomPipeline }
};
const game = new Phaser.Game(config);
function create() {
this.customPipeline = this.renderer.pipelines.add('CustomPipeline', new CustomPipeline(this.game));
const sprite = this.add.sprite(400, 300, 'myTexture');
sprite.setPipeline('CustomPipeline');
}
Обратите внимание:
pipelines.add позволяет добавить кастомный
пайплайн с уникальным именем.setPipeline привязывает пайплайн к конкретному
объекту.Для динамического управления эффектами часто применяются uniform-переменные GLSL. Их можно задавать и обновлять из кода Phaser:
this.customPipeline.setFloat1('time', 0);
this.tweens.addCounter({
from: 0,
to: 1,
duration: 2000,
yoyo: true,
repeat: -1,
onUpdate: (tween) => {
this.customPipeline.setFloat1('time', tween.getValue());
}
});
Ключевые моменты:
setFloat1, setFloat2,
setFloat3, setFloat4 позволяют задавать
float-переменные для шейдера.По умолчанию SinglePipeline использует стандартный
вершинный шейдер Phaser. Для полного контроля можно создать собственный
вершинный шейдер:
class VertexCustomPipeline extends Phaser.Renderer.WebGL.Pipelines.SinglePipeline {
constructor(game) {
super({
game: game,
vertShader: `
attribute vec2 inPosition;
attribute vec2 inTexCoord;
uniform mat4 uProjectionMatrix;
varying vec2 outTexCoord;
void main(void) {
gl_Position = uProjectionMatrix * vec4(inPosition, 0.0, 1.0);
outTexCoord = inTexCoord;
}
`,
fragShader: defaultFragShader
});
}
}
Важно понимать:
uProjectionMatrix обеспечивает корректное отображение
объектов на экране.Кастомный пайплайн удобно использовать для пост-эффектов на всей сцене. Это делается через рендер-таргеты:
const rt = this.add.renderTexture(0, 0, 800, 600);
rt.draw(this.add.sprite(400, 300, 'myTexture'));
rt.setPipeline('CustomPipeline');
Преимущество такого подхода:
Кастомные пайплайны работают на GPU и требуют минимальных операций на CPU. Для оптимизации:
MultiPipeline только при необходимости
обработки нескольких текстур.Сдвиг цветов (Chromatic Shift):
Размытие (Blur):
Волновая деформация:
Каждый из этих эффектов реализуется через модификацию фрагментного шейдера и передачу параметров через uniform. В сочетании с Phaser это открывает практически неограниченные возможности для кастомной графики.