I currently have 2 renderers with 2 cameras, each rendering the same scene. I have a type of object that is on a layer with one of the cameras, so it is only visible on one of the renderers. I would like to maintain this visibility level (only visible on one of the layers), but have it occlude other objects on both layers. Is there a way to do this? If possible, I would like to not have to make a clone of this object as they can be quite large.
I don’t know how this will suit your layer system, but generally, you can make an object invisible and occluding other objects via a combination of Object3D.renderOrder and Material.colorWrite.
The idea is to render this occlusive object before the other occluded objects (i.e. the value of .renderOrder for its mesh or whatever should be lower than the similar values for the objects you want to occlude) and set its material’s .colorWrite to false to make it invisible.
Logically, this would also mean that you’d have to replicate the object on the layer you want it to act as an invisible occlusion, but if someone else knows a way to avoid that, feel free to share it.
Other than that, are you sure that using layers and duplicate renderers / cameras is the only way to achieve what you want? I mean, you know best what you want to achieve, but toggling the Object3D.visible seems more efficient in terms of resources to me, although it comes with its own set of gotchas (like some of the other settings not acting on objects that are not being rendered at all).
P.S. Personally, in my current project, I just selectively .dispose() objects and recreate them to present different views / styles for the things in the scene, but this is probably not suited for larger and more time consuming objects / layouts.
I have a solution implemented like you describe (have a clone of the model loaded and on the other layer with colorWrite set to false and renderOrder to 0). However, my models are quite big so I would like to avoid cloning them, if possible.
Re: your second comment. For my use case, different cameras/renderers is optimal solution for what I’m trying to achieve. This is a fairly large project with many different components so I’m trying to stick with it for now. Also, the project is a few years old now and don’t want to change the setup too much.
Ah, I see - so you’re looking for an alternative to the .renderOrder / .colorWrite combo that doesn’t involve cloning. Hmm… unfortunately, I don’t know of another way, though other folks who know more than I do might chime in with an idea on that.
Yep, I understand - older and larger projects are difficult to go through them again and make bigger changes. Generally, if things already work out reasonably well, improvement is an option to consider, but not major changes in the project.
Oh, and no problem, I’m glad to help - sorry I couldn’t do more about it. I don’t use layers in my current project, but I used the .colorWrite approach and for my case it was enough.
“If you want some objects to render “on top”, or “in front”, one trick is to create two scenes – the first scene is your regular scene, and the second scene contains the objects that you want to have on top.
First, set
renderer.autoClear = false;
Then create two scenes
var scene = new THREE.Scene();
var scene2 = new THREE.Scene();
Add your objects to the first scene as usual, and add the objects you want to have “on top” to the second scene.
Then, in your render() function, do this:
renderer.clear();
renderer.render( scene, camera );
renderer.clearDepth();
renderer.render( scene2, camera );