Babylon Viewer (v2)

Hey everyone - we are working on a new Babylon Viewer and are already publishing (to npmjs) preview packages. The aim of the Babylon Viewer is to make it dead simple to add a great model viewing experience to your app (web or native). Check out the blog post for more background, and the readme for steps to try it out! Note that “alpha/preview” means the API is not yet stable, but the implementation is intended to be production quality.

We’ll use this thread to give some more detail on the features we have in mind (organized by the design principles described in the blog post) along with an indication of which ones have been completed (we’ll keep it up-to-date!). Please share any thoughts you have directly in this thread in terms of what features from the list below are most important to you, and any features you think should be added!

Easy to Integrate

JavaScript layer that is framework agnostic (can be used with web frameworks like React or even with Babylon Native)
HTML Web Components / Custom Element layer for easy integration directly in HTML
Custom element manifest (for simpler integration when using tools like VSCode)
Provide a “configurator” tool with UI to help setup the viewer (including annotations), show a live preview, and provide code snippets
Other framework integrations, such as React (maybe)
Inspector support

Compact

Defer loading (via dynamic imports) loaders (e.g. gltf, obj, stl, splat), glTF extensions, and features (e.g. animation, audio, etc.) until they are needed.
Statically import only what is always needed
Tooling to help understand and improve bundle size
Automated tooling to detect size regressions

Flexible

Default UI (in HTML custom element) can be customized through CSS variables, parts, and slots.
Support all model formats and glTF extensions that are supported by Babylon.
Formally expose Babylon constructs like the Scene, AssetContainer, etc.
Support some form of usd/z (big maybe :slightly_smiling_face:)
Compatible with Babylon Native
Configurable camera auto orbit
Configurable animation auto play

Modern

Provide an ESM dist for direct usage in html
Support WebGPU (with snapshot rendering mode)
Use environment for IBL, otherwise fallback to standard lighting
Use environment for skybox
Allow skybox to be configured independent of environment
Support annotations
Support WebXR
Support QuickLook
Configurable shadows
Configurable tone mapping

Easy to Use

Viewer is accessible (keyboard interactions, screen readers, color contrast).
Default camera framing that takes into account animation
Interpolate/animate camera pose reset
Interpolate/animate camera for manual pose changes
Default UI for selecting, playing, and scrubbing animations
Default UI for loading progress
Default UI for material variants
Pause render loop by default when no animations are playing and camera is stationary
Pause render loop by default when the viewer canvas is not in view
Interaction hints
Gracefully handle page scrolling vs. camera orbit (for pointer input)
Full screen mode
Placeholder image (while loading)

15 Likes

I just had a thought: it would be great if the viewer could load a playground (URL param) in the background. This could be a way of configuring the viewer and applying the playground script to any user-loaded model. The viewer should have no code visibility but doesn’t stop people opening the playground. A great way to prototype and share?

1 Like

Great news!

I will update Babylon Viewer Wordpress plugin soon.
What is the best way to make it backwards compatible for the old content?
For example, how to deal with HTML syntax difference?

// Old Viewer
<babylon model="model.gltf"></babylon>
// New Viewer v2
 <babylon-viewer source="model.gltf"></babylon-viewer>
1 Like

Interesting idea! I think this might be better aligned with something like an embed button in the Playground though. Something that is easy to just drop into a web page and it gets the needed runtime bits from the Babylon CDN. I think this might work better because Playground scripts have certain assumptions, like the presence of the BABYLON UMD global, which doesn’t/can’t exist in the context of the Viewer since we want to optimize the bundle size and not include anything that is not used. Let me have a chat with @RaananW and see if Playground embeds is something we’ve ever thought about.

3 Likes

It wasn’t really possible to make the new Viewer backward compatible with the old Viewer and achieve the goals of the new Viewer. For example, a lot of the configuration syntax was based on Handlebars and while it might be possible to replicate with Web Components, I think it would be very “non-standard” and slow down rampup for new users.

