FrostedGlass#

A container that blurs the 3D scene behind it, creating a frosted glass effect. The blur pipeline is automatic: it captures what the scene's main camera (the one tagged MainCamera) sees, so no render texture setup is needed. The blur appears in Play mode; the edit-mode preview shows only the tint.

Import#

import { FrostedGlass } from "onejs-react"

Basic Usage#

<FrostedGlass style={{ width: 300, height: 200, borderRadius: 16 }}>
    <Label text="Hello from behind the glass" />
</FrostedGlass>

Props#

PropTypeDefaultDescription
blurnumber10Blur radius in screen pixels. Higher = more blurry
tintcolor"rgba(255,255,255,0.15)"Tint color overlaid on the blurred background
styleViewStyleInline styles
classNamestringUSS class name(s)

Tint Color#

The tint prop takes any color style does: hex (#19c8f033), rgb() and rgba(), a CSS name, or an [r, g, b, a] array of 0 to 1 values. A value that is not a color falls back to the default tint. Use alpha to control how much the tint blends with the blurred background:

// Subtle white frost
<FrostedGlass tint="rgba(255,255,255,0.15)" />

// Colored glass
<FrostedGlass tint="#19c8f033" />

// Heavy tint
<FrostedGlass tint={[0, 0, 0, 0.5]} />

Dynamic Blur#

The blur radius can be adjusted at runtime:

function BlurPanel() {
    const [blur, setBlur] = useState(10)

    return (
        <View>
            <FrostedGlass blur={blur}
                style={{ width: 300, height: 200, borderRadius: 16 }}>
                <Label text={`Blur: ${Math.round(blur)}`} />
            </FrostedGlass>
            <Slider
                value={blur}
                min={0}
                max={40}
                onChange={(e) => setBlur(e.value)}
                style={{ width: 300, marginTop: 16 }}
            />
        </View>
    )
}

How It Works#

FrostedGlass captures the 3D scene using a lightweight clone camera (excluding UI), downsamples it, and applies a two-pass Gaussian blur. The blurred result is UV-mapped to the element's screen position so it always reflects what's directly behind it.

Multiple FrostedGlass elements share a single blur pass, so they all use the largest blur among them.

FrostedGlass or backdropFilter#

Unity 6.6 adds its own backdrop-filter USS property, which OneJS passes through from USS and from style={{ backdropFilter: "blur(8px)" }} (see Filters). That is Unity's filter applied to what is behind the element. FrostedGlass is separate: it blurs the 3D scene from the main camera, carries its own tint, and works from Unity 6.3.

Rotation Example#

The blur stays screen-aligned even when the element is rotated:

function App() {
    const [blur, setBlur] = useState(10)
    const [rotation, setRotation] = useState(0)
    const rafRef = useRef<number>(0)

    useEffect(() => {
        const animate = () => {
            setRotation(r => (r + 0.5) % 360)
            rafRef.current = requestAnimationFrame(animate)
        }
        rafRef.current = requestAnimationFrame(animate)
        return () => cancelAnimationFrame(rafRef.current)
    }, [])

    return (
        <View style={{ justifyContent: "center", alignItems: "center",
            width: "100%", height: "100%" }}>
            <FrostedGlass blur={blur} tint="rgba(25, 243, 243, 0.15)"
                style={{ justifyContent: "center", alignItems: "center",
                    width: 300, height: 200, borderRadius: 16, rotate: rotation }}>
                <Label>Blur: {Math.round(blur)}</Label>
            </FrostedGlass>
            <Slider min={0} max={40} value={blur}
                onChange={(e) => setBlur(e.value)}
                style={{ width: 300, marginTop: 16 }} />
        </View>
    )
}