Summary
BoxShadowFilter appears to create very high GPU usage when applied to static display objects in a continuously-rendered PixiJS v8 scene. Even when the filter instances and scene are stable, the GPU cost remains high every frame.
This came up in a real app using pixi-box-shadow@1.2.0 with PixiJS v8. The scene is visually static except for a few connector animations, but the app intentionally keeps the Pixi ticker/render loop running to measure realistic runtime behavior.
Environment
- Hardware: MacBook Pro M2 Max
- Browser: Chrome via local Vite dev server
- PixiJS:
pixi.js@8.18.1
- pixi-box-shadow:
pixi-box-shadow@1.2.0
- App renderer: WebGL (
preference: "webgl")
- Canvas size: about 641 x 561 logical px, using
window.devicePixelRatio
Observed GPU Usage
Measured via macOS Activity Monitor GPU usage:
- Normal scene with box-shadow filters: ~80% GPU
- Disable only texture-mode icon shadows: ~30% GPU
- Disable all
BoxShadowFilter usage: ~10% GPU
So the texture-mode shadows are the largest cost, but the non-texture box/card/accent shadows still add a large amount of GPU work.
Filters in the Scene
The app uses only BoxShadowFilter; no other Pixi filters are present.
- Card shadow on icon-box card fill:
new BoxShadowFilter({
boxShadow:
"0 12px 24px rgba(0, 0, 0, 0.04), 0 6px 12px rgba(0, 0, 0, 0.02), 0 3px 6px rgba(0, 0, 0, 0.01)",
borderRadius: 8,
});
- Accent bar glow using
shapeMode: "box":
new BoxShadowFilter({
shapeMode: "box",
borderRadius: 0,
shadows: [
{ offsetX: 0, offsetY: 4, blur: 12, spread: 0, color: fillRgb, alpha: 0.32, inset: false },
{ offsetX: 0, offsetY: 2, blur: 4, spread: 0, color: fillRgb, alpha: 0.12, inset: false },
{ offsetX: 0, offsetY: 1, blur: 1, spread: 0, color: fillRgb, alpha: 0.16, inset: false },
{ offsetX: 0, offsetY: 0.5, blur: 1, spread: 0, color: fillRgb, alpha: 0.12, inset: false },
],
});
- Icon drop shadow using
shapeMode: "texture":
new BoxShadowFilter({
shapeMode: "texture",
quality: 4,
shadows: [
{ offsetX: 0, offsetY: 0.5, blur: 1, spread: 0, color: iconColorHex, alpha: 0.12, inset: false },
{ offsetX: 0, offsetY: 1, blur: 2, spread: 0, color: iconColorHex, alpha: 0.12, inset: false },
],
});
The app caches/reuses filter objects by shadow parameters, but GPU usage does not improve meaningfully, which suggests the expensive part is the per-frame offscreen/filter/composite work rather than JS allocation.
Reproduction Steps
- Create a PixiJS v8 app with
autoStart: true, WebGL renderer, and a continuously-running ticker/render loop.
- Add multiple static display objects with
BoxShadowFilter applied, including several texture-mode filters.
- Let the scene sit idle; do not mutate the filtered display objects.
- Watch GPU usage in Activity Monitor.
- Toggle filters off and compare GPU usage.
In the real app:
- Normal: ~80% GPU
- Texture-mode shadows disabled: ~30% GPU
- All box-shadow filters disabled: ~10% GPU
Expected Behavior
Static shadows should be much cheaper in a continuously-rendered Pixi scene. Ideally the library could avoid re-running expensive shadow work every frame when the target object and shadow parameters have not changed.
Potential directions:
- Internal cache/render-texture path for static filter output.
- A documented/static mode that bakes the shadow into a texture until invalidated.
- Better defaults or optimizations for
shapeMode: "texture".
- Guidance around
filterArea, padding, resolution, or Pixi cache APIs if user-land configuration can fix this.
Why This Matters
For canvas/editor apps, keeping the ticker/render loop alive can be the correct runtime model. The current cost makes static box shadows too expensive in that setup, especially on high-end Apple Silicon where ~75-80% GPU usage for a mostly static small canvas is surprising.
Summary
BoxShadowFilterappears to create very high GPU usage when applied to static display objects in a continuously-rendered PixiJS v8 scene. Even when the filter instances and scene are stable, the GPU cost remains high every frame.This came up in a real app using
pixi-box-shadow@1.2.0with PixiJS v8. The scene is visually static except for a few connector animations, but the app intentionally keeps the Pixi ticker/render loop running to measure realistic runtime behavior.Environment
pixi.js@8.18.1pixi-box-shadow@1.2.0preference: "webgl")window.devicePixelRatioObserved GPU Usage
Measured via macOS Activity Monitor GPU usage:
BoxShadowFilterusage: ~10% GPUSo the texture-mode shadows are the largest cost, but the non-texture box/card/accent shadows still add a large amount of GPU work.
Filters in the Scene
The app uses only
BoxShadowFilter; no other Pixi filters are present.shapeMode: "box":shapeMode: "texture":The app caches/reuses filter objects by shadow parameters, but GPU usage does not improve meaningfully, which suggests the expensive part is the per-frame offscreen/filter/composite work rather than JS allocation.
Reproduction Steps
autoStart: true, WebGL renderer, and a continuously-running ticker/render loop.BoxShadowFilterapplied, including several texture-mode filters.In the real app:
Expected Behavior
Static shadows should be much cheaper in a continuously-rendered Pixi scene. Ideally the library could avoid re-running expensive shadow work every frame when the target object and shadow parameters have not changed.
Potential directions:
shapeMode: "texture".filterArea, padding, resolution, or Pixi cache APIs if user-land configuration can fix this.Why This Matters
For canvas/editor apps, keeping the ticker/render loop alive can be the correct runtime model. The current cost makes static box shadows too expensive in that setup, especially on high-end Apple Silicon where ~75-80% GPU usage for a mostly static small canvas is surprising.