Hey, I’m pretty new to Three.js and have a problem that is completely boggling my mind. I’ve set up a basic scene that loads a glb object and has it rotate, and it will sometimes render to the page, but other times it will just completely fail and give the error: Uncaught ReferenceError: scene is not defined
I’ve tried switching the glb file to other objects. Some work consistently every time, while others work about 5% of the time. What could possibly be causing the inconsistency here?
To provide a little more detail, the console error points me towards my renderer.js module, which has the code:
import { WebGLRenderer } from "../../../vendor/three/build/three.module.js";
function createRenderer() {
const renderer = new WebGLRenderer({ antialias: true });
// start the loop
renderer.setAnimationLoop(() => {
renderer.render(scene, camera);
});
renderer.physicallyCorrectLights = true;
return renderer;
}
export { createRenderer };
Any ideas on what could be causing this inconsistency?
This sounds like a race condition – probably you’re not consistently creating the “scene” variable before this code runs. Perhaps show the code that (1) creates the scene, and (2) calls createRenderer
? Are you sure things are happening in that order?
So this is my code that builds the scene and also calls createRenderer:
class World {
constructor(container) {
camera = createCamera();
scene = createScene();
renderer = createRenderer();
loop = new Loop(camera, scene, renderer);
container.append(renderer.domElement);
controls = createControls(camera, renderer.domElement);
const { ambientLight, mainLight } = createLights();
loop.updatables.push(controls);
scene.add(ambientLight, mainLight);
const resizer = new Resizer(container, camera, renderer);
}
async init() {
const { parrot } = await loadBirds();
console.log("the can has been loaded.");
loop.updatables.push(parrot);
scene.add(parrot);
}
render() {
renderer.render(scene, camera);
}
start() {
loop.start();
}
stop() {
loop.stop();
}
}
export { World };
I think I’ve identified that the bug is happening inside the setAnimationLoop function inside renderer.js:
import { WebGLRenderer } from "../../../vendor/three/build/three.module.js";
function createRenderer() {
const renderer = new WebGLRenderer({ antialias: true });
// start the loop
renderer.setAnimationLoop(() => {
renderer.render(scene, camera);
// THIS DOES NOT SHOW UP IN CONSOLE:
console.log("renderer.SetAnimationLoop");
});
renderer.physicallyCorrectLights = true;
console.log("createRenderer");
return renderer;
}
export { createRenderer };
You’ve defined scene
in one file but appear to be using it in another file, that’s probably a mistake. You’re also calling renderer.render(...)
in both files? An editor like VSCode or similar should be able to highlight cases where variables are used but not defined, there seem to be a few here.