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
- Call `await renderer.init();` before `pmrem.fromScene(scene)`.
- Use the deprecated `await pmrem.fromSceneAsync(scene, ...)` which inits the renderer internally.
- 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
- Await renderer.init() before constructing or using a PMREMGenerator.
- Run environment-map baking in an async post-init phase.
- Reuse a single initialized renderer for all PMREM work.
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
- THREE.PMREMGenerator: .fromEquirectangular() called before t
- THREE.PMREMGenerator: .fromCubemap() called before the backe
- THREE.Renderer: .hasFeature() called before the backend is i
- THREE.Renderer: .initTexture() called before the backend is
- THREE.Renderer: .initRenderTarget() called before the backen
AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12).
Data as JSON: /api/errors/f2a085062a222728.
Report an issue: GitHub.