Uniform-переменные — это специальные глобальные переменные шейдера,
значения которых остаются неизменными для всех вершин или фрагментов в
рамках одного вызова отрисовки. В экосистеме PixiJS они используются при
создании пользовательских фильтров (PIXI.Filter), кастомных
шейдеров (PIXI.Shader) и низкоуровневой работы с WebGL
через систему рендеринга.
Uniform-переменные:
uniform;vertex), так и во
фрагментном (fragment) шейдере;Пример объявления во фрагментном шейдере:
precision mediump float;
uniform float uTime;
uniform vec2 uResolution;
uniform sampler2D uTexture;
void main() {
vec2 uv = gl_FragCoord.xy / uResolution;
vec4 color = texture2D(uTexture, uv);
gl_FragColor = color * abs(sin(uTime));
}
Здесь используются три типа uniform-переменных:
floatvec2sampler2DВ PixiJS uniform-переменные передаются через объект
uniforms при создании PIXI.Filter или
PIXI.Shader.
const fragmentShader = `
precision mediump float;
uniform float uTime;
uniform vec2 uResolution;
uniform sampler2D uSampler;
varying vec2 vTextureCoord;
void main() {
vec4 color = texture2D(uSampler, vTextureCoord);
gl_FragColor = color * abs(sin(uTime));
}
`;
const filter = new PIXI.Filter(null, fragmentShader, {
uTime: 0.0,
uResolution: [800, 600]
});
Uniform-переменные задаются как свойства обычного JavaScript-объекта.
floatGLSL:
uniform float uAlpha;
PixiJS:
uniforms: {
uAlpha: 1.0
}
Тип значения в JavaScript — number.
intGLSL:
uniform int uMode;
PixiJS:
uniforms: {
uMode: 2
}
Передаётся как обычное число. WebGL автоматически приводит его к целочисленному типу.
vec2GLSL:
uniform vec2 uOffset;
PixiJS:
uniforms: {
uOffset: [100.0, 50.0]
}
Передаётся как массив из двух чисел.
vec3uniform vec3 uColor;
uniforms: {
uColor: [1.0, 0.5, 0.2]
}
Используется для RGB-цветов, направлений, координат в 3D.
vec4uniform vec4 uColor;
uniforms: {
uColor: [1.0, 0.5, 0.2, 1.0]
}
Применяется для RGBA-цвета, прямоугольных областей, параметров.
mat3uniform mat3 uMatrix;
PixiJS:
uniforms: {
uMatrix: [
1, 0, 0,
0, 1, 0,
0, 0, 1
]
}
Передаётся как массив из 9 чисел (column-major порядок).
mat4uniform mat4 uProjection;
uniforms: {
uProjection: new Float32Array(16)
}
Рекомендуется использовать Float32Array для матриц
размером 4x4.
sampler2DТекстуры передаются иначе, чем примитивные типы.
GLSL:
uniform sampler2D uTexture;
PixiJS:
uniforms: {
uTexture: PIXI.Texture.from('image.png')
}
При использовании PIXI.Filter стандартный uniform
uSampler автоматически содержит текстуру объекта, к
которому применён фильтр.
Uniform можно изменять во время выполнения:
app.ticker.add((delta) => {
filter.uniforms.uTime += 0.05 * delta;
});
PixiJS отслеживает изменения и передаёт обновлённые значения в GPU перед отрисовкой.
Особенности:
filter.uniforms;uniforms не должен полностью заменяться;Правильно:
filter.uniforms.uTime = 1.5;
Неправильно:
filter.uniforms = { uTime: 1.5 };
Во втором случае связь с внутренней системой рендеринга нарушается.
WebGL 1.0 (используется PixiJS) имеет ограничения:
struct) поддерживаются;GLSL:
struct Light {
vec2 position;
vec3 color;
};
uniform Light uLight;
Передача в PixiJS:
uniforms: {
uLight: {
position: [300, 200],
color: [1.0, 1.0, 1.0]
}
}
PixiJS автоматически развернёт структуру в соответствующие uniform-переменные WebGL.
GLSL:
uniform float uWeights[5];
PixiJS:
uniforms: {
uWeights: [0.2, 0.3, 0.1, 0.25, 0.15]
}
uniform vec2 uPoints[3];
uniforms: {
uPoints: [
100, 100,
200, 200,
300, 300
]
}
Массив передаётся как плоский список значений.
При использовании PIXI.Filter система автоматически
добавляет:
uSampler — текстура объекта;inputSize — размер входной текстуры;outputFrame — область вывода;resolution — масштаб рендеринга;projectionMatrix — матрица проекции.Эти переменные не требуют явного указания в
uniforms.
Изменение uniform вызывает синхронизацию CPU → GPU. Частые изменения больших массивов могут стать узким местом.
Рекомендации:
Float32Array для больших данных;Проверка лимитов:
const gl = app.renderer.gl;
console.log(gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS));
uniform vec2 uOffset;
uOffset: 10
Ошибка: требуется массив из двух чисел.
GLSL использует column-major порядок. Неправильное заполнение матрицы приводит к искажению трансформаций.
Во фрагментном шейдере необходимо указывать точность:
precision mediump float;
Без этого шейдер может не скомпилироваться.
Создание PIXI.Shader напрямую:
const program = PIXI.Program.from(vertexSource, fragmentSource);
const shader = new PIXI.Shader(program, {
uTime: 0.0
});
Такой подход применяется при создании Mesh,
Geometry и низкоуровневых графических примитивов.
Внутри PixiJS:
Shader хранит UniformGroup;Это снижает количество вызовов gl.uniform*.
GLSL:
precision mediump float;
uniform float uTime;
varying vec2 vTextureCoord;
uniform sampler2D uSampler;
void main() {
vec4 color = texture2D(uSampler, vTextureCoord);
color.r += sin(uTime) * 0.2;
gl_FragColor = color;
}
Jav * aScript:
const filter = new PIXI.Filter(null, fragmentShader, {
uTime: 0
});
sprite.filters = [filter];
app.ticker.add((delta) => {
filter.uniforms.uTime += 0.05 * delta;
});
В результате происходит динамическое изменение красного канала изображения.
Uniform-переменные являются ключевым механизмом передачи данных между JavaScript и GPU в PixiJS. Понимание их типов, ограничений и особенностей передачи позволяет создавать производительные фильтры, кастомные шейдеры и сложные графические эффекты.