mrdoob/three.js · error · Error

THREE.PMREMGenerator: .fromScene() called before the backend

Error message

THREE.PMREMGenerator: .fromScene() called before the backend is initialized. Use "await renderer.init();" before using this method.

What it means

Thrown by PMREMGenerator.fromScene() when the underlying renderer has not been initialized. PMREMGenerator._hasInitialized delegates to renderer.hasInitialized(); generating a PMREM requires rendering a scene into a cubemap, so the GPU backend must already be live.

Source

Thrown at src/renderers/common/extras/PMREMGenerator.js:145

	 * @param {number} [options.size=256] - The texture size of the PMREM.
	 * @param {Vector3} [options.position=origin] - The position of the internal cube camera that renders the scene.
	 * @param {?RenderTarget} [options.renderTarget=null] - The render target to use.
	 * @return {RenderTarget} The resulting PMREM.
	 * @see {@link PMREMGenerator#fromScene}
	 */
	fromScene( scene, sigma = 0, near = 0.1, far = 100, options = {} ) {

		const {
			size = 256,
			position = _origin,
			renderTarget = null,
		} = options;

		this._setSize( size );

		if ( this._hasInitialized === false ) {

			throw new Error( 'THREE.PMREMGenerator: .fromScene() called before the backend is initialized. Use "await renderer.init();" before using this method.' );

		}

		_oldTarget = this._renderer.getRenderTarget();
		_oldActiveCubeFace = this._renderer.getActiveCubeFace();
		_oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel();

		const cubeUVRenderTarget = renderTarget || this._allocateTarget( true );

		this._init( cubeUVRenderTarget );

		this._sceneToCubeUV( scene, near, far, cubeUVRenderTarget, position );

		if ( sigma > 0 ) {

			this._blur( cubeUVRenderTarget, 0, 0, sigma );

		}

View on GitHub (pinned to da05705fa3)

Solutions

  1. Call `await renderer.init();` before `pmrem.fromScene(scene)`.
  2. Use the deprecated `await pmrem.fromSceneAsync(scene, ...)` which inits the renderer internally.
  3. Defer PMREM generation until after the first render frame.

Example fix

// before
const renderer = new WebGPURenderer();
const pmrem = new PMREMGenerator(renderer);
const envMap = pmrem.fromScene(scene); // throws

// after
const renderer = new WebGPURenderer();
await renderer.init();
const pmrem = new PMREMGenerator(renderer);
const envMap = pmrem.fromScene(scene);
Defensive patterns

Strategy: validation

Validate before calling

async function safeFromScene(pmrem, scene, opts) {
  if (!pmrem._renderer.hasInitialized()) await pmrem._renderer.init();
  return pmrem.fromScene(scene, opts);
}

Type guard

function pmremReady(pmrem) {
  return pmrem._renderer && typeof pmrem._renderer.hasInitialized === 'function' && pmrem._renderer.hasInitialized();
}

Try / catch

try {
  return pmrem.fromScene(scene);
} catch (e) {
  if (/fromScene\(\) called before/.test(e.message)) { await pmrem._renderer.init(); return pmrem.fromScene(scene); }
  else throw e;
}

Prevention

When it happens

Trigger: Constructing `new PMREMGenerator(renderer)` and calling `.fromScene(scene)` before `await renderer.init()` has resolved. Common when generating an environment map at app startup.

Common situations: Environment-map baking at module load. Migrating from the deprecated fromSceneAsync without adding the explicit init await. Loading an HDR/scene-based environment before the first render.

Related errors


AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12). Data as JSON: /api/errors/f2a085062a222728. Report an issue: GitHub.