I don’t know much about Wordpress plugins, but from a quick look at the plugin you linked, my impression is that Wordpress plugin is making the old Babylon Viewer directly available to use without any abstraction over top of it, is that right? If that is the case, then it might be easier to introduce a v2 of the Babylon Viewer WordPress plugin. Otherwise is it possible for your Wordpress plugin to support both, depending on the syntax used (e.g. <babylon /> vs. <babylon-viewer />)?

For core Babylon libraries, we try very hard to maintain back compat, but for the Viewer it didn’t seem practical. The hope was that the API surface area was small enough that it would be fairly painless for folks to migrate to the new one if it was beneficial for their use case.

3 Likes

I wonder if there could be an optional bridge which would allow to use the Viewer v2 without code changes (sometimes painful) on the existing pages.

Seems there shouldn’t be any problems with it on PHP level.

Still, there was the function BabylonViewer.InitTags("the-other-tag-name") - Babylon.js docs
Is it possible to do the same with the @customElement("babylon-viewer") ?

1 Like

It is “possible,” but I don’t think it is practical. The old viewer used the deprecated Handlebars OSS lib, which allowed attributes and child elements to be used interchangeably. For example, all these are equivalent:

<babylon camera.behaviors.auto-rotate="0" />

<babylon>
  <camera behaviors.auto-rotate="0" />
</babylon>

<babylon>
  <camera>
    <behaviors auto-rotate="0" />
  </camera>
</babylon>

This is not how Web Components Custom Elements work (WebAPI standard for custom elements). For Web Components, we would have to create custom elements for effectively every property, we’d have to enumerate every possible attribute permutation (e.g. camera, camera.behaviors, camera.behaviors.auto-rotate, behaviors.auto-rotate, auto-rotate) since Web Components requires attributes to be statically declared, and we probably could not make this work correctly with tooling (like Custom Element manifests which enable intellisense in tools like VS Code).

So unfortunately I don’t think it is possible for us to move the Viewer to modern web standards without breaking changes.

2 Likes

I created a small demo with Viewer v2 - https://codepen.io/eldinor/pen/NWQXrRp

