Shaders draw in the sprite's own pass: a Mesh with the graph's fragment, no filter (#77)
game-maker / suite (push) Successful in 8m24s
game-maker / suite (push) Successful in 8m24s
A sprite's picture is now a Mesh (unit quad, sibling of its Graphics node, which keeps only the hit area); a worn shader replaces Pixi's fragment in that draw, so there is no intermediate texture and no extra render pass. Measured on the HD 630: 400 shaded sprites hold 60 fps (was 34), 800 hold 56 (was 20). Two Pixi facts the code leans on: a mesh's texture is bound only for Pixi's own shader, so GraphShader.wear hands it over; and MeshPipe caches whether a mesh batches and re-checks it only in a frame without structure changes, so switching a shader on or off calls mesh.unload(). The console panel mirrors console.group/groupCollapsed/groupEnd and fills the %s %d %o %c directives, so Pixi's deprecation warning shows its head, not only its stack. E2E 12 guards against the addChild-on-Graphics warning, 28 counts shaders instead of filters. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
82effb2c03
commit
0e5e5ef925
15 files changed
+328
-88
No files matched your search
+15
-2
@@ -1,4 +1,4 @@
|
||||
import { type Application, Color, type ColorSource, type Container, Rectangle, Text } from 'pixi.js';
|
||||
import { type Application, Color, type ColorSource, type Container, Mesh, Rectangle, Text } from 'pixi.js';
|
||||
import { resolveObjects } from '../core/model/instance';
|
||||
import { findObjectHolder } from '../core/model/Project';
|
||||
import type { FrameRect } from '../core/model/texture';
|
||||
@@ -171,6 +171,8 @@ export function installDebugHook(app: Application, state: EditorState, editor: E
|
||||
};
|
||||
(window as unknown as { __gm: unknown }).__gm = {
|
||||
state,
|
||||
/** The Pixi application, for probes that need the renderer or the stage. */
|
||||
app,
|
||||
sceneObjects: () => (state.activeScene ? objectsOf(state.activeScene.id) : []),
|
||||
locate,
|
||||
locateAll,
|
||||
@@ -386,7 +388,7 @@ export function installDebugHook(app: Application, state: EditorState, editor: E
|
||||
};
|
||||
},
|
||||
fps: () => editor.fps,
|
||||
/** Visible nodes carrying a filter – one extra render pass each, which is what shader cost is made of. */
|
||||
/** Visible nodes carrying a filter – one extra render pass each; since #77 a shader is none. */
|
||||
filterCount: () => {
|
||||
let n = 0;
|
||||
const walk = (node: Container): void => {
|
||||
@@ -397,6 +399,17 @@ export function installDebugHook(app: Application, state: EditorState, editor: E
|
||||
walk(app.stage);
|
||||
return n;
|
||||
},
|
||||
/** Visible sprite meshes drawing with a shader of their own – one draw call each, no pass (#77). */
|
||||
shaderCount: () => {
|
||||
let n = 0;
|
||||
const walk = (node: Container): void => {
|
||||
if (!node.visible) return;
|
||||
if (node instanceof Mesh && node.shader) n += 1;
|
||||
for (const child of node.children) walk(child);
|
||||
};
|
||||
walk(app.stage);
|
||||
return n;
|
||||
},
|
||||
lowLatency: () =>
|
||||
(app.renderer as unknown as { gl?: WebGL2RenderingContext }).gl?.getContextAttributes()
|
||||
?.desynchronized === true,
|
||||
|
||||
Reference in new issue
Block a user