Skip to content

Disposing scene background texture does not remove the geometry #26897

@fromtheghost

Description

@fromtheghost

Description

When a scene background is set to a Texture, /src/renderers/webgl/WebGLBackground.js creates a mesh:

planeMesh = new Mesh(
	new PlaneGeometry( 2, 2 ),
	new ShaderMaterial( {
		name: 'BackgroundMaterial',
		uniforms: cloneUniforms( ShaderLib.background.uniforms ),
		vertexShader: ShaderLib.background.vertexShader,
		fragmentShader: ShaderLib.background.fragmentShader,
		side: FrontSide,
		depthTest: false,
		depthWrite: false,
		fog: false
	} )
);

However there doesn't seem to be any way to dispose of that PlaneGeometry. Calling scene.background.dispose() only disposes of the Texture.

Here's an example: https://codesandbox.io/s/still-voice-zwrpsn?file=/src/index.mjs

The scene has a cube and a background texture. When you execute dispose() in the gui, you are still left with 1 geometry hanging around.

Reproduction steps

  1. Create a scene and set scene.background to a Texture.
  2. Check renderer.info.memory and verify there is 1 geometry and 1 texture.
  3. Call scene.background.dispose() and see that there is still 1 geometry in memory.

Code

import * as THREE from "three";
import GUI from "lil-gui";

// Set up the scene, camera, and renderer
const scene = new THREE.Scene();
const backgroundTexture = new THREE.TextureLoader().load(
	"https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/textures/water.jpg"
);
scene.background = backgroundTexture;
const camera = new THREE.PerspectiveCamera(
	75,
	window.innerWidth / window.innerHeight,
	0.1,
	1000
);
camera.position.z = 5;

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// Create a cube with a material that uses an envMap
const geometry = new THREE.BoxGeometry();

const material = new THREE.MeshNormalMaterial();
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

// Add a resize listener to update camera aspect ratio and renderer size
window.addEventListener("resize", function () {
	const newWidth = window.innerWidth;
	const newHeight = window.innerHeight;
	camera.aspect = newWidth / newHeight;
	camera.updateProjectionMatrix();
	renderer.setSize(newWidth, newHeight);
});

const panel = document.createElement("div");
//absolute top left position
panel.style.position = "absolute";
panel.style.top = "0px";
panel.style.left = "0px";
panel.style.backgroundColor = "black";
panel.style.padding = "5px";
panel.style.color = "white";
//add panel to document
document.body.appendChild(panel);

panel.update = () => {
	//show the renderer.info.memory stats
	panel.innerHTML = JSON.stringify(renderer.info.memory, null, 2);
};

// Render the scene
function animate() {
	requestAnimationFrame(animate);
	cube.rotation.x += 0.01;
	cube.rotation.y += 0.01;
	renderer.render(scene, camera);
	panel.update();
}
animate();

const gui = new GUI();
const guiObject = {
	dispose: () => {
		material.dispose();
		geometry.dispose();
		scene.background = null;
		backgroundTexture.dispose();
		scene.remove(cube);
	},
};

gui.add(guiObject, "dispose");

Live example

Screenshots

No response

Version

r157

Device

No response

Browser

No response

OS

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions