Skip to content

Conversation

@DennisSmolek
Copy link
Member

forceEven Canvas Prop

Added forceEven prop to Canvas for Safari compatibility. Safari has issues with odd or fractional HTML canvas dimensions. When enabled, canvas dimensions are rounded up to the nearest even number.

<Canvas forceEven>{/* Canvas dimensions are guaranteed to be even numbers */}</Canvas>

Key details:

  • Rounds dimensions UP to the nearest even number (e.g., 501 → 502, 301 → 302)
  • Uses Math.ceil(n / 2) * 2 to ensure odd values round up, not down
  • Accessible to Drei components via useThree((state) => state.internal.forceEven)

Files changed:

  • packages/fiber/types/canvas.d.ts - Added forceEven prop type
  • packages/fiber/types/store.d.ts - Added forceEven to InternalState
  • packages/fiber/src/core/Canvas.tsx - Prop destructuring and effectiveSize rounding logic
  • packages/fiber/src/core/renderer.tsx - Store forceEven in internal state

Canvas Background Prop

Added a flexible background prop to Canvas for declarative scene background and environment configuration. Supports colors, URLs, presets, and an expanded object form for separate background/environment maps.

Simple string forms:

<Canvas background="red" />              // Color
<Canvas background="#1a1a2e" />          // Hex color
<Canvas background={0xff0000} />         // Hex number
<Canvas background="/path/to/env.hdr" /> // URL
<Canvas background="sunset" />           // Preset

Expanded object form:

<Canvas
  background={{
    preset: 'city',
    backgroundBlurriness: 0.5,
    backgroundIntensity: 1,
    environmentIntensity: 1.2,
  }}
/>

Key features:

  • String detection: presets → URLs → colors (priority order)
  • Supports all HDRI presets: apartment, city, dawn, forest, lobby, night, park, studio, sunset, warehouse
  • Object form allows separate backgroundMap and environment files
  • Replaces verbose <color attach="background"> pattern

Loader migrations:

  • RGBELoaderHDRLoader (renamed in Three.js r180)
  • HDRJPGLoaderUltraHDRLoader (Three.js native)

New exports:

  • Environment component from @react-three/fiber
  • useEnvironment hook from @react-three/fiber
  • presetsObj and PresetsType for preset names

Files changed:

  • packages/fiber/types/canvas.d.ts - Added BackgroundProp, BackgroundConfig types
  • packages/fiber/src/core/Canvas.tsx - Background prop parsing and Environment rendering
  • packages/fiber/src/core/components/Environment/Environment.tsx - Enhanced with color/backgroundFiles support
  • packages/fiber/src/core/hooks/useEnvironment.tsx - Loader migrations
  • packages/fiber/src/core/index.tsx - Added Environment exports
  • packages/fiber/src/core/hooks/index.tsx - Added useEnvironment export

Multi-Canvas Rendering (WebGPU)

Added support for sharing a single WebGPURenderer across multiple Canvas components, enabling HUD overlays, picture-in-picture views, and multi-viewport rendering.

Primary canvas setup:

<Canvas id="main" renderer>
  <Scene />
</Canvas>

Secondary canvas sharing the renderer:

<Canvas renderer={{ primaryCanvas: 'main', scheduler: { after: 'main', fps: 30 } }}>
  <HudScene />
</Canvas>

Key features:

  • renderer={{ primaryCanvas: 'id' }} - Share renderer from another canvas
  • scheduler.after - Control render ordering between canvases
  • scheduler.fps - Limit secondary canvas render rate
  • primaryStore - Access primary's scene/camera for HUD-style rendering

Color Management Props

Added explicit colorSpace and toneMapping props for direct control over renderer color settings, deprecating the boolean linear and flat shortcuts.

New props:

  • colorSpace - Set renderer.outputColorSpace directly (default: THREE.SRGBColorSpace)
  • toneMapping - Set renderer.toneMapping directly (default: THREE.ACESFilmicToneMapping)

Deprecated props:

  • linear - Use colorSpace={THREE.LinearSRGBColorSpace} instead
  • flat - Use toneMapping={THREE.NoToneMapping} instead
// Before (deprecated)
<Canvas linear flat />

// After
<Canvas
  colorSpace={THREE.LinearSRGBColorSpace}
  toneMapping={THREE.NoToneMapping}
/>

// New flexibility - use any tone mapping algorithm
<Canvas toneMapping={THREE.ReinhardToneMapping} />
<Canvas toneMapping={THREE.CineonToneMapping} />
  • Fixed portal size state being overwritten by parent resize events. Portals now correctly preserve their own size override when the root canvas resizes, matching the existing behavior for events. This also fixes nested portals ignoring their size configuration.
  • Fixed setSize not triggering a frame in demand mode. Now calls scheduler.invalidate() directly so useFrame callbacks can respond to size changes.

Replace boolean shortcut props with explicit THREE.js value props for
better flexibility and clarity:

- colorSpace: Set renderer.outputColorSpace directly (default: SRGBColorSpace)
- toneMapping: Set renderer.toneMapping directly (default: ACESFilmicToneMapping)

Deprecated props (will be removed in v11):
- linear: Use colorSpace={THREE.LinearSRGBColorSpace} instead
- flat: Use toneMapping={THREE.NoToneMapping} instead

The new props allow any THREE.js color space or tone mapping algorithm,
not just the two hardcoded options. Backwards compatible - old props
still work but log deprecation warnings.
@DennisSmolek DennisSmolek merged commit 723622e into v10 Jan 25, 2026
2 checks passed
@DennisSmolek DennisSmolek deleted the feat-scene-bg branch January 25, 2026 08:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants