A React Three Fiber component to add photo mode functionality to your 3D scenes.
npm install fiber-photo-mode
PhotoMode / screenshot capture system with post-processing effects for React Three Fiber.
⚠️ Warning: Early-stage, experimental – under active development. The API may change in future releases.
``sh`
npm install fiber-photo-mode
React Fiber Photo Mode makes it easy to take high-quality screenshots of your Three.js / React Three Fiber scenes, including post-processing effects and camera settings.
While it's technically possible to capture directly from the canvas, fiber-photo-mode lets you:
- Take screenshots at custom resolutions independent of the canvas size
- Override the canvas pixel ratio for better quality (e.g., if your canvas uses a low pixel ratio for performance, the screenshot can still be full-quality)
- Capture scenes with post-processing effects, keeping the same visual fidelity as in the canvas
- Apply photo effects (Bloom, Brightness/Contrast, Hue/Saturation, Vignette, Chromatic Aberration, Grain) to your captures
Insert into your
`jsx
import { Canvas } from "@react-three/fiber";
import { PhotoMode } from "fiber-photo-mode";
;
`
Use the usePhotoMode hook to capture screenshots:
`jsx
import { usePhotoMode } from "fiber-photo-mode";
const MyComponent = () => {
const { takeScreenshot, togglePhotoMode } = usePhotoMode();
const handleClick = async () => {
const dataUrl = await takeScreenshot();
console.log("Screenshot ready:", dataUrl);
};
return ;
};
`
The takeScreenshot function accepts optional configuration:
`jsx`
const file = await takeScreenshot({
width: 1920, // Custom width (default: canvas width)
height: 1080, // Custom height (default: canvas height)
format: "jpeg", // 'jpeg' | 'png' | 'webp' | 'avif' (default: 'jpeg')
quality: 0.95, // Compression quality 0-1 (default: 0.8)
toFile: true, // Return as File instead of DataURL
});
includes an integrated EffectComposer - any post-processing effects you want to capture must be placed as children of :
`jsx
import { Canvas } from "@react-three/fiber";
import { PhotoMode } from "fiber-photo-mode";
import { BrightnessContrast, ToneMapping } from "@react-three/postprocessing";
;
`
Important: These effects passed as children to will be visible in the canvas at all times, not just in screenshots. If you want effects visible only in photo mode, use the usePhotoModeEffects hook instead.
The library includes built-in photo effects that are added to the EffectComposer and can be toggled and controlled independently. By default, all effects are enabled except Bloom (which is experimental and may cause visual artifacts).
Use the enabledEffects prop to configure which built-in effects are added to the effect composer. The enabledEffects prop is optional - you only need to specify the effects you want to override from the defaults:
`jsx`
bloom: true, // Enable Bloom (disabled by default)
}}
{/ Your effects from react-postprocessing /}
Important distinction: The enabledEffects prop determines which effects are added to the EffectComposer, not whether they are visible. By default, when effects are added, they are inactive (with zero intensity/values).
To actually see these effects in your canvas and screenshots, you must:
1. Enable photo mode using the hook:
`jsx`
const { togglePhotoMode } = usePhotoMode();
togglePhotoMode(); // Enables photo mode
2. Set effect values using the effects hook:
`jsx`
const { setEffect } = usePhotoModeEffects();
setEffect("bloom", 2.5);
setEffect("brightness", 0.3);
Use the usePhotoModeEffects hook to read current effect values and control them:
`jsx
import { usePhotoMode, usePhotoModeEffects } from "fiber-photo-mode";
export function PhotoModeUI() {
const { brightness, setEffect } = usePhotoModeEffects();
const { photoModeOn } = usePhotoMode();
if (!photoModeOn) return null;
return (
<>
type="range"
value={brightness}
onChange={(e) => setEffect("brightness", parseFloat(e.target.value))}
min={-1}
max={1}
step={0.01}
className="w-full"
/>
);
}
`
- Hue/Saturation - Adjust color tone and saturation (enabled by default)
- Brightness/Contrast - Modify exposure and contrast (enabled by default)
- Vignette - Darken edges for a focused look (enabled by default)
- Chromatic Aberration - Add RGB color shift for stylized effect (enabled by default)
- Grain - Add film grain texture (enabled by default)
- Bloom - Add glow to bright areas (disabled by default - experimental)
| Aspect | Built-in Photo Effects | Custom Effects (as children) |
| ----------------------- | ---------------------------------------- | ----------------------------------- |
| Added via | enabledEffects prop | |togglePhotoMode()
| Visibility | Only visible in photo mode (when active) | Always visible on canvas |
| Captured in screenshots | Yes | Yes |
| Togglable | Yes, via | Always active |usePhotoModeEffects()
| Configurable | Yes, via | Configured directly on component |
- 1:1 screenshot of the canvas with accurate camera & viewport
- Built-in photo effects integrated into
- Capture at custom resolutions, independent of canvas size or pixel ratio
- Easy-to-use hooks for calling screenshots and managing effects from anywhere in your app
- Support for custom post-processing effects as children
- Automatic effect pass management
MIT – free to use, modify, and expand.