[for reference] feat: TypeGPU core shaders - #46
Open
iwoplaza wants to merge 5 commits into
Open
Conversation
Move the analytic Slug fill out of TSL into `slug-shaders/core`, whose modules import TypeGPU only. The q-form solver, root-eligibility table, per-curve coverage and weight, band header and reference bit layout, fragment scale, thickening, weighted blend, and vertex dilation are now expressed once and are callable from vanilla WebGPU, vanilla WebGL, TypeGPU, or Three.js. Both axes reach one curve evaluator and one quadratic solver, because a vertical band is the transposed horizontal band with the opposite winding sense. The modules beside the core stay the Three.js host and keep the band loop, its sorted-reference terminator, the 2D grid addressing, and every texture read: `@typegpu/three` has no texture bridge, and grid addressing exists only because these resources are textures. Every crossing goes through `coreValue`, which assigns the result to a named TSL property. That is load-bearing rather than cosmetic. The bridge resolves a core call by traversing the TSL nodes it reads, and TypeGPU's resolution context is a single stack, so a core node reachable through another core call's arguments resolves re-entrantly and fails a resolution-stack assertion. `.toVar()` is not sufficient, because a variable node's traversal still descends into its initializer. Two correctness fixes come along: the horizontal solve's `b` coefficient is `p0.y - p1.y`, matching `reference.ts` and the vertical solver, and the core clamps to the unit interval instead of calling `std.saturate`, which WGSL defines and GLSL does not, so the same functions now link on WebGL2. Add a device-free test that compiles the staged Slug material through both Three.js node builders and holds one declaration per core function, one statement per boundary, no boundary variable shadowing a core function, and no WGSL-only builtin in the GLSL output. Weakening `coreValue` makes it fail with the same assertion the browser reports. Exclude emitted declarations from the shader build plugin, which its default include would otherwise select and then fail to parse as non-ambient TypeScript. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`typegpu`, `@typegpu/three`, and `@typegpu/gl` are peers for the same reason Three.js and React are: each keys its identity to a single instance, so a duplicate copy breaks interop rather than merely wasting bytes. `typegpu` warns on a duplicate version and derives every internal symbol from its version string, and `@typegpu/three` already declares `three`, `typegpu`, and `@typegpu/gl` as its own peers. They are optional because only the Slug subpath needs them, exactly as `react` and `@react-three/fiber` are optional for the React subpath, so a Bitmap-only or MTSDF-only consumer installs nothing extra. The declared ranges mirror the upstream contract while the exact pkg.pr.new builds stay in devDependencies, which is how the `three` peer is already handled. The package-size boundary follows the dependency boundary: peer runtimes are outside the reviewed ceilings because the consumer installs and dedupes them. This moves the Slug graph from 944,637 to 445,687 raw bytes and from 160,911 to 89,110 gzip, leaving only this package's own emitted shader code inside the measurement. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Regenerate the report, which the tsdown/Rolldown emit commit left stale. Two causes are separated in the recorded numbers. Slug's own shipped shader code grows because the build plugin emits a transpiled syntax tree per shader function for runtime resolution: roughly 45,000 raw and 41,000 minified bytes. That metadata compresses well, so Slug's reviewed gzip and Brotli ceilings are unchanged and still shared with the other two rasters, and only its uncompressed ceilings rise. Its retained-capacity baseline is rebased rather than given a five-fold allowance, which would have stopped the assertion bounding anything. Everything else is drift from the emit migration, between 85 and 211 bytes across `browser-core`, both shared-graph rasters, and the baker worker; those graphs' own code did not change. One Wasm brotli growth allowance was already exceeded against the committed report before any of this work and is corrected to the recorded figure. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Add the host-agnostic core and its TypeGPU-to-TSL boundary as cited sources, describe what is portable and what stays with the Three.js host, state the single-resolution-stack invariant the boundary enforces, and record the peer-dependency reasoning and the size consequence. Refresh both package digests, which the preceding commit left stale. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes:
unplugin-typegpu, I adoptedtsdown. However, if preferred, babel can be used on the files produced by the TypeScript compiler.