What is the easy way to debug a scene with Inspector (like scene.debug="true" in the ‘old’ Viewer?
What is the way to display several viewers with different models at one page?
Would it be possible to assign clearColor with the help of HTML3DElement (without JS)?

2 Likes

My two cents - the playground is using UMD and requires the entire BABYLON namespace (including other packages like loaders, serializers, GUI and so on) to work, so it will need to be dealt with when embedding a playground. However, I am totally not against it :slight_smile:. Maybe when I finally get to the playground improvements and allow ES6 playgrounds? then it makes sense to allow embedding those in the new viewer’s architecture somehow.

1 Like

:heart_eyes_cat:

I created a small demo with Viewer v2

Awesome!

What is the easy way to debug a scene with Inspector (like scene.debug="true" in the ‘old’ Viewer?

There is not one right now, and honestly it wasn’t on the radar, but it’s a great idea and I will add it to the feature list at the start of the post!

What is the way to display several viewers with different models at one page?

Right now, just use multiple instances. They won’t share any resources (e.g. they will have their own engine instance). We may make it possible to share an engine instance or optimize multiple instances in some other way in the future, but no concrete plans right now.

Would it be possible to assign clearColor with the help of HTML3DElement (without JS)?

Yes for sure. I’ve hesitated on exposing it as an attribute because I’m not sure if it could/should somehow be driven by CSS (e.g. background-color), but for sure we will provide a way to do it.

I believe this is a very important feature.

So at the moment, as I presume, there is no way to do it without custom JS code, like in the old Viewer (where I could put as much <babylon> tags as needed and canvas and engine would be created automatically)?
(I am not sure that it is possible at all since all Viewer v2 instances will ask for the same <div id="canvasContainer" )

Here is the example of clearcolor property added to the Viewer HTML element - Viewer Local Development The parameter is passed as clearcolor="#CC646480"
Actually, it is already there in finalOptions.backgroundColor, just not exposed.

And the last question: how to bundle the viewer into minified js file like this?

So at the moment, as I presume, there is no way to do it without custom JS code, like in the old Viewer (where I could put as much <babylon> tags as needed and canvas and engine would be created automatically)?
(I am not sure that it is possible at all since all Viewer v2 instances will ask for the same <div id="canvasContainer" )

The Babylon Viewer uses a shadow dom via Web Components Custom Elements, which means any html elements being rendered within it are in a separate scope from the document, so a canvas with an id of canvasContainer is scoped to just that instance of the Babylon Viewer. Here is an example with two Babylon Viewers side by side:

Here is the example of clearcolor property added to the Viewer HTML element - Viewer Local Development The parameter is passed as clearcolor="#CC646480"
Actually, it is already there in finalOptions.backgroundColor , just not exposed.

Yep, it is there in the lower layer. The open question for me is whether in the HTML Element layer () there should be an explicit attribute, or it should come from the CSS background-color. Depends on what users expect (so would love your input!), and on what is technically practicle.

And the last question: how to bundle the viewer into minified js file like this?

Are you just asking how we create the minified ESM compatible bundle in the dist folder (the link you included)? If so, we are using Rollup, and you can see the rollup config here: Babylon.js/packages/public/@babylonjs/viewer-alpha/rollup.config.dist.esm.mjs at master · BabylonJS/Babylon.js · GitHub

That is great!

I am sure there should be an explicit attribute. CSS background-color or background-image better to use in usual way, to style the parent div. Here is the example of transparent clearColor and CSS background image at parent div - 1001 Minutes - BabylonPress

What are the steps to apply rollup.config.dist.esm.mjs in the packages/tools/viewer-alpha folder? Or, in other words, how to produce a minified ESM version from Babylon fork?

And the last thing which is very much needed to be exposed in the Viewer HTML element is the autorotation. There is a lot of cases where autorotation (by default) in not needed, and it will be a pain to turn it off with JS every time.

If I choose .babylon file as a source, I have the following error: “Error: No plugin or fallback for https://playground.babylonjs.com/scenes/dummy3.babylon


The same thing with .obj files.
I’ve heard from people who had read the readme file that “The Babylon Viewer supports all the formats that Babylon.js supports”…

Found another interesting case which I couldn’t repro in Pen.
There is a test page with 2 Viewer instances, and they work OK.
If I add to one of them engine="WebGPU" I have the next errors in the console:

Thanks for providing this insight and feedback, makes perfect sense! Created a PR to add a clear-color attribute here: Viewer: add clear-color attribute by ryantrem · Pull Request #15752 · BabylonJS/Babylon.js

This one will definitely be added, and probably soon.

Ah yes, when I wrote the blog post I forgot to mention this one. It is not currently supported but we have some work planned to allow the BabylonFileLoader to be easily imported dynamically. As soon as we get this done, we’ll bring in support for .babylon files to the Viewer.

I can’t repro any issues with .obj. You can see an example here:

This one is interesting! I don’t have an explanation, but thanks for letting us know!

That is great! Now the Viewer tuning and styling is much simpler.

Seems that my .obj issues were due to CORS. Tested .obj with .mtl files, all is OK.

Good news is that I tested the new Viewer v2 Wordpress plugin and it works :slight_smile: I’ll publish it soon, probably tomorrow.

And the funny thing is that inside my plugin files I found todo.md written 4 years ago with the point: “Add attributes for clearColor” :slight_smile:

2 Likes

Still I have another issue :slight_smile:
If you click on any of the viewers to interact at your Pen - https://codepen.io/ryantrem/pen/OJKvzeQ - there are visible black outlines on the borders (I believe it is due to some shadowDOM elements without outline:none).

1 Like

Would be nice to have the ability to assign background image while loading.
Here is quite old example with the ‘old’ Viewer - BabylonJS Viewer Progress Bar with Overlay Image