Transparent objects in Three.js

Both your spheres are transparent, and are remaining so. What is happening is that the smaller sphere is not being rendered at all.

Transparency in WebGL is tricky. You can google the issue to find out more about it.

But you have stumbled upon an issue related to how three.js in particular handles transparency.

The WebGLRenderer in three.js sorts objects based upon their distance from the camera, and renders transparent objects in order from farthest to closest. (This is an important point: It sorts objects based on their position, and renders objects in the sorted order.)

So for two transparent objects to render correctly, the object that is in back — the smaller sphere in your case — must be rendered first. Otherwise, it will not be rendered at all, due to the depth buffer.

But in your case, you have two spheres that are in the same location, and hence are equidistant from the camera. That is the problem — which one to render first; it is a toss-up.

So you need to place the smaller sphere further away from the camera than the larger sphere in order for the scene to render correctly.

One solution is to move the smaller sphere back a little.

Another solution is to set renderer.sortObjects = false. Then the objects will render in the order they are added to the scene. In that case, be sure to add the smaller sphere to the scene first.

A third solution is to set material1.depthWrite = false and material2.depthWrite = false.

EDIT:

Renderable objects having material.transparent = false (opaque objects) are rendered before objects having material.transparent = true (transparent objects).

So a fourth solution is to make the smaller sphere opaque so it is rendered first.

New feature for r.71:

There is now an Object3D.renderOrder property. Within each class of object (opaque or transparent), objects are rendered in the order specified by object.renderOrder. The default value of renderOrder is 0. Note that renderOrder is not inherited by child objects; you must set it for each renderable object.

Objects with the same renderOrder (ties), are sorted by depth, as described above.

So a fifth solution is to set renderOrder = 1 for the larger sphere. This is likely the best solution in your case.

three.js r.71

Leave a Comment