while using three inspector i noticed if
parent = new THREE.Object3D();
parent.add(mesh1);
parent.add(mesh2);
parent.visible = false;
mesh1 and mesh 2 are still visible.
is this intended or bug?
I think this should work on CanvasRenderer and SVGRenderer but not on WebGLRenderer (yet).
We have been discussing this and for some reason we decided it was better like this. I already don't remember why.
That's why there is SceneUtils.showHierarchy to provide this functionality:
https://github.com/mrdoob/three.js/blob/master/src/extras/SceneUtils.js#L7
Just run into this issue recently. I add some sprites to an Object3D for grouping. By changing parent visibility or opacity I expect all children are affected, but apparently they are not. Really keen to know the reason behind :-)
seems like SceneUtils.showHierarchy 04a7ac496c115374b3a7714bdb9fe133c4a7c0f5 was added after c580473ff88fb271521ce0f757507d2679d4fdab
if for some technical problems it was difficult to do children visibility in webgl, perhaps it might be easier to do a workaround similar to something done in the render loop like updateMatrices()
for each child,
THREE.SceneUtils.traverseHierarchy( root, function( node ) { node.__visible = child.visible; } )
then inside webglRenderer instead of using .visible, it can retrieve the values of .__visible.
this way, we can keep the compatibility of how the scenegraph visibility is supposed to work?
wouldn't it be better to just add a method which updates all children visible property ??
Object3d.prototype.changeVisibility = function( visible, recursively ) {
this.visible = visible;
if(recursively){
for(var i = 0,il = this.children.length;i<il;i++){
this.children[i].changeVisibility(visible,recursively);
}
}
};
that seems to be what SceneUtils.showHierarchy is doing. This is not ideal because at times, you do not wish to overwrite your children visibility states when toggling the parent's.
example.
var basket = new THREE.Object3D();
var apple = new THREE.Object3D();
var bananas = new THREE.Object3D();
var oranges = new THREE.Object3D();
// hide apple and bananas
apple.visible = false;
oranges.visible = false;
render(); // display oranges
// hide basket
basket.visible = false;
render(); // shows nothing
// show basket = false;
render(); // show oranges
That's what basket.material.visible = false solves :)
hmm... i was thinking of this too, but my concerns are
Object3D for grouping)
- the material is being shared (eg. by 100 baskets) - good idea to create 100 separate materials?
Yeah that should be ok.
- there may not be any basket material (if its basket is an
Object3Dfor grouping)
Then that object won't be visible so no need to make it invisible, no?
So here's the explanation of the current situation...
I think the behaviour should be that if you set visible to false to an object, the object and all its children should go invisible. That's how it works in CanvasRenderer, SVGRenderer and all the renderers that get the list of objects to render out of Projector.
The reason WebGLRenderer doesn't work like this is because it handles way more objects and there is the concern that updating an array with the objects that need to be rendered every frame may decrease the performance considerably.
Basically, what Projector does every frame is parsing all the scene graph, and adding to an array all the visible objects that are in the frustum. This array gets cleaned every frame with objects.length = 0, which seemed to be the most performant approach back when I tested it. The benefits of this is that the ideal behaviour gets done for free and the code is also pretty clean.
On the other hand, WebGLRenderer does it's own scene graph parsing and for the invisible objects or objects outside the frustrum it sets some internal booleans (or just continue the loop) and also has some internal arrays in the Scene that only get updated when a new element gets added or removed...
__lights
__objects
__objectsAdded
__objectsRemoved
__webglFlares
__webglObjects
__webglObjectsImmediate
__webglSprites
So, I'm supposed to do some more performance tests some day, to see whether nowadays browsers still have a performance hit with updating arrays every frame or not and try see if WebGLRenderer could use Projector for the scene parsing instead.
If anyway wants to give it a go... :)
The showHierarchy method of THREE.SceneUtils works great but I expected this to be the default behavior.
FYI: I just upgraded to r52, but this appears to still be at large. I'm using traverseHierarchy, which is unexpected but fine, but it wipes the visibility state of children.
I see. This was closed at the time SceneUtils.traverseHierarchy was moved to object.traverse (a change I like btw). I figured the visibility issue was fixed at that time.
Yeah. We still need to find a good solution for this. But object.traverse should do the trick until then.
Yeah. We still need to find a good solution for this.
I can commit a good one.
uh?
In case it's not clear from the above: Setting visible on a parent now affects children also. (tested with r71)
yeh!
Hi everyone, not sure if this has already been clarified, but Im trying to set up an enclosed room with some soft lighting. I wanted to use area lights to achieve this but the light source is visible. Is there a way to keep the light emitting but hide the visibility of the light source itself? Any help would be greatly appreciated!
@jesseazueta please, don't post in old conversations with unrelated questions.