Skip to content

Fix THREE.js WebGPU renderer initialization timing issue in FiberCanvas#237

Closed
wcandillon with Copilot wants to merge 3 commits into
mainfrom
copilot/fix-214
Closed

Fix THREE.js WebGPU renderer initialization timing issue in FiberCanvas#237
wcandillon with Copilot wants to merge 3 commits into
mainfrom
copilot/fix-214

Conversation

Copilot AI commented Jun 25, 2025

Copy link
Copy Markdown

Problem

The THREE.js WebGPU renderer was being called before proper initialization, causing the warning:

THREE.Renderer: .render() called before the backend is initialized. Try using .renderAsync() instead.

This occurred because:

  • The WebGPU renderer was created immediately but initialized asynchronously
  • React Three Fiber started rendering with frameloop="always" before initialization completed
  • This created a race condition where render() was called on an uninitialized renderer

Solution

Implemented proper initialization sequencing by:

  1. Added frameloop state management - Start with frameloop="never" to prevent premature rendering
  2. Moved renderer initialization - Initialize WebGPU renderer directly in the gl configuration function
  3. Async initialization control - Set frameloop="always" only after renderer.init() completes
  4. State-driven reconfiguration - Added useEffect to update frameloop when initialization status changes
  5. Removed duplicate initialization - Eliminated redundant await state.gl.init() call in onCreated

Code Changes

// Before: Immediate rendering with uninitialized renderer
gl: renderer,
frameloop: "always",
onCreated: async (state: RootState) => {
  await state.gl.init(); // Race condition here
  // ...
}

// After: Controlled initialization sequence
const [frameloop, setFrameloop] = useState<"always" | "never">("never");

gl: () => {
  const renderer = new THREE.WebGPURenderer({...});
  renderer.init().then(() => {
    setFrameloop("always"); // Enable rendering only after init
  });
  return renderer;
},
frameloop, // Controlled by state
onCreated: (state: RootState) => {
  // No duplicate initialization
  // ...
}

Validation

  • ✅ TypeScript compilation passes without errors
  • ✅ ESLint validation passes without warnings
  • ✅ Minimal code changes (28 additions, 7 deletions in 1 file)
  • ✅ No breaking changes to existing API

This should resolve the timing issue and prevent the renderer initialization warning while maintaining consistent rendering behavior.

Fixes #214.

Warning

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • googlechromelabs.github.io
    • Triggering command: /usr/local/bin/node install.mjs (dns block)
  • https://storage.googleapis.com/chrome-for-testing-public/127.0.6533.88/linux64/chrome-headless-shell-linux64.zip
    • Triggering command: /usr/local/bin/node install.mjs (http block)
  • https://storage.googleapis.com/chrome-for-testing-public/127.0.6533.88/linux64/chrome-linux64.zip
    • Triggering command: /usr/local/bin/node install.mjs (http block)

If you need me to access, download, or install something from one of these locations, you can either:


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Copilot AI and others added 2 commits June 25, 2025 20:49
Co-authored-by: wcandillon <306134+wcandillon@users.noreply.github.com>
Co-authored-by: wcandillon <306134+wcandillon@users.noreply.github.com>
Copilot AI changed the title [WIP] THREE.Renderer: .render() called before the backend is initialized. Try using .renderAsync() instead. Fix THREE.js WebGPU renderer initialization timing issue in FiberCanvas Jun 25, 2025
Copilot AI requested a review from wcandillon June 25, 2025 20:54
@wcandillon wcandillon closed this Jun 26, 2025
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.

THREE.Renderer: .render() called before the backend is initialized. Try using .renderAsync() instead.

2 participants