Shader graph: UV, Sample texture, Texture size, Time, Sin/Floor/Fract/Step; edge mode on Output (#78)
game-maker / suite (push) Successful in 8m38s

Fragment-side coordinate nodes instead of vertex nodes: the quad stays the
quad, a UV read plus a sample at a computed coordinate covers flip, scroll,
wave, pixelate and scanlines. Time is a uniform only when a Time node reaches
the Output; a viewport that drew a Time shader redraws from the ticker so the
Scene tab animates without a running world. Edge (Mirror/Repeat/Clamp) is a
second texture variant in TextureLibrary because WebGL binds no TextureStyle
resource of the shader. The compiler now emits #version 300 es first: Pixi
only compiles as ES 3.00 when the fragment says so, and textureSize needs it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
rootandClaude Fable 5.1 committed 2026-09-13 16:18:22 +02:00
1 parent 0e5e5ef925
commit f85606427b
12 files changed
+586 -38

No files matched your search

+13
View File
@@ -9,6 +9,18 @@ import type { ShaderSource } from './shaders';
*/
export class ShaderLibrary {
private readonly builds = new Map<string, { fingerprint: string; build: ShaderBuild }>();
private readonly started = performance.now();
/** Set from the test hook: the clock stands at this second until released. */
private frozenAt: number | null = null;
/** Seconds since the library came up – what a Time node reads. */
now(): number {
return this.frozenAt ?? (performance.now() - this.started) / 1000;
}
freezeTime(at: number | null): void {
this.frozenAt = at;
}
buildFor(asset: ShaderAsset): ShaderBuild {
const fingerprint = JSON.stringify(asset.graph);
@@ -23,6 +35,7 @@ export class ShaderLibrary {
source(project: Project): ShaderSource {
const seen = new Map<string, ShaderBuild | null>();
return {
now: this.now(),
compiled: (assetId) => {
let build = seen.get(assetId);
if (build === undefined) {