@docyrus/animaguru 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.md +256 -0
- package/README.md +241 -0
- package/dist/animaguru.js +27338 -0
- package/package.json +37 -0
- package/skills/animaguru/SKILL.md +115 -0
- package/skills/animaguru-advertising/SKILL.md +25 -0
- package/skills/animaguru-advertising/references/brand-bumper.md +11 -0
- package/skills/animaguru-advertising/references/comparison.md +11 -0
- package/skills/animaguru-advertising/references/creator-testimonial.md +11 -0
- package/skills/animaguru-advertising/references/editorial-advertorial.md +11 -0
- package/skills/animaguru-advertising/references/game-reward.md +11 -0
- package/skills/animaguru-advertising/references/offer-promotion.md +11 -0
- package/skills/animaguru-advertising/references/product-launch.md +11 -0
- package/skills/animaguru-advertising/references/product-proof.md +11 -0
- package/skills/animaguru-analog-film-tape/SKILL.md +29 -0
- package/skills/animaguru-analog-film-tape/references/recipe.md +23 -0
- package/skills/animaguru-animated-data-visualization/SKILL.md +39 -0
- package/skills/animaguru-animated-data-visualization/references/data-contract.md +16 -0
- package/skills/animaguru-animated-data-visualization/references/variants.md +17 -0
- package/skills/animaguru-art-deco-motion/SKILL.md +29 -0
- package/skills/animaguru-art-deco-motion/references/recipe.md +22 -0
- package/skills/animaguru-ascii-crt/SKILL.md +29 -0
- package/skills/animaguru-ascii-crt/references/recipe.md +22 -0
- package/skills/animaguru-blueprint-drafting/SKILL.md +29 -0
- package/skills/animaguru-blueprint-drafting/references/recipe.md +22 -0
- package/skills/animaguru-cartoon-character-animation/SKILL.md +35 -0
- package/skills/animaguru-cartoon-character-animation/references/variants.md +17 -0
- package/skills/animaguru-cutout-animation/SKILL.md +33 -0
- package/skills/animaguru-cutout-animation/references/production-recipe.md +37 -0
- package/skills/animaguru-cutout-animation/references/variants.md +17 -0
- package/skills/animaguru-cutout-animation/references/visual-style.md +34 -0
- package/skills/animaguru-dark-tech-stage/SKILL.md +29 -0
- package/skills/animaguru-dark-tech-stage/references/recipe.md +23 -0
- package/skills/animaguru-diagram-formula-motion/SKILL.md +36 -0
- package/skills/animaguru-diagram-formula-motion/references/variants.md +17 -0
- package/skills/animaguru-engraved-relief-print/SKILL.md +29 -0
- package/skills/animaguru-engraved-relief-print/references/recipe.md +24 -0
- package/skills/animaguru-flat-vector-motion/SKILL.md +35 -0
- package/skills/animaguru-flat-vector-motion/references/variants.md +17 -0
- package/skills/animaguru-general-video/SKILL.md +20 -0
- package/skills/animaguru-general-video/references/ambient-loop.md +11 -0
- package/skills/animaguru-general-video/references/music-lyrics.md +11 -0
- package/skills/animaguru-general-video/references/short-film.md +11 -0
- package/skills/animaguru-general-video/references/titles-event.md +11 -0
- package/skills/animaguru-general-video/references/visual-essay.md +11 -0
- package/skills/animaguru-generative-light-signal/SKILL.md +29 -0
- package/skills/animaguru-generative-light-signal/references/recipe.md +23 -0
- package/skills/animaguru-glass-mosaic/SKILL.md +29 -0
- package/skills/animaguru-glass-mosaic/references/recipe.md +23 -0
- package/skills/animaguru-halftone-editorial/SKILL.md +29 -0
- package/skills/animaguru-halftone-editorial/references/recipe.md +23 -0
- package/skills/animaguru-holographic-scan/SKILL.md +29 -0
- package/skills/animaguru-holographic-scan/references/recipe.md +22 -0
- package/skills/animaguru-interface-motion/SKILL.md +36 -0
- package/skills/animaguru-interface-motion/references/screen-mapping.md +16 -0
- package/skills/animaguru-interface-motion/references/variants.md +17 -0
- package/skills/animaguru-isometric-worlds/SKILL.md +35 -0
- package/skills/animaguru-isometric-worlds/references/variants.md +17 -0
- package/skills/animaguru-kinetic-typography/SKILL.md +35 -0
- package/skills/animaguru-kinetic-typography/references/variants.md +17 -0
- package/skills/animaguru-miniature-diorama/SKILL.md +29 -0
- package/skills/animaguru-miniature-diorama/references/recipe.md +23 -0
- package/skills/animaguru-painterly-depth-animation/SKILL.md +35 -0
- package/skills/animaguru-painterly-depth-animation/references/variants.md +17 -0
- package/skills/animaguru-paper-popup/SKILL.md +29 -0
- package/skills/animaguru-paper-popup/references/recipe.md +22 -0
- package/skills/animaguru-photo-footage-editorial/SKILL.md +29 -0
- package/skills/animaguru-photo-footage-editorial/references/recipe.md +23 -0
- package/skills/animaguru-pixel-art-animation/SKILL.md +36 -0
- package/skills/animaguru-pixel-art-animation/references/variants.md +17 -0
- package/skills/animaguru-portal-zoom/SKILL.md +29 -0
- package/skills/animaguru-portal-zoom/references/recipe.md +21 -0
- package/skills/animaguru-risograph-print/SKILL.md +29 -0
- package/skills/animaguru-risograph-print/references/recipe.md +23 -0
- package/skills/animaguru-sand-drawing/SKILL.md +29 -0
- package/skills/animaguru-sand-drawing/references/recipe.md +21 -0
- package/skills/animaguru-shadow-theatre/SKILL.md +29 -0
- package/skills/animaguru-shadow-theatre/references/recipe.md +23 -0
- package/skills/animaguru-silkscreen-poster/SKILL.md +29 -0
- package/skills/animaguru-silkscreen-poster/references/recipe.md +22 -0
- package/skills/animaguru-stop-motion-objects/SKILL.md +29 -0
- package/skills/animaguru-stop-motion-objects/references/recipe.md +23 -0
- package/skills/animaguru-studio-product-reveal/SKILL.md +29 -0
- package/skills/animaguru-studio-product-reveal/references/recipe.md +23 -0
- package/skills/animaguru-video/SKILL.md +79 -0
- package/skills/animaguru-whiteboard-line-drawing/SKILL.md +34 -0
- package/skills/animaguru-whiteboard-line-drawing/references/variants.md +17 -0
- package/templates/video/AGENTS.md +34 -0
- package/templates/video/CLAUDE.md +19 -0
- package/templates/video/README.md +101 -0
- package/templates/video/VIDEO-STYLE-NOTICES.txt +54 -0
- package/templates/video/film.config.json +10 -0
- package/templates/video/gitignore +11 -0
- package/templates/video/index.html +14 -0
- package/templates/video/package.json +28 -0
- package/templates/video/public/brand/logo-mark.svg +5 -0
- package/templates/video/scripts/build.mjs +12 -0
- package/templates/video/scripts/export-html.mjs +12 -0
- package/templates/video/scripts/export-mp4.mjs +209 -0
- package/templates/video/scripts/html-export-plugin.mjs +35 -0
- package/templates/video/scripts/html-export.mjs +54 -0
- package/templates/video/scripts/install-example.mjs +32 -0
- package/templates/video/scripts/review-analysis.mjs +29 -0
- package/templates/video/scripts/review-audio.mjs +24 -0
- package/templates/video/scripts/review.mjs +37 -0
- package/templates/video/scripts/starter-film.sha256 +1 -0
- package/templates/video/shared/locales/en/export.json +10 -0
- package/templates/video/shared/locales/en/film.json +42 -0
- package/templates/video/shared/locales/en/player.json +31 -0
- package/templates/video/shared/locales/en/style-studies.json +168 -0
- package/templates/video/shared/locales/en/timeline.json +33 -0
- package/templates/video/src/assets.ts +4 -0
- package/templates/video/src/download.ts +27 -0
- package/templates/video/src/exporter.ts +70 -0
- package/templates/video/src/film-resources.ts +29 -0
- package/templates/video/src/film.ts +132 -0
- package/templates/video/src/main.ts +219 -0
- package/templates/video/src/resource-timeline.ts +193 -0
- package/templates/video/src/review.ts +50 -0
- package/templates/video/src/studies/film.ts +26 -0
- package/templates/video/src/studies/media.ts +46 -0
- package/templates/video/src/studies/model.ts +60 -0
- package/templates/video/src/studies/pixi-renderer.ts +121 -0
- package/templates/video/src/studies/scenes.ts +410 -0
- package/templates/video/src/studies/timing.ts +53 -0
- package/templates/video/src/studies/variants.ts +39 -0
- package/templates/video/src/style.css +111 -0
- package/templates/video/src/timeline-model.ts +55 -0
- package/templates/video/style-source-provenance.json +11 -0
- package/templates/video/tsconfig.json +15 -0
- package/templates/video/vite.config.mjs +9 -0
- package/vendor/pixijs-skills/LICENSE +21 -0
- package/vendor/pixijs-skills/provenance.json +79 -0
- package/vendor/pixijs-skills/skills/pixijs/SKILL.md +66 -0
- package/vendor/pixijs-skills/skills/pixijs/references/index.md +136 -0
- package/vendor/pixijs-skills/skills/pixijs-accessibility/SKILL.md +224 -0
- package/vendor/pixijs-skills/skills/pixijs-application/SKILL.md +293 -0
- package/vendor/pixijs-skills/skills/pixijs-application/references/application-options.md +314 -0
- package/vendor/pixijs-skills/skills/pixijs-assets/SKILL.md +303 -0
- package/vendor/pixijs-skills/skills/pixijs-assets/references/background.md +137 -0
- package/vendor/pixijs-skills/skills/pixijs-assets/references/bundles.md +122 -0
- package/vendor/pixijs-skills/skills/pixijs-assets/references/caching.md +143 -0
- package/vendor/pixijs-skills/skills/pixijs-assets/references/compressed-textures.md +120 -0
- package/vendor/pixijs-skills/skills/pixijs-assets/references/fonts.md +205 -0
- package/vendor/pixijs-skills/skills/pixijs-assets/references/gif.md +171 -0
- package/vendor/pixijs-skills/skills/pixijs-assets/references/manifests.md +175 -0
- package/vendor/pixijs-skills/skills/pixijs-assets/references/progress.md +142 -0
- package/vendor/pixijs-skills/skills/pixijs-assets/references/resolution.md +142 -0
- package/vendor/pixijs-skills/skills/pixijs-assets/references/spritesheet.md +119 -0
- package/vendor/pixijs-skills/skills/pixijs-assets/references/svg.md +132 -0
- package/vendor/pixijs-skills/skills/pixijs-assets/references/video.md +158 -0
- package/vendor/pixijs-skills/skills/pixijs-blend-modes/SKILL.md +215 -0
- package/vendor/pixijs-skills/skills/pixijs-color/SKILL.md +299 -0
- package/vendor/pixijs-skills/skills/pixijs-core-concepts/SKILL.md +132 -0
- package/vendor/pixijs-skills/skills/pixijs-core-concepts/references/render-loop.md +216 -0
- package/vendor/pixijs-skills/skills/pixijs-core-concepts/references/renderers.md +287 -0
- package/vendor/pixijs-skills/skills/pixijs-create/SKILL.md +276 -0
- package/vendor/pixijs-skills/skills/pixijs-custom-rendering/SKILL.md +405 -0
- package/vendor/pixijs-skills/skills/pixijs-custom-rendering/references/advanced-gpu.md +244 -0
- package/vendor/pixijs-skills/skills/pixijs-custom-rendering/references/uniform-types.md +94 -0
- package/vendor/pixijs-skills/skills/pixijs-environments/SKILL.md +243 -0
- package/vendor/pixijs-skills/skills/pixijs-events/SKILL.md +387 -0
- package/vendor/pixijs-skills/skills/pixijs-filters/SKILL.md +300 -0
- package/vendor/pixijs-skills/skills/pixijs-html-source/SKILL.md +228 -0
- package/vendor/pixijs-skills/skills/pixijs-math/SKILL.md +489 -0
- package/vendor/pixijs-skills/skills/pixijs-migration-v8/SKILL.md +415 -0
- package/vendor/pixijs-skills/skills/pixijs-performance/SKILL.md +489 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-container/SKILL.md +345 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-core-concepts/SKILL.md +243 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-core-concepts/references/constructor-options.md +155 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-core-concepts/references/container-hierarchy.md +232 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-core-concepts/references/layers.md +145 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-core-concepts/references/masking.md +129 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-core-concepts/references/render-groups.md +140 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-core-concepts/references/scene-management.md +169 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-core-concepts/references/transforms.md +198 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-dom-container/SKILL.md +193 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-gif/SKILL.md +233 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-graphics/SKILL.md +576 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-mesh/SKILL.md +141 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-mesh/references/mesh-perspective.md +189 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-mesh/references/mesh-plane.md +159 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-mesh/references/mesh-rope.md +176 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-mesh/references/mesh-simple.md +144 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-mesh/references/mesh.md +213 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-particle-container/SKILL.md +323 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-sprite/SKILL.md +120 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-sprite/references/animated-sprite.md +262 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-sprite/references/nineslice-sprite.md +202 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-sprite/references/sprite.md +181 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-sprite/references/tiling-sprite.md +216 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-text/SKILL.md +136 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-text/references/bitmap-text.md +232 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-text/references/html-text.md +192 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-text/references/split-bitmap-text.md +187 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-text/references/split-text.md +168 -0
- package/vendor/pixijs-skills/skills/pixijs-scene-text/references/text.md +311 -0
- package/vendor/pixijs-skills/skills/pixijs-ticker/SKILL.md +292 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# Render Loop
|
|
2
|
+
|
|
3
|
+
Every PixiJS frame runs a fixed sequence of ticker callbacks in priority order, with `app.render()` registered at `UPDATE_PRIORITY.LOW` — scene graph update and GPU draw happen _inside_ that one callback. The `Application`'s `TickerPlugin` drives this loop automatically. Understanding the priority order and when to render yourself is key for integrating game logic, physics, and custom frame pacing.
|
|
4
|
+
|
|
5
|
+
## Frame lifecycle
|
|
6
|
+
|
|
7
|
+
Each frame, the `Ticker` measures elapsed time, clamps it with `minFPS`/`maxFPS`, then calls every listener registered with `ticker.add()` in priority order. `app.render()` is itself one of those listeners, registered at `UPDATE_PRIORITY.LOW`. When it runs, it walks the display list from `app.stage`, recalculates world transforms (position/rotation/scale propagated parent-to-child), fires each object's `onRender` hook, culls off-screen objects if culling is enabled, then batches draw calls and issues GPU commands.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
requestAnimationFrame
|
|
11
|
+
│
|
|
12
|
+
[Ticker._tick()]
|
|
13
|
+
│
|
|
14
|
+
├─ Compute elapsed time (minFPS/maxFPS clamp)
|
|
15
|
+
└─ Call listeners in priority order
|
|
16
|
+
├─ INTERACTION / HIGH / NORMAL listeners
|
|
17
|
+
├─ LOW: app.render()
|
|
18
|
+
│ ├─ Traverse display list
|
|
19
|
+
│ ├─ Update world transforms
|
|
20
|
+
│ │ └─ object.onRender() (per-object during traversal)
|
|
21
|
+
│ ├─ Cull display objects (if enabled)
|
|
22
|
+
│ ├─ Upload data to GPU
|
|
23
|
+
│ └─ Draw
|
|
24
|
+
└─ UTILITY listeners (post-render)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Rendering is **retained mode**: objects persist across frames unless you explicitly remove them.
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
app.ticker.add((ticker) => {
|
|
33
|
+
sprite.rotation += 0.01 * ticker.deltaTime;
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
app.ticker.add(
|
|
37
|
+
(ticker) => {
|
|
38
|
+
updatePhysics(ticker.deltaMS);
|
|
39
|
+
},
|
|
40
|
+
undefined,
|
|
41
|
+
UPDATE_PRIORITY.HIGH,
|
|
42
|
+
);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Callbacks receive a `Ticker` instance. Use `ticker.deltaTime` (dimensionless, ~1.0 at 60fps) for simple multipliers; use `ticker.deltaMS` (milliseconds) for time-based calculations.
|
|
46
|
+
|
|
47
|
+
## Core Patterns
|
|
48
|
+
|
|
49
|
+
### Priority order
|
|
50
|
+
|
|
51
|
+
The ticker runs registered callbacks in descending priority. The `TickerPlugin` registers `app.render()` at `UPDATE_PRIORITY.LOW`, so callbacks at `NORMAL`, `HIGH`, or `INTERACTION` run before the render.
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
UPDATE_PRIORITY.INTERACTION = 50 // pointer events
|
|
55
|
+
UPDATE_PRIORITY.HIGH = 25 // physics, input sampling
|
|
56
|
+
UPDATE_PRIORITY.NORMAL = 0 // gameplay (default)
|
|
57
|
+
UPDATE_PRIORITY.LOW = -25 // app.render() registered here
|
|
58
|
+
UPDATE_PRIORITY.UTILITY = -50 // post-render cleanup
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import { UPDATE_PRIORITY } from "pixi.js";
|
|
63
|
+
|
|
64
|
+
app.ticker.add(
|
|
65
|
+
(ticker) => {
|
|
66
|
+
handleInput(ticker.deltaMS);
|
|
67
|
+
},
|
|
68
|
+
undefined,
|
|
69
|
+
UPDATE_PRIORITY.HIGH,
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
app.ticker.add((ticker) => {
|
|
73
|
+
updateAnimations(ticker.deltaTime);
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Time units
|
|
78
|
+
|
|
79
|
+
| Property | Type | Scaled by speed? | Capped by minFPS? |
|
|
80
|
+
| ----------- | ----------------------------- | ---------------- | ----------------- |
|
|
81
|
+
| `deltaTime` | dimensionless (~1.0 at 60fps) | yes | yes |
|
|
82
|
+
| `deltaMS` | milliseconds | yes | yes |
|
|
83
|
+
| `elapsedMS` | milliseconds | no | no |
|
|
84
|
+
|
|
85
|
+
Use `deltaTime` as a frame-rate multiplier for simple per-frame logic; use `deltaMS` for pixels-per-second or other time-based math; use `elapsedMS` only for profiling (raw, uncapped, unscaled).
|
|
86
|
+
|
|
87
|
+
### Manual rendering
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
await app.init({ autoStart: false, width: 800, height: 600 });
|
|
91
|
+
|
|
92
|
+
function frame(time: number) {
|
|
93
|
+
updateGameState();
|
|
94
|
+
app.renderer.render(app.stage);
|
|
95
|
+
requestAnimationFrame(frame);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
requestAnimationFrame(frame);
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`autoStart: false` disables the `TickerPlugin`'s automatic render registration. You control when the scene draws, letting you integrate with a custom loop, an external animation library, or a fixed-timestep game clock.
|
|
102
|
+
|
|
103
|
+
### Stop and start
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
app.stop(); // pause the ticker and rendering
|
|
107
|
+
app.start(); // resume
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Useful for a pause menu or when the user switches away from the tab. The ticker is automatically paused on page blur when `sharedTicker: false` (default).
|
|
111
|
+
|
|
112
|
+
### Per-object update via `onRender`
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
const sprite = new Sprite(texture);
|
|
116
|
+
sprite.onRender = () => {
|
|
117
|
+
sprite.rotation += 0.01;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
app.stage.addChild(sprite);
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
`onRender` is called during scene graph traversal, just before the object is drawn. It's a per-object hook; an alternative to a global ticker callback when the logic is tied to a specific display object.
|
|
124
|
+
|
|
125
|
+
### Frame rate capping
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
app.ticker.maxFPS = 30; // run at 30fps
|
|
129
|
+
app.ticker.minFPS = 10; // cap deltaTime at 10fps worth if frames drop
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
`maxFPS` enforces a ceiling by skipping updates. `minFPS` caps `deltaTime` so large frame drops don't produce enormous deltas that break physics. Defaults: no `maxFPS`, `minFPS: 10`.
|
|
133
|
+
|
|
134
|
+
## Common Mistakes
|
|
135
|
+
|
|
136
|
+
### [CRITICAL] Treating the ticker callback arg as a number
|
|
137
|
+
|
|
138
|
+
Wrong:
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
app.ticker.add((dt) => {
|
|
142
|
+
sprite.rotation += dt; // dt is the Ticker instance, not a number
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Correct:
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
app.ticker.add((ticker) => {
|
|
150
|
+
sprite.rotation += ticker.deltaTime;
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
v8 passes the `Ticker` instance to the callback, not a delta. Old v7 code that used `(dt) => sprite.x += dt` compiles but produces `NaN` because `dt` is an object.
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
### [HIGH] Using `updateTransform` for per-frame logic
|
|
158
|
+
|
|
159
|
+
Wrong:
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
class MySprite extends Sprite {
|
|
163
|
+
updateTransform() {
|
|
164
|
+
super.updateTransform();
|
|
165
|
+
this.rotation += 0.01;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Correct:
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
class MySprite extends Sprite {
|
|
174
|
+
constructor() {
|
|
175
|
+
super();
|
|
176
|
+
this.onRender = () => {
|
|
177
|
+
this.rotation += 0.01;
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
`updateTransform` was removed in v8. Use `onRender` for per-object per-frame logic.
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
### [MEDIUM] Assuming ticker callbacks run after render
|
|
187
|
+
|
|
188
|
+
Wrong:
|
|
189
|
+
|
|
190
|
+
```ts
|
|
191
|
+
app.ticker.add(() => {
|
|
192
|
+
readPixelsFromCanvas(); // empty; render hasn't happened yet this frame
|
|
193
|
+
});
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Correct:
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
app.ticker.add(
|
|
200
|
+
() => {
|
|
201
|
+
readPixelsFromCanvas();
|
|
202
|
+
},
|
|
203
|
+
undefined,
|
|
204
|
+
UPDATE_PRIORITY.UTILITY,
|
|
205
|
+
);
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Callbacks added at the default priority (`NORMAL = 0`) run _before_ the render call (at `LOW = -25`). Use `UTILITY = -50` for post-render work like pixel readbacks or DOM sync.
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
## API Reference
|
|
212
|
+
|
|
213
|
+
- [Ticker](https://pixijs.download/release/docs/ticker.Ticker.html.md)
|
|
214
|
+
- [TickerPlugin](https://pixijs.download/release/docs/app.TickerPlugin.html.md)
|
|
215
|
+
- [UPDATE_PRIORITY](https://pixijs.download/release/docs/ticker.UPDATE_PRIORITY.html.md)
|
|
216
|
+
- [Application](https://pixijs.download/release/docs/app.Application.html.md)
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
# Renderers: WebGPU, WebGL, and Canvas
|
|
2
|
+
|
|
3
|
+
PixiJS v8 ships three renderers: `WebGPURenderer` (fastest where available), `WebGLRenderer` (broad compatibility, WebGL2), and `CanvasRenderer` (a last-resort 2D Canvas backend). `autoDetectRenderer` (used internally by `Application.init`) picks the best available backend based on a preference list.
|
|
4
|
+
|
|
5
|
+
**Status:** `WebGLRenderer` is recommended for production. `WebGPURenderer` is feature-complete but still experimental; browser implementations have inconsistencies. `CanvasRenderer` is a fallback for environments without WebGL/WebGPU and supports a reduced feature set.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
const app = new Application();
|
|
11
|
+
|
|
12
|
+
await app.init({
|
|
13
|
+
preference: ["webgpu", "webgl"],
|
|
14
|
+
width: 800,
|
|
15
|
+
height: 600,
|
|
16
|
+
background: 0x222233,
|
|
17
|
+
antialias: true,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
document.body.appendChild(app.canvas);
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
`preference` can be a single string (try that first, fall back to default order) or an array (use only these, in this order; others are excluded). Default priority when `preference` is not set: `webgl`, `webgpu`, `canvas`.
|
|
24
|
+
|
|
25
|
+
## Core Patterns
|
|
26
|
+
|
|
27
|
+
### Preference forms
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
// Single string: try webgpu first, fall back through defaults
|
|
31
|
+
await app.init({ preference: "webgpu" });
|
|
32
|
+
|
|
33
|
+
// Array: only try listed backends in order
|
|
34
|
+
await app.init({ preference: ["webgpu", "webgl"] });
|
|
35
|
+
|
|
36
|
+
// Array acts as a blocklist; anything not listed is excluded
|
|
37
|
+
await app.init({ preference: ["webgl"] }); // never uses webgpu or canvas
|
|
38
|
+
|
|
39
|
+
// Force canvas (legacy-only environments)
|
|
40
|
+
await app.init({ preference: ["canvas"] });
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
A string form falls through to defaults if the preferred backend isn't available. An array form excludes any backend not in the list, even if the preferred one fails.
|
|
44
|
+
|
|
45
|
+
### Per-renderer options
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
await app.init({
|
|
49
|
+
width: 800,
|
|
50
|
+
height: 600,
|
|
51
|
+
webgpu: { antialias: true, powerPreference: "high-performance" },
|
|
52
|
+
webgl: { antialias: true, premultipliedAlpha: false },
|
|
53
|
+
canvasOptions: { backgroundAlpha: 0 },
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Common options live at the top level; renderer-specific options go in `webgpu`, `webgl`, or `canvasOptions`. Only the options for the selected renderer apply; the others are discarded.
|
|
58
|
+
|
|
59
|
+
### Systems and pipes
|
|
60
|
+
|
|
61
|
+
Each renderer is composed of a fixed set of `System`s (lifecycle services: textures, buffers, state, events, filters, masks) and a set of `RenderPipe`s (per-renderable instruction builders: sprite, graphics, mesh, particle, text, tiling-sprite).
|
|
62
|
+
|
|
63
|
+
- `Systems` run once per renderer lifecycle and manage GPU state.
|
|
64
|
+
- `RenderPipes` run every frame, one per renderable type. They batch instructions for their object class and flush them to the GPU.
|
|
65
|
+
|
|
66
|
+
Writing a custom renderable means implementing a `RenderPipe`, a `BatchableX` class, and registering both via the extensions system. See `pixijs-custom-rendering`.
|
|
67
|
+
|
|
68
|
+
### Lazy-loading backend-specific systems and pipes
|
|
69
|
+
|
|
70
|
+
Systems and pipes that only one backend needs can stay out of the main bundle. Register a renderer loader (`ExtensionType.WebGLLoader`, `ExtensionType.WebGPULoader`, or `ExtensionType.CanvasLoader`) whose `load()` dynamic-imports the module that registers them. During `init`, the renderer awaits every loader for its own backend after the environment extensions load and before it creates its systems and pipes; loaders for other backends never run.
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
import { extensions, ExtensionType } from "pixi.js";
|
|
74
|
+
|
|
75
|
+
extensions.add({
|
|
76
|
+
extension: { type: ExtensionType.WebGLLoader, name: "my-plugin" },
|
|
77
|
+
load: () => import("./gl/register"), // registers WebGL systems and pipes on import
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Loader names are unique per backend; a second loader with the same name is ignored. Loaders run concurrently; registered systems and pipes are ordered by their own `priority`, not by loader completion. `skipExtensionImports: true` skips loaders too, so custom builds import backend modules directly.
|
|
82
|
+
|
|
83
|
+
### Direct renderer construction
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
import { WebGLRenderer } from "pixi.js";
|
|
87
|
+
|
|
88
|
+
const renderer = new WebGLRenderer();
|
|
89
|
+
await renderer.init({ width: 800, height: 600 });
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Most apps use `Application.init` or `autoDetectRenderer()`, but you can instantiate a specific renderer directly when the target environment is known (tests, tooling, editor integrations).
|
|
93
|
+
|
|
94
|
+
### `renderer.render()` options
|
|
95
|
+
|
|
96
|
+
The `.render()` method accepts either a `Container` or an options object:
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
// shorthand: just render the stage
|
|
100
|
+
renderer.render(app.stage);
|
|
101
|
+
|
|
102
|
+
// options form: control clearing, transform, or a render target
|
|
103
|
+
renderer.render({
|
|
104
|
+
container: app.stage,
|
|
105
|
+
clear: true,
|
|
106
|
+
transform: new Matrix(),
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// render into a mip level, array layer, cube face or 3D slice of a texture
|
|
110
|
+
renderer.render({
|
|
111
|
+
container: myContainer,
|
|
112
|
+
target: renderTexture,
|
|
113
|
+
mipLevel: 1,
|
|
114
|
+
layer: 0,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// store the capture in screen orientation (for 3D UVs)
|
|
118
|
+
renderer.render({ container: scene3d, target: renderTexture, flipY: true });
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
`container` is the scene root to draw. `target` is a separate destination (e.g. a `RenderTexture`). `mipLevel > 0` is useful for custom LOD systems or manual mipmap generation. `flipY` defaults to `false`; set it to store a texture render un-flipped, with winding adjusted so back-face culling still works. `layer` selects an array layer, a cube face, or a depth slice of a 3D `TextureSource` (`depth`); pass the source itself as `target`.
|
|
122
|
+
|
|
123
|
+
### Render targets
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
import { CLEAR, RenderTarget, Texture, TextureSource } from "pixi.js";
|
|
127
|
+
|
|
128
|
+
const depthSource = new TextureSource({ width: 512, height: 512, format: "depth24plus-stencil8" });
|
|
129
|
+
|
|
130
|
+
const target = new RenderTarget({
|
|
131
|
+
colorAttachments: [{ texture: new TextureSource({ width: 512, height: 512 }), loadOp: "clear" }],
|
|
132
|
+
depthStencilAttachment: { texture: depthSource, depthLoadOp: "clear" },
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
renderer.render({ container, target });
|
|
136
|
+
|
|
137
|
+
// bind directly from custom render code; always use the options object
|
|
138
|
+
renderer.renderTarget.push({ target, clear: CLEAR.COLOR, mipLevel: 0 });
|
|
139
|
+
renderer.renderTarget.pop();
|
|
140
|
+
|
|
141
|
+
const saved = renderer.renderTarget.getBindState();
|
|
142
|
+
renderer.renderTarget.bind(saved); // replays without clearing
|
|
143
|
+
|
|
144
|
+
// copy the depth attachment into another depth-format texture (WebGL2 and WebGPU)
|
|
145
|
+
const depthCopy = new Texture({
|
|
146
|
+
source: new TextureSource({ width: 512, height: 512, format: "depth24plus-stencil8" }),
|
|
147
|
+
});
|
|
148
|
+
renderer.renderTarget.copyDepthTexture(target, depthCopy, { x: 0, y: 0 }, { width: 512, height: 512 });
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
- `RenderTarget` takes WebGPU-style `colorAttachments`/`depthStencilAttachment` or the older `colorTextures`/`depth`/`stencil`/`depthStencilTexture` options. `colorTextures: 0` with `depth: true` makes a depth-only target.
|
|
152
|
+
- Positional `bind(target, clear, ...)` and `push(...)` are deprecated since 8.20.0. `pop()` throws when the stack is empty.
|
|
153
|
+
- `copyDepthTexture` needs WebGL2 or WebGPU and a depth-format destination. The next render into the destination target must clear color only (`clear: CLEAR.COLOR`), or the copied depth is lost.
|
|
154
|
+
- Destroy a target you constructed with `target.destroy()`; the renderer releases the GPU objects it built for it.
|
|
155
|
+
|
|
156
|
+
### Resizing, texture generation, and interop
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
renderer.resize(window.innerWidth, window.innerHeight);
|
|
160
|
+
|
|
161
|
+
const texture = renderer.generateTexture(displayObject);
|
|
162
|
+
|
|
163
|
+
// Mixing PixiJS with Three.js (or any other WebGL/WebGPU library)
|
|
164
|
+
threeRenderer.resetState();
|
|
165
|
+
threeRenderer.render(scene, camera);
|
|
166
|
+
|
|
167
|
+
pixiRenderer.resetState();
|
|
168
|
+
pixiRenderer.render({ container: stage });
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Call `resetState()` before each library renders. Both libraries leave GPU state (bound textures, blend modes, active shaders) that conflicts with the other; without `resetState()`, objects can disappear or blend incorrectly.
|
|
172
|
+
|
|
173
|
+
### Destroying a renderer
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
renderer.destroy();
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Releases GPU resources, systems, pipes, and event listeners. A destroyed renderer cannot be used for further rendering.
|
|
180
|
+
|
|
181
|
+
### Manual rendering
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
await app.init({ autoStart: false, width: 800, height: 600 });
|
|
185
|
+
|
|
186
|
+
function frame() {
|
|
187
|
+
app.renderer.render(app.stage);
|
|
188
|
+
requestAnimationFrame(frame);
|
|
189
|
+
}
|
|
190
|
+
requestAnimationFrame(frame);
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Disable the automatic ticker plugin with `autoStart: false`, then call `app.renderer.render(app.stage)` yourself. Useful for integrating with an external game loop.
|
|
194
|
+
|
|
195
|
+
### Renderer selection at runtime
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
console.log(app.renderer.name); // 'webgl', 'webgpu', or 'canvas'
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
After `init`, `app.renderer` is the concrete class. Use `app.renderer.name` (a string) to branch on backend; `app.renderer.type` exists but is a numeric id meant for internal dispatch — prefer `name` in user code.
|
|
202
|
+
|
|
203
|
+
### Supports check
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
if (await isWebGPUSupported()) {
|
|
207
|
+
// ok to prefer webgpu
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (isWebGLSupported()) {
|
|
211
|
+
// ok to prefer webgl
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// after init, WebGPU-only capability flags
|
|
215
|
+
if (renderer.name === "webgpu") {
|
|
216
|
+
renderer.device.extensions.transientAttachment; // GPUTextureUsage.TRANSIENT_ATTACHMENT available
|
|
217
|
+
renderer.limits.supportsOverrideConstants; // pipeline constants vs. source-baked overrides
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Both helpers are exported from `pixi.js`. Useful if you want to tell the user which backend is about to be used before calling `app.init`.
|
|
222
|
+
|
|
223
|
+
### Context and device loss
|
|
224
|
+
|
|
225
|
+
```ts
|
|
226
|
+
// both renderers recover on their own; only render bundles need re-recording
|
|
227
|
+
if (!renderer.encoder.isBundleValid(bundle)) {
|
|
228
|
+
bundle = record();
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
The WebGL renderer restores itself after `webglcontextrestored`. The WebGPU renderer requests a new device when the browser reports `GPUDevice.lost` and rebuilds its GPU resources on the next render. A device you pass through the WebGPU `gpu` option is neither restored nor destroyed by PixiJS. A render bundle recorded on a lost device fails `isBundleValid` and must be re-recorded.
|
|
233
|
+
|
|
234
|
+
## Common Mistakes
|
|
235
|
+
|
|
236
|
+
### [HIGH] Expecting WebGPU everywhere
|
|
237
|
+
|
|
238
|
+
Wrong:
|
|
239
|
+
|
|
240
|
+
```ts
|
|
241
|
+
await app.init({ preference: ["webgpu"] });
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Correct:
|
|
245
|
+
|
|
246
|
+
```ts
|
|
247
|
+
await app.init({ preference: ["webgpu", "webgl"] });
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
WebGPU is not yet available on all browsers. An array-form preference of only `['webgpu']` will fail init on unsupported browsers (no fallback). Always include `'webgl'` as a fallback unless you've verified WebGPU support upstream.
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
### [MEDIUM] Assuming CanvasRenderer supports everything
|
|
254
|
+
|
|
255
|
+
CanvasRenderer does not support filters, masks beyond basic clipping, compressed textures, or custom shaders. It's intended as a last-resort for environments that can't run WebGL. If you need full feature parity, target WebGL or WebGPU.
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
### [MEDIUM] Calling render before init
|
|
259
|
+
|
|
260
|
+
Wrong:
|
|
261
|
+
|
|
262
|
+
```ts
|
|
263
|
+
const app = new Application();
|
|
264
|
+
app.renderer.render(app.stage);
|
|
265
|
+
await app.init();
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Correct:
|
|
269
|
+
|
|
270
|
+
```ts
|
|
271
|
+
const app = new Application();
|
|
272
|
+
await app.init();
|
|
273
|
+
app.renderer.render(app.stage);
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
`app.renderer` is populated only after `init()` resolves. Any access before that is `undefined`.
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
## API Reference
|
|
280
|
+
|
|
281
|
+
- [autoDetectRenderer](https://pixijs.download/release/docs/rendering.autoDetectRenderer.html.md)
|
|
282
|
+
- [AbstractRenderer](https://pixijs.download/release/docs/rendering.AbstractRenderer.html.md)
|
|
283
|
+
- [WebGLRenderer](https://pixijs.download/release/docs/rendering.WebGLRenderer.html.md)
|
|
284
|
+
- [WebGPURenderer](https://pixijs.download/release/docs/rendering.WebGPURenderer.html.md)
|
|
285
|
+
- [CanvasRenderer](https://pixijs.download/release/docs/rendering.CanvasRenderer.html.md)
|
|
286
|
+
- [RenderTarget](https://pixijs.download/release/docs/rendering.RenderTarget.html.md)
|
|
287
|
+
- [RenderTargetSystem](https://pixijs.download/release/docs/rendering.RenderTargetSystem.html.md)
|