diff --git a/src/renderers/common/Bindings.js b/src/renderers/common/Bindings.js index f296ef62b7ae52..d6c16863e372fa 100644 --- a/src/renderers/common/Bindings.js +++ b/src/renderers/common/Bindings.js @@ -265,6 +265,10 @@ class Bindings extends DataMap { binding.release(); + } else if ( binding.isSampler ) { + + binding.release(); + } } diff --git a/src/renderers/common/RenderObject.js b/src/renderers/common/RenderObject.js index f5a8db798ea18a..0d732bdeb46d6c 100644 --- a/src/renderers/common/RenderObject.js +++ b/src/renderers/common/RenderObject.js @@ -281,6 +281,16 @@ class RenderObject { */ this._monitor = null; + /** + * The object's original material when this render object is drawn with an + * override material. + * + * @type {?Material} + * @private + * @default null + */ + this._sourceMaterial = renderer._currentSourceMaterial; + /** * An event listener which is defined by `RenderObjects`. It performs * clean up tasks when `dispose()` on this render object. @@ -328,6 +338,12 @@ class RenderObject { this.material.addEventListener( 'dispose', this.onMaterialDispose ); this.geometry.addEventListener( 'dispose', this.onGeometryDispose ); + if ( this._sourceMaterial !== null ) { + + this._sourceMaterial.addEventListener( 'dispose', this.onMaterialDispose ); + + } + } /** @@ -923,6 +939,12 @@ class RenderObject { this.material.removeEventListener( 'dispose', this.onMaterialDispose ); this.geometry.removeEventListener( 'dispose', this.onGeometryDispose ); + if ( this._sourceMaterial !== null ) { + + this._sourceMaterial.removeEventListener( 'dispose', this.onMaterialDispose ); + + } + this.onDispose(); } diff --git a/src/renderers/common/Renderer.js b/src/renderers/common/Renderer.js index 69437e5cf16aa7..0fc0b0ebebae83 100644 --- a/src/renderers/common/Renderer.js +++ b/src/renderers/common/Renderer.js @@ -661,6 +661,16 @@ class Renderer { */ this._compilationPromises = null; + /** + * When an override material is in use, this property points to the current + * source material during the rendering of a render object. + * + * @private + * @type {?Material} + * @default null + */ + this._currentSourceMaterial = null; + /** * Whether the renderer should render transparent render objects or not. * @@ -3483,6 +3493,8 @@ class Renderer { let materialPositionNode; let materialSide; + const previousSourceMaterial = this._currentSourceMaterial; + // object.onBeforeRender( this, scene, camera, geometry, material, group ); @@ -3491,6 +3503,8 @@ class Renderer { if ( material.allowOverride === true && scene.overrideMaterial !== null ) { + this._currentSourceMaterial = material; + const overrideMaterial = scene.overrideMaterial; materialOverride = true; @@ -3566,6 +3580,8 @@ class Renderer { } + this._currentSourceMaterial = previousSourceMaterial; + // object.onAfterRender( this, scene, camera, geometry, material, group ); diff --git a/src/renderers/common/Sampler.js b/src/renderers/common/Sampler.js index 9effaa408617b2..bcd88765c6a170 100644 --- a/src/renderers/common/Sampler.js +++ b/src/renderers/common/Sampler.js @@ -119,6 +119,15 @@ class Sampler extends Binding { } + /** + * Releases the texture reference. + */ + release() { + + this._texture = null; + + } + } export default Sampler; diff --git a/src/renderers/common/Textures.js b/src/renderers/common/Textures.js index 5288e4d8bb91e0..4c6479055dd3fe 100644 --- a/src/renderers/common/Textures.js +++ b/src/renderers/common/Textures.js @@ -626,6 +626,7 @@ class Textures extends DataMap { if ( binding.isSampler && binding.texture === texture ) { binding.reset(); + binding.release(); }