Repository navigation
chore: version packages - #220
Open
github-actions[bot] wants to merge 1 commit into
Open
github-actions[bot] wants to merge 1 commit into
github-actions[bot] wants to merge 1 commit into
Conversation
github-actions
Bot
force-pushed
the
changeset-release/main
branch
21 times, most recently
from
October 10, 2026 14:57
9de5305 to
ce344e6
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
4 times, most recently
from
October 15, 2026 00:30
55e1a0d to
9a25b19
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
3 times, most recently
from
October 27, 2026 12:58
3c9b8ed to
46667fe
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
2 times, most recently
from
October 29, 2026 13:06
bebf99d to
efcec22
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
5 times, most recently
from
November 1, 2026 11:30
88e1863 to
47f7a05
Compare
github-actions
Bot
force-pushed
the
changeset-release/main
branch
from
November 1, 2026 12:49
47f7a05 to
3329fd4
Compare
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.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
Releases
@camp-dev/shaders@0.23.0
Minor Changes
28b02c2:
Auroradraws its field into a texture once per frame, and each march step reads the texture instead of working out five noise octaves, 60 times for every pixel. The texture stores the field before the shaping that makes the thin filaments, so the texture filter blends a smooth value and the filaments stay sharp. Pixel values shift slightly, but the curtains look the same. At 3272 by 1392 device pixels on an M1 Max, Aurora's GPU time per frame drops from about 14.4 ms to about 5.0 ms. Where the renderer cannot draw into a half-float target, on WebGL2 withoutEXT_color_buffer_float, Aurora works out the field at every step as before.ShaderContextValuegainsregisterPrePass, which adds a draw that runs before the scene's meshes on every frame, including the redraw after a resize. A hand-built context, such as a fake one in a test, needsregisterPrePasstoo, and() => () => undefinedregisters nothing.ShaderMonitor's GPU time counts these draws along with the scene pass and the output quad.TexturePassOptionsgainsformat:RGBAFormat, the default, for four channels, orRedFormatfor one.fee293c: Add
createTexturePassand itsTexturePassandTexturePassOptionstypes. A texture pass draws a TSL node into a render target of its own, and exposes the texture,render,resize, anddispose. It exposes no texture when the renderer cannot render to or bind the requested texel type: on WebGL2 withoutEXT_color_buffer_float, or for a full float on a WebGPU device withoutfloat32-filterable. After a lost device, it goes inert.Auroradraws its 60 slice colors into a texture once per material build, instead of running its color ramp 60 times for every pixel. It also works out its per-pixel constants before its march loop. It looks the same as before. At 3272 by 1392 device pixels on an M1 Max, Aurora's GPU time per frame drops from about 18.4 ms to about 14.4 ms.5862f45: Add
FlutedGlass, an Effect that shows the image beneath it through repeating flutes of glass. Mount it after a Source inside aShaderScene. Each flute bends the image under it into a squeezed copy, catches a highlight along the wall that faces the light, and darkens near its grooves where the glass turns steep. Its props:fluteWidthsets each flute's width in CSS pixels.anglesets the direction the flutes run, in the degreesLinearGradientuses, so the default of 90 gives vertical flutes.refractionsets how far the glass bends the image, andrefraction={0}leaves it unchanged.dispersionsplits the image's colors where the glass bends, as a share of the bend. Blue bends further than red, as in real glass, so colors fringe near the grooves and the flute centers stay clean.dispersion={0}turns the split off.crossSectionsets each flute's shape, from a pointed'prism'through a'round'lens to a'flat'top with steep walls, or any number from 0 to 1 between them.lightAnglesets where the light comes from, in degrees that turn the same way asangle: 0 from the right and 90 from above. It defaults to 135, the upper left. The light stays put whileangleturns the glass.highlightandshadowset how strong the highlight and the shadow are, from 0 to 1.highlightColortints the highlight.Every prop except
highlightColortakes a static value or an animation signal. Near the canvas edge, the glass mirrors the image back onto the canvas.FlutedGlassbends only what Sources drew, never the output of an Effect such asGrain, so mount such Effects after it. It works in Mode 1 only.Add the
fluteSurfaceprimitive for Mode 2. For a position, it returns the bend to add before you sample your own texture, the slope and steepness of the glass, and how far the position sits from its flute's center.ec69ebe: Add
LiquidGradient, a Source that streaks bands of color along slow, curling currents, like paint stirred into liquid. Mount it inside aShaderScene.stops,colorSpace, andhueInterpolationpick the colors, as they do onLinearGradient.angleandrepeatlay the bands out before the current moves them, andsoftnesssets how the colors meet, from hard bands at 0 to full blends at 1.swirlsets how far the current carries the colors,scalesets roughly how many eddies span the canvas's height, andspeedsets how fast the current drifts. Each of those six props takes a static value or an animation signal.seedpicks a different layout with the same look. A literalspeed={0}holds the current still and lets the scene park. It works in Mode 1 only.LiquidGradientdraws the current, a noise field, and its palette into textures before the scene pass, and redraws each texture only when a prop it depends on changes. Where the renderer cannot draw into a half-float target, on WebGL2 withoutEXT_color_buffer_float, every read works its value out from the noise or the palette instead. The result looks the same and costs more GPU time.b899dd9: An Effect can now take more than one sample of the image beneath it.
useResampleregisters a resample, a function that receives the sampler for everything mounted beneath the Effect and returns the sampler that replaces it. The new sampler can call the one beneath as often as it needs, such as three times for a color split. TheResampleandSamplertypes describe the two functions.useBasePassUvkeeps its signature and registers the resample that samples beneath once, at the warped coordinate.Dither,LedWall,CursorRipple, andCursorSmudgedraw the same as before unless two of them stack.When two UV warps stack, the last-mounted one is now the top layer, the way every other Effect stacks. Before, the first-mounted UV warp moved the screen coordinate first, so
<Dither /><CursorRipple />pixelated the water along with the image beneath it. Now Dither pixelates the image, and the water bends the pixelated result.Effects now keep their place in the stack. An Effect that registers again, because a value in its
depschanged, goes back where it was instead of moving to the top.CursorRipplenow stacks where it is mounted. Its UV warp and its shine used to register one render late, after every Effect beside it, so<CursorRipple /><Grain />added the shine over the grain. Now Grain runs over the shine.ShaderContextValueandOutputStagereplaceregisterBaseUvTransformwithregisterResample. If you callregisterBaseUvTransformyourself, register(sampleBeneath) => (coordinate) => sampleBeneath(warp(coordinate))withregisterResampleinstead.registerResampleandregisterOverlaytake an optionalSlotas their second argument. A registration under a slot that registered before goes back to that slot's place.useResampleandusePostProcessPasspass one for you.618e2ad:
<ShaderScene>takes amaxFPSprop, which sets the scene's frame cap, the most frames per second it draws. With no frame cap, a scene draws at the display's refresh rate, as before.maxFPS={60}draws every other frame of a 120 Hz display. A new value applies from the next frame without rebuilding the renderer. Frames that a prop change asks for count against the cap, but a resize still redraws at once. A frame cap never wakes a parked scene or resumes a paused one.FrameScheduler.setMaxFPSsets the cap on a scheduler. The scheduler skips an animation frame that arrives sooner than one interval after its last tick, less a tenth of the interval for timestamp jitter. A tick'sdeltaspans the skipped frames. Speed-driven animation keeps its pace while tick intervals stay at or below 0.1 seconds; longer intervals are clamped byuseAnimatableSpeed, slowing the motion.0af6c42: On WebGPU, a scene no longer keeps MSAA samples or a depth buffer.
createRendererdefaultsantialiasto false and gives the canvas no depth buffer, and the scene pass inside<ShaderScene>renders without one. Every component draws one quad that covers the canvas and smooths its own edges, so neither changed a pixel. At 3272 by 1392 device pixels, a scene's render targets drop from about 400 MB to about 73 MB, and each resize reallocates the smaller set. The WebGL2 fallback renders as before.If you call
createRendereryourself, passantialias: trueto turn MSAA back on. Nothing in a WebGPU scene is depth-tested, so each mesh you draw covers whatever three drew before it.9feeb7d:
<ShaderScene>takes apausedprop, which freezes the scene on its current frame. Time stops while the scene is paused, so it resumes on the frame it stopped on. While paused, a resize draws the frozen frame again at the new size. A scene paused from its mount draws nothing until it resumes.Paused time no longer counts anywhere. When a scene resumes after a hidden tab or an off-screen canvas, it now carries on from its last frame rather than jumping ahead by the time away.
FrameScheduler's first tick after a resume carries nodelta, andelapsedcounts only the time the scheduler ran.FrameScheduler.onPauseChangetells a listener when the scheduler pauses or resumes.holdRendererClockholds the renderer's clock at its current time and returns the function that puts it back, because three's own animation loop advances that clock on every animation frame, rendered or not. The pause watcher'ssetPausedpauses the loop whatever the visibility.846e997: Add
scrollPushtoShaderScene. With it on, a touch that scrolls the page over the canvas pushes the scene's cursor effects at the finger, and a fling keeps pushing until the page stops. The scene listens passively and never cancels a touch, so the page scrolls and zooms as it would without the scene. A touch then reaches cursor effects only this way, because touch pointer moves no longer move the cursor. A mouse works as before.CursorRipplestirs its water with the push.CursorSpotlightdoesn't read the push, so it ignores touch in a scene withscrollPushon.CursorInputgainssetScrollPush,getPush,isPushing, andonPushStart. The signaluseCursorreturns gainsgetPush, which reads the frame's push stroke. The newPushStroketype has the shape of a wave field's stroke. WhilescrollPushis on,ShaderSceneticks its sharedCursorInputonce per frame, ahead of the cursor effects that read it, and keeps drawing while a touch pushes.924fe6e: Add
strokeAttoShaderScene, so code can draw a scripted stroke across the scene's cursor effects. Pass an animation signal, such as aMotionValue, holding a point from 0 to 1 across the canvas. Each frame strokes from where the point was to where it is, and a move wakes a parked scene. Attaching the point, resuming from a pause, and resizing each start a fresh stroke. While a point is attached,CursorSmudgeandCursorRippleignore the mouse and scroll push. It works with or withoutscrollPush.CursorInputgainssetStrokePoint,getScriptedStroke, andisScripting, and the signaluseCursorreturns gainsgetScriptedStrokeandisScripting. The newStrokePointtype is the shape a point must have.CursorInputalso gainsonPushEnd, which fires once for everyonPushStart, when the fling settles or the contact ends another way. A scripted stroke never starts or ends a push.8e52969:
ShaderMonitorshows the scene's GPU time per frame under its frame rate, averaged over the same half-second window. Mounting the monitor turns on GPU timing for its scene, and unmounting it turns the timing off. The readout shows a dash on the WebGL2 fallback, and on an adapter without timestamp queries. The time covers the scene pass and the output quad. Where the GPU runs the two passes at once, as Apple silicon does, the overlap counts once. A pass that a component draws on its own, such asCursorRipple's wave field, is not counted.ShaderContextValuegainstimeGpu, which turns the timing on and returns the off switch. A hand-built context, such as a fake one in a test, needs the field too, and() => () => undefinedreports nothing.c921384: Add
CursorSmudge, a cursor effect that pulls the Sources' image along pointer movement and recovers smoothly. Control the pull withstrength,radius, anddecay, using numbers or animation signals. Setdecay={0}to hold the distortion. EnablescrollPushonShaderScenefor touch scrolling.378a752:
@camp-dev/shaders/defaultsexportsSTYLE_DIAL_DEFAULTS, FractalNoise's contrast and balance for each style, without loading three. Import it from there where the root entry can't load, such as in a server render or a Node test.Patch Changes
a29b6da: A running
<ShaderScene>now redraws straight after its canvas resizes. A resize clears the canvas after the frame loop has drawn, so while a canvas changed size on every frame, such as during a window drag, the browser painted a cleared canvas on almost every frame. The redraw ticks no animation, so aspeedphase still advances once per frame. A scene out of view, or in a hidden tab, skips the redraw and draws at the new size when it resumes.The scene now updates
useResize's size before it redraws, so the redrawn frame has the new aspect ratio.useResizereturns the scene's size signal from its first render, where it used to return a placeholder size of[0, 0, 1]for one render. EveryuseResizecall in a scene shares that one signal, in place of a resize observer each.170ecc1: On WebGPU, resizing a canvas that holds a smudge from
CursorSmudgeno longer logs three'sBindings._update: binding should be availableerror.createTexturePassnow marks its texture for update when a resize changes the texture's size. A shader that samples the texture before the next draw into it then binds the new allocation.@camp-dev/shaders-cli@0.23.0
Minor Changes
postercan now render a scene that imports an image. Its bundler inlines each imported.png,.jpg,.jpeg, or.webpfile as a data URL string, so the poster server needs no route for the file. Next.js turns the same import into an object with asrcfield, so a scene that also runs in Next.js has to accept both.