Thanks to Mat Grove’s work, PixiJS 6.1.0 will ship with support for Uniform Buffer Objects, a WebGL 2 optimization to make uniform uploads faster.
Context
UBOs are handles to GPU buffers that store uniform data. They can be attached to a shader in a single step, without needing to upload each uniform field individually. If you share uniforms between multiple shaders, this can be used to reduce uploads of relatively static data.
Theoretically, you can optimize filters with UBOs. The common uniforms passed to Filter
don’t change between them: inputSize
, inputPixel
, inputClamp
, outputFrame
.
Usage
To use UBOs in a shader, you’ll need to use GLSL 3 ES.
#version 300 es
#define SHADER_NAME Example-Shader
precision highp float;
To migrate an existing GLSL 1 shader (the default), you need to use the in
keyword instead of attribute
, out
instead of varying
in the vertex shader, in
instead of varying
in the fragment shader, and then create an out
variable in the fragment shader instead of using gl_FragColor
.
You can then move some of your uniforms into a UBO block:
uniform location_data {
mat3 locationMatrix;
};
In this example, you can reference the locationMatrix
uniform directly.
void main(void) {
mat3 matrix = locationMatrix;
}
To upload the UBO uniforms, you need to add an UniformBufferGroup
in PixiJS in your shader’s uniform.
import { Shader, UniformBufferGroup } from 'pixi.js';
Shader.from(vertexSrc, fragmentSrc, {
location_data: UniformBufferGroup.uboFrom({
locationMatrix: new Matrix().toArray(),
}),
})
UniformBufferGroup.uboFrom
creates a “static” UBO. If you ever change a value in it, you’ll need to update
it.
Here’s an example that applies a gradient color to a texture using a UBO:
When should I use UBOs?
UBOs are useful if you have multiple shaders that share static uniform data. If your uniforms are dynamic and change very often, UBOs will not be much of an optimization.