Phaser использует WebGL для рендеринга графики, что позволяет применять GLSL-шейдеры для создания сложных визуальных эффектов. Шейдеры делятся на вершинные (vertex) и фрагментные (fragment). Вершинные шейдеры управляют положением вершин на экране, а фрагментные — цветом каждого пикселя. В Phaser чаще используются фрагментные шейдеры для эффектов постобработки, фильтров и анимации текстур.
Каждый шейдер состоит из двух ключевых компонентов:
Пример простого фрагментного шейдера:
precision mediump float;
uniform float u_time;
uniform vec2 u_resolution;
void main() {
vec2 st = gl_FragCoord.xy / u_resolution;
gl_FragColor = vec4(st.x, st.y, abs(sin(u_time)), 1.0);
}
Здесь u_time и u_resolution —
uniforms, которые будут обновляться с каждой итерацией
в Phaser.
Phaser 3 предоставляет удобный класс
Phaser.Renderer.WebGL.Pipelines.PostFXPipeline
для интеграции пользовательских шейдеров. Основные шаги:
class MyShaderPipeline extends Phaser.Renderer.WebGL.Pipelines.PostFXPipeline {
constructor(game) {
super({
game,
fragShader: document.getElementById('myShader').textContent
});
}
onPreRender() {
this.setFloat1('u_time', this.game.loop.time / 1000);
this.set2f('u_resolution', this.game.scale.width, this.game.scale.height);
}
}
onPreRender вызывается перед каждым кадром для
обновления uniforms.setFloat1 и set2f устанавливают значения
для шейдера.const config = {
type: Phaser.WEBGL,
width: 800,
height: 600,
scene: { preload, create },
pipeline: { myShader: MyShaderPipeline }
};
const game = new Phaser.Game(config);
this.add.sprite(400, 300, 'myTexture').setPipeline('myShader');
Теперь к спрайту будет применяться фрагментный шейдер с переданными uniform-параметрами.
Attributes передаются шейдеру через вершинные данные, чаще всего в форме буферов. Phaser автоматически создаёт стандартные атрибуты:
aPosition — координаты вершины;aTexCoord — текстурные координаты;aColor — цвет вершины.Создание кастомного атрибута:
this.renderer.setVertexAttrib('aCustom', new Float32Array([0, 1, 0, 1]), 2);
vec2).В шейдере атрибут объявляется как:
attribute vec2 aCustom;
Использование атрибута позволяет создавать динамическую деформацию спрайтов и эффекты искажения без изменения текстуры на стороне CPU.
Uniforms бывают различных типов:
float, vec2, vec3,
vec4 — скаляры и векторы;sampler2D — текстурные объекты;int, bool — целые числа и булевы
значения.В Phaser uniforms обновляются через методы пайплайна:
setFloat1(name, value) — float;setFloat2(name, x, y) — vec2;setFloat3(name, x, y, z) — vec3;setFloat4(name, x, y, z, w) — vec4;setTexture(name, texture) — sampler2D.Пример динамического изменения цвета:
this.pipeline.setFloat1('u_time', this.game.loop.time / 1000);
this.pipeline.setFloat3('u_color', Math.sin(t), Math.cos(t), Math.sin(t * 0.5));
gl_FragColor = vec4(abs(sin(u_time)), st.y, st.x, 1.0);
u_time позволяет создавать пульсирующие,
волновые и мерцающие эффекты.vec2 newPos = aTexCoord + vec2(sin(aPosition.x * 10.0 + u_time) * 0.05, 0.0);
vec4 color = texture2D(uSampler, newPos);
aPosition используется для искажения текстуры,
создавая эффект волн или колебаний.vec4 texColor = texture2D(uSampler, aTexCoord);
vec4 maskColor = texture2D(uMask, aTexCoord);
gl_FragColor = texColor * maskColor.a;
u_resolution для независимости от размера экрана.mediump для точности и производительности
на мобильных устройствах.onPreRender гарантирует
синхронизацию с игровым циклом.<script type="x-shader/x-fragment"> и вставлять текст
в Phaser через document.getElementById.Эта методология позволяет создавать сложные визуальные эффекты в Phaser, сочетая динамические uniforms, кастомные атрибуты и фрагментные шейдеры, обеспечивая как производительность, так и гибкость в дизайне графики.