Releases: pmndrs/react-postprocessing
Release list
v3.1.3
Patch release - fixes broken N8AO output after a pixel ratio change (#280).
Fixed
- EffectComposer: changing only the pixel ratio (
setDpr,<AdaptiveDpr>,dprprop) didn't resize the composer and its passes. They now follow the drawing buffer size.
What's Changed
- fix(EffectComposer): resize the composer when the pixel ratio changes by @tonyblu331 in #381
New Contributors
- @tonyblu331 made their first contribution in #381
Full Changelog: v3.1.2...v3.1.3
v3.1.2
Patch release - fixes a crash in mergeMode: "auto" when combining a UV-transforming effect (e.g. Glitch) with a convolution effect (e.g. ChromaticAberration).
Fixed
- EffectComposer:
mergeMode: "auto"could merge amainUveffect into the same pass as a convolution effect, whichpostprocessingitself doesn't allow -EffectPassthrows at render time either way.'auto'now keeps them apart the same way it already keeps two convolution effects apart.
What's Changed
- docs: add example links for ASCII and N8AO by @kvvasuu in #379
- fix: keep mainUv effects out of the same auto-merged pass as convolution effects by @kvvasuu in #380
Full Changelog: v3.1.1...v3.1.2
v3.1.1
Patch release focused purely on compatibility - no behavior changes.
It loosens peerDependencies that were accidentally over-constrained in 3.1.0.
What's Changed
- fix: loosen peerDependencies for react and three by @kvvasuu in #378
- Build the docs with pmndrs/docs@v4 by @abernier in #375
Full Changelog: v3.1.0...v3.1.1
v3.1.0
This release is an internal rewrite of how effects apply prop changes - most of it is invisible unless you hit one of the bugs it fixes, but it puts every effect on the same reliable, live-updating foundation instead of each one reconstructing itself in ad hoc ways.
Added
- EffectGroup: new component that groups effects into a single
EffectPasswith its own cheapenabledtoggle, backed by a shared trailingCopyPassso disabling the last pass in a chain doesn't blank the canvas. - DepthPicking, useDepthPicking: new component + hook for reading world-space positions off the depth buffer, extracted from
<Autofocus>into a reusable, standalone primitive.<DepthPicking>just mounts the vanillaDepthPickingPassand exposesreadDepthvia ref - renders nothing, updates nothing automatically.useDepthPickingturns a screen position into a world-space point on demand, auto-detecting the composer's own camera when used inside its<EffectComposer>, with an explicitcameraoverride for calling it from outside that tree.<Autofocus>is now built on both internally, same external behavior. - EffectComposer: new
autoRenderToScreen?: booleanprop (defaulttrue) - construction-time option, same treatment asdepthBuffer/multisampling. - EffectComposer: new
renderPass?: (scene, camera) => Passprop - lets consumers supply their own scene/camera render pass - EffectComposer: new
mergeMode?: 'auto' | 'all' | 'none'prop (default'auto').'auto'merges effects into as fewEffectPasses as possible while keeping at most one convolution effect per pass - matching whatpostprocessingitself actually allows. This is strictly better than the old unconditional "any convolution effect gets fully isolated" behavior.'all'drops that safety limit entirely.'none'gives every effect its own pass. - createEffectComponent: the internal effect-wrapping factory is now part of the public API, for wrapping your own zero-arg-constructible
postprocessingeffect classes the same way this library's own simple effects do. - N8AO: new
enabledprop, wired into the same shared trailing-CopyPasssafety net asEffectGroup(N8AO isn't a mergeablepostprocessingEffect, so it needed its own toggle rather than going throughEffectGroupdirectly). - Grid, Glitch:
opacitynow works - these never went throughwrapEffect(the only place that handled it) before, so it was silently inert regardless of what the (missing) types suggested. - Outline, GodRays: warn in the console when mounted without
<EffectComposer autoClear={false}>- both render an internal extra pass that silently produces wrong output (outlines don't render at all; GodRays occlusion looks wrong) without it. - Outline:
visibleEdgeColor/hiddenEdgeColornow typed asColorRepresentation(number | string | Color) instead of justnumber- the runtime already wrapped values innew Color(value), so string colors ("red", "#ff0000", etc.) always worked, the type just didn't say so. - LensFlare, ShockWave:
lensPosition/positionnow acceptReactThreeFiber.Vector3(a tuple or a single number, not just aVector3instance), matching how position props work everywhere else in the r3f ecosystem.
Changed
- Effects whose
postprocessingclass can be constructed with zero arguments are now built oncreateEffectComponent: live props update the existing effect instance in place instead of reconstructing it on every change, and arefnow points to one stable instance across prop updates instead of a new one every render. - Effects that need real constructor args and can't use
createEffectComponentsimilarly apply live props throughuseLiveDefaultsinstead of reconstructing the whole effect on every change. - EffectComposer: pass rebuild lifecycle rewritten - passes are now only rebuilt when the resolved effect/pass list actually changed, not on every unrelated React render.
- SSAO:
resolutionScalenow falls back to the parent<EffectComposer>'s ownresolutionScaleprop when not set directly on<SSAO>, instead of always defaulting straight to1. - Build:
distis no longer minified - the consumer's own bundler minifies anyway in a real production build, and this keeps stack traces/devtools readable when debugging into the library.
Fixed
- SSAO: almost none of its props updated live on change -
useMemoonly depended on[camera, downSamplingPass, normalPass, resolutionScale], and props were never re-applied to the effect any other way. Changingcolor,intensity,radius,samples,worldProximityThreshold/worldProximityFalloff, or anything else did nothing until one of those four values happened to change too. Now applies live viauseLiveDefaults. - DepthOfField: changing
depthTexturereconstructed the whole effect - render targets and passes included - despiteDepthOfFieldEffect.setDepthTexture()existing specifically to update an existing instance in place. Now applied live. - N8AO: config/
qualitychanges mutateeffect.configurationdirectly (a plain object outside r3f's reconciler) without ever callinginvalidate(), so changes didn't repaint under<Canvas frameloop="demand">. - EffectComposer: sized itself off r3f's
size, which drei's<View>overrides per-portal only onView's own re-renders - not kept live - so a composer nested in a<View>could go arbitrarily long without picking up a resize (in practice: staying offset/wrong-sized indefinitely). Now readsgl.getSize()directly instead, which isn't portal-scoped and can't be missed regardless of whether the component itself ever re-renders.
Removed
- Pixelation, ShockWave:
blendFunction/opacityprops removed entirely. Both aremainUv-only shaders (nomainImage, verified againstpostprocessing's own pass-composition logic) - there's no color output to blend, so the props never did anything; they're gone rather than wired up. If you were passing either to<Pixelation>/<ShockWave>, remove them - they were already silent no-ops.
What's Changed
- Add createEffectComponent, a thin r3f-native effect factory by @kvvasuu in #363
- Rewrite EffectComposer's pass lifecycle for correctness and cost by @kvvasuu in #364
- Migrate simple effects to createEffectComponent by @kvvasuu in #366
- Migrate hand-rolled effects to useLiveDefaults by @kvvasuu in #367
- Simplify Autofocus's dispose handling, drop idempotency guard by @kvvasuu in #368
- docs: Update Custom Effects docs for React 19 by @MaximeHeckel in #337
- Fix/docs workflow v3 by @kvvasuu in #370
- docs(examples): migrate examples to @pmndrs/examples by @kvvasuu in #371
- feat: add DepthPicking component and useDepthPicking hook by @kvvasuu in #372
- chore: switch from yarn to pnpm by @kvvasuu in #373
- docs: add missing effect pages by @kvvasuu in #374
- docs: link effect examples to pmndrs/examples by @kvvasuu in #376
New Contributors
- @MaximeHeckel made their first contribution in #337
Full Changelog: v3.0.5...v3.1.0
v3.0.5
Fixed
- EffectComposer: the composer was created in
useMemo, which React may discard without running cleanup. Creation moved into a proper effect lifecycle instead. (#353) by @kvvasuu - EffectComposer:
renderer.autoClearandrenderer.toneMappingwere force-set and never restored. They're now restored on unmount. (#358) by @kvvasuu - ChromaticAberration: moved off the generic
wrapEffectonto a manual construct/dispose pattern so the tupleoffsetprop is correctly coerced. (#355) by @kvvasuu - Selection: fixed an infinite update loop caused by
Select's effect depending on its own write; it now diffs newly-claimed/released objects against what it previously claimed instead of clearing and re-adding unconditionally. (#359) by @kvvasuu - Selection: object detection now covers
Mesh/Line/Pointssubclasses (isMesh/isLine/isPoints), not just an exacttype === 'Mesh'check - custom mesh subclasses are now selectable. (#359) by @kvvasuu - SelectiveBloom: light refs that haven't attached yet are now resolved and filtered instead of crashing
addLight/removeLighton a null object. (#360) by @kvvasuu - Outline, SelectiveBloom: selection sync unified behind a shared
useSelectionSynchook, which also stops the selection effect from re-running on every render (it previously depended on an unstable spreadpropsobject). (#360) by @kvvasuu - Outline:
patternScale,multisampling,resolutionScale,resolutionX,resolutionYare now wired up as live constructor options. (#360) by @kvvasuu - SelectiveBloom:
radius,levels,resolutionScale,resolutionX,resolutionYare now wired up as live constructor options. (#360) by @kvvasuu - All
<primitive>-based effects now dispose themselves (newuseDisposehook). (#355) by @kvvasuu - Corrected npm package metadata (added
bugs/homepagefields). (#347) by @2lll5
Changed
wrapEffectsplit out ofutil.tsxinto its own module; Effect components droppedforwardRefin favor ofrefas a plain, optional prop. (#352) by @kvvasuu@react-three/fiberpeer floor raised to>=9.7.0. (#353) by @kvvasuupostprocessingmoved from a pinneddependenciesentry to apeerDependenciesrange (^6.36.0);threepeer floor raised to>= 0.182.0. (#351) by @kvvasuu- Migrated ESLint config to flat config; updated dependencies. (#351) by @kvvasuu
- Updated tone mapping docs (examples and props table). (#345) by @vis-prime
Added
- Smoke test coverage for every effect component, plus new regression tests for Selection, Outline, SelectiveBloom, ChromaticAberration, EffectComposer, and wrapEffect. (#355, #356, #359, #360) by @kvvasuu
- GitHub Action for publishing releases to npm from
master, by @krispya
New Contributors
- @2lll5 made their first contribution in #347
- @vis-prime made their first contribution in #345
Full Changelog: v3.0.4...v3.0.5
v3.0.4
What's Changed
- fix(types): emit types in build by @CodyJasonBennett in #327
Full Changelog: v3.0.3...v3.0.4
v3.0.3
Manual re-release of v3.0.2.
Full Changelog: v3.0.2...v3.0.3