@liquid-dom/r3f
v0.1.0
Published
`@liquid-dom/r3f` bridges React Three Fiber, Three's WebGPU renderer, and the React liquid-glass scene. It renders your R3F scene into an intermediate backdrop target, then composites liquid glass over it.
Readme
@liquid-dom/r3f
Description
@liquid-dom/r3f bridges React Three Fiber, Three's WebGPU renderer, and the React liquid-glass scene. It renders your R3F scene into an intermediate backdrop target, then composites liquid glass over it.
Install
pnpm add @liquid-dom/r3f @liquid-dom/react @react-three/fiber react react-dom threeQuick Start
import * as THREE from 'three/webgpu'
import { Canvas, extend } from '@react-three/fiber'
import { LiquidGlassR3F } from '@liquid-dom/r3f'
import {
Frame,
Glass,
GlassContainer,
Html,
} from '@liquid-dom/react'
extend(THREE as any)
export function App() {
return (
<LiquidGlassR3F.Root>
<Canvas
gl={async (props) => {
const renderer = new THREE.WebGPURenderer(props as any)
await renderer.init()
return renderer
}}
>
<mesh>
<boxGeometry />
<meshBasicNodeMaterial color="hotpink" />
</mesh>
<LiquidGlassR3F.Render />
</Canvas>
<LiquidGlassR3F.Scene>
<GlassContainer blur={12} spacing={28}>
<Frame width={280} height={160}>
<Glass cornerRadius={44}>
<Html sizing="fill">
<button>Native content</button>
</Html>
</Glass>
</Frame>
</GlassContainer>
</LiquidGlassR3F.Scene>
</LiquidGlassR3F.Root>
)
}API Overview
Component API
<LiquidGlassR3F.Root>
<Canvas gl={createWebGpuRenderer}>
<LiquidGlassR3F.Render renderPriority={1} />
</Canvas>
<LiquidGlassR3F.Scene>
{/* @liquid-dom/react layout */}
</LiquidGlassR3F.Scene>
</LiquidGlassR3F.Root>LiquidGlassR3F.Rootshares the scene ref and invalidation bridge.LiquidGlassR3F.Scenecreates a headlessLiquidScenefor liquid-glass React components.LiquidGlassR3F.Renderruns inside the R3F canvas and takes over final rendering with a positive frame priority.LiquidGlassR3Fis also callable as the render component, so<LiquidGlassR3F />is equivalent to<LiquidGlassR3F.Render />.
Component props:
| Component | Props |
| --- | --- |
| LiquidGlassR3F.Root | children, optional sceneRootRef |
| LiquidGlassR3F.Scene | children |
| LiquidGlassR3F.Render | sceneRootRef, renderPriority, enabled, dpr, outputTexture, renderTarget, onError |
| LiquidGlassR3F | Same props as LiquidGlassR3F.Render |
Hook API
Use useLiquidGlassR3F when you want to own the LiquidScene placement yourself.
import { Canvas } from '@react-three/fiber'
import { useRef, type RefObject } from 'react'
import { LiquidScene, type LiquidSceneRef } from '@liquid-dom/react'
import { useLiquidGlassR3F } from '@liquid-dom/r3f'
function Bridge() {
const sceneRootRef = useRef<LiquidSceneRef | null>(null)
return (
<>
<Canvas gl={createWebGpuRenderer}>
<RenderBridge sceneRootRef={sceneRootRef} />
</Canvas>
<LiquidScene ref={sceneRootRef}>
{/* @liquid-dom/react layout */}
</LiquidScene>
</>
)
}
function RenderBridge({
sceneRootRef,
}: {
sceneRootRef: RefObject<LiquidSceneRef | null>
}) {
useLiquidGlassR3F({ sceneRootRef, renderPriority: 1 })
return null
}Render Options
LiquidGlassR3F.Render and useLiquidGlassR3F accept:
renderPriority: positive R3F frame priority. Defaults to1.enabled: disables rendering without unmounting resources.dpr: number or function. Defaults to Three's pixel ratio.outputTexture: optionalGPUTextureor function returning one.renderTarget: options for the internal Three backdrop target.onError: setup or render error handler.
The hook also accepts sceneRootRef and deferUntilSceneRoot.
Full option reference:
| Option | Type | Description |
| --- | --- | --- |
| sceneRootRef | RefObject<LiquidSceneRef \| null> | Ref for the LiquidScene to render. Required by useLiquidGlassR3F; optional for the component API when used under Root. |
| deferUntilSceneRoot | boolean | Hook-only option that waits for sceneRootRef.current instead of throwing. |
| renderPriority | number | Positive R3F frame priority. Defaults to 1. |
| enabled | boolean | Enables or disables the bridge. Defaults to true. |
| dpr | number \| (state) => number | DPR used by liquid-glass rendering. Invalid values fall back to Three's pixel ratio. |
| outputTexture | GPUTexture \| null \| undefined \| (state) => GPUTexture \| null \| undefined | Optional output target. Defaults to the canvas current texture. |
| renderTarget | LiquidGlassR3FRenderTargetOptions | Options for the internal Three RenderTarget: colorSpace, depthBuffer, format, samples, stencilBuffer, and type. |
| onError | (error: unknown) => void | Called for setup or render failures. If omitted, errors are thrown. |
Exported types are LiquidGlassR3FDpr, LiquidGlassR3FOutputTexture, LiquidGlassR3FRenderTargetOptions, UseLiquidGlassR3FOptions, LiquidGlassR3FRootProps, LiquidGlassR3FSceneProps, LiquidGlassR3FRenderProps, and LiquidGlassR3FProps.
Integration Notes
- This package requires R3F with an initialized Three WebGPU renderer.
- DOM-backed
Htmlcontent from@liquid-dom/reactrequires the experimental HTML-in-Canvas API, currently available only behind Chrome's Canvas Draw Element flag:chrome://flags/#canvas-draw-element. renderPrioritymust be positive so the bridge can take over final rendering.- The component API wires liquid-scene invalidations into R3F invalidation, including demand-driven frame loops.
- The hook API is lower-level. If you use it directly, make sure the supplied
LiquidSceneinvalidates R3F when layout or frame state changes. - The bridge renders the R3F scene into an internal target before compositing liquid glass.
- Reference: WICG HTML-in-Canvas.
Local Development
pnpm --filter @liquid-dom/r3f build
pnpm --filter @liquid-dom/r3f watch