makc3d
August 29, 2021, 12:42pm
1
So far I see there were some threads from 2017-2018 where this seemed to work out of the box in some jsfiddle, but today I am getting a ton of errors in three.js (r109, so 2019 actually, lol) when it tries to retrieve non-existing entry from buffers WeakMap after context is restored. I tried this:
renderer.domElement.addEventListener( 'webglcontextrestored', function( event ) {
const updateMaterial = function( material ) {
material.needsUpdate = true;
for( var key in material ) if( material[key] && material[key].isTexture ) {
material[key].needsUpdate = true;
}
};
scene.traverse( function( object ) {
if( object.geometry ) {
for(var key in object.geometry.attributes) {
object.geometry.attributes[key].needsUpdate = true;
}
if( object.geometry.index ) {
object.geometry.index.needsUpdate = true;
}
}
if( object.material ) {
if( object.material.length ) {
object.material.forEach( updateMaterial );
} else {
updateMaterial( object.material );
}
}
});
scene.backgound.needsUpdate = true;
});
but it did not do anything useful. Does anyone have a working snippet for this?
1 Like
In console was only one error. I added try/catch at scene.backgound.needsUpdate = true;
const updateMaterial = function( material ) {
material.needsUpdate = true;
for( var key in material ) if( material[key] && material[key].isTexture ) {
material[key].needsUpdate = true;
}
};
scene.traverse( function( object ) {
if( object.geometry ) {
for(var key in object.geometry.attributes) {
object.geometry.attributes[key].needsUpdate = true;
}
if( object.geometry.index ) {
object.geometry.index.needsUpdate = true;
}
}
if( object.material ) {
if( object.material.length ) {
object.material.forEach( updateMaterial );
} else {
updateMaterial( object.material );
}
}
});
try{
scene.backgound.needsUpdate = true;
}
catch(e){}
makc3d
August 29, 2021, 1:25pm
3
I guess you dont have a texture in there, but the point is, this whole thing does not do anything, and I think it should not too.
Have textures. Version is 132dev. I checking just puting into console:
const updateMaterial = function( material ) {
.........
try{
scene.backgound.needsUpdate = true;
}
catch(e){}
makc3d
August 29, 2021, 1:47pm
5
no, no, try this:
ext = renderer.context.getExtension('WEBGL_lose_context')
ext.loseContext()
and then few seconds later
ext.restoreContext()
Error was:
Changed to
var ext = renderer.getContext().getExtension('WEBGL_lose_context');
Its working. Full code:
renderer.domElement.addEventListener( 'webglcontextrestored', function( event ) {
const updateMaterial = function( material ) {
material.needsUpdate = true;
for( var key in material ) if( material[key] && material[key].isTexture ) {
material[key].needsUpdate = true;
}
};
scene.traverse( function( object ) {
if( object.geometry ) {
for(var key in object.geometry.attributes) {
object.geometry.attributes[key].needsUpdate = true;
}
if( object.geometry.index ) {
object.geometry.index.needsUpdate = true;
}
}
if( object.material ) {
if( object.material.length ) {
object.material.forEach( updateMaterial );
} else {
updateMaterial( object.material );
}
}
});
try{
scene.backgound.needsUpdate = true;
}
catch(e){}
});
var ext=renderer.getContext().getExtension('WEBGL_lose_context');
ext.loseContext();
setTimeout("ext.restoreContext();",5000);
makc3d
August 29, 2021, 2:30pm
8
if that is working for you, you should be able to comment out everything in
addEventListener and it will still work, no?
I put into console changed code and ok.
var ext=renderer.getContext().getExtension('WEBGL_lose_context');
ext.loseContext();
setTimeout("ext.restoreContext();",5000);
renderer.domElement.addEventListener( 'webglcontextrestored', function( event ) {
const updateMaterial = function( material ) {
material.needsUpdate = true;
for( var key in material ) if( material[key] && material[key].isTexture ) {
material[key].needsUpdate = true;
}
};
scene.traverse( function( object ) {
if( object.geometry ) {
for(var key in object.geometry.attributes) {
object.geometry.attributes[key].needsUpdate = true;
}
if( object.geometry.index ) {
object.geometry.index.needsUpdate = true;
}
}
if( object.material ) {
if( object.material.length ) {
object.material.forEach( updateMaterial );
} else {
updateMaterial( object.material );
}
}
});
try{
scene.backgound.needsUpdate = true;
}
catch(e){}
});
makc3d
August 29, 2021, 3:27pm
10
so… discussing a similar issue on github Ive found that my browser is now working differently from how it did 4 years ago, so Im going to assume it is broken and confirm on another machine
1 Like
makc3d
August 29, 2021, 4:23pm
11
turns out this issue is unrelated, and happens under different os/browser any way… as soon as it tries to render a shadow map of some mesh, it cant find the buffer for its geometry.index
for now I will give up on debugging this and just stick with
renderer.domElement.addEventListener( 'webglcontextlost', function() {
location.reload();
});