xeokit / xeokit-sdk

Open source JavaScript SDK for viewing high-detail, full-precision 3D BIM and AEC models in the Web browser.
https://xeokit.io
Other
718 stars 285 forks source link

How to handle tranparency and rendering order? #1525

Closed lzoia-bc closed 3 months ago

lzoia-bc commented 3 months ago

In the documentation is not clear how to proper handle transparency and rendering order between XKT models and other elements.

Is quite common in our application to load inside the viewer a XKT file using the XKTLoaderPlugin and add some other 3D elements using the SceneModel approach to take advantage of the Geometry Instancing. Currently the XKT files is loaded with the edges and the xrayed property set to true. If the SceneModel meshes have no opacity set everything works as expected. But when I need to place an element with opacity that element covers the XKT model. Is there a way to handle by code the rendering order of 3D elements ?

I'll post here a screenshot of the problem for reference: image

The blu elements have no opacity while the box has an opacity of 0.4

xeolabs commented 3 months ago

In xeokit, all objects are partitioned into opaque and translucent bins within the renderer, and there is no control over the order in which the transparent objects are rendered.

This becomes a problem when near objects happen to be rendered earlier than distant objects, ie. when the near objects obscure the distant objects. Due to the way that the WebGL z-buffer works, this means that the pixels for the distant objects will not be rendered for the distant objects when they have already been rendered for the near, obscuring objects. It sometimes makes things disappear from view, when viewed from certain angles, or 50% of the time when transparent objects are nested inside each other.

We opted not to implement order-independent-rendering, because it impacts on rendering performance, which is our priority, and so far it's been a tolerable glitch for most building models.

However, if users want to explicitly control the order in which objects are rendered, say to make a certain object always get rendered last, for example, we could add something equivalent to the CSS z-index property to each object in the viewer.

These z-index values could be programmatically set on Entity, Mesh, Node and SceneModel components, and also could be associated via a lookup table with IFC types.

Does this sounds like it might solve your use case?

lzoia-bc commented 3 months ago

Yes it should solve the problem. In that way I can put the xkt file always on top of the other transparent objects. Thanks a lot. Is this a complex change ? Do you have an estimation ?

xeolabs commented 3 months ago

Not a complex change - although, using the strategy in mind, a caveat would be to keep the number of distinct values for z-index (or whatever the name will be) to a minimum, since it will directly increase the number of rendering bins (ie. draw calls) created by the renderer.

If you're assigning a z-index to an entire model loaded from XKT, however, that's going to have a low impact on performance though, so not likely an impact for your use case.

We'll get this in this week.