Virtual Worlds - from VRML to BabylonJS


I’m happy to present you some of the virtual worlds I made in 1998 with VRML now avaible with babylonjs framework.

website :

Example :

Floating islands

You can move with keyboard and look around with your mouse, use icons like camera to change view, fly or walk and use pannel to go from one world to another world.

I try to preserve as much as possible the geormetry/textures like it was before for memory, only two things are new : a forest made with thin instances in the city of trees, and particles for rain effect into the great hall. Otherwise you will see the virtual worlds as they were on that time.

I really enjoy to use BabylonJS, it’s nice and easy to get into it and thanks to all the videos, tutorials and topics on this forum I never feel lost. I want to thank you all for making such a great tool.

see you soon


Thanks for the walk down memory lane @deimos411 . I recall your inspiring art of that time very well.

1 Like

This is so interesting! I was 2 in 98, so it’s very cool to see how things were around back then. And I think these worlds still look pretty nice, because of the creativity and care I see were put into them. Thank you for showing us this piece of history!

1 Like

This is definitely huge for me !!! Having enjoyed VRML in the past !!!

I feel so old now ;D

1 Like

Msn gaming zone and age of empires …the glory days

1 Like

Thanks you a lot for your support messages :slightly_smiling_face:

1 Like

Awesome. I remember reading parts of a VRML book back in those days, but I never got around to actually making any projects with it. I really like the “City of trees” world that you created. It kind of reminds me of the Channelwood Age in Myst.

Very cool. It would be great to have a VRML/X3D importer, and I see there have been some attempts.

One approach may be to convert Viewpoints, Lights and Shapes (“assets”) to .babylon json. And then deal with runtime behaviour (event cascade, routing) separately, somehow, perhaps with observables.

A main problem is how to deal with DEF/USE, or multi-parenting. In VRML, a single node can appear multiple times in the scene graph, eg. it can have multiple parents. This is somewhat similar to cloning and instancing. But if any aspect of the original (not just geometry) is modified it affects all clones (because the clones are actually (links to) the original). Also, any type of node can be cloned.

Do you have any insight from porting how to translate DEF/USE and vrml events/routing to Babylon.js ? I understand that it may well be that any sufficiently generic solution is out of reach and it is in the end easiest to just recode manually.


The biggest issue is VRML prototypes and scripts, but I guess they can simply be ignored by any importer. However another issue is all the proprietary extensions that various vendors added over the years, so there’s a lot of VRML content in the wild containing non-standard nodes and fields.

Oh, and welcome to the community @andreasplesch !

1 Like

Thanks. Of course, protos in particular but also script nodes would be really hard but ignoring them is not the end of the world for a great start. Perhaps script nodes could be supported if the importer acts more like a code generator. Also, there would not be a high expectation that non-standard nodes could be supported.

Anyways, insights and experience from actual conversions could be really valuable to learn what kind of code patterns in BJS turn out to be good matches, for example for DEF/USE.

Thinking about Touchsensor, are BJS action triggers based on dom events ? When are triggers fired ? As soon as possible ? And when are actions/handlers called ? Right away after the trigger, or perhaps triggers are accumulated, for more deterministic timing ? Probably too early to even think about that.

Hi @andreasplesch,

Glad some people think about a vrml importer tool. Do you have also some project you made in vrml? I whish there was one when I start restoring my worlds. As I didn’t know yet well babylon format and almost forgot vrml one I didn’t try to make such a tool which can be quite complex.

As far as I remember my vrml file were generated by tool like Internet Space Builder or CosmoWorld, I didn’t make the vrml object directly inside the code, only some routing or scriptting and all the others things like models, texture mapping, object coordinate, cloning and so one are all made by visual editor. That’s why I dive quickly into Blender which have a babylon export as addon.

What I can say about DEF/USE is that if I want to have the same result of cloning in babylon export as vrml file have, in Blender I use Alt+D ( Duplicate Linked ) on an object to duplicate it. Shift+D will make a copy which is different.

For example the cloning of sheep in floating islands ( Sheep2 is a clone of Sheep )

VRML File :

DEF Sheep2 Transform { # children: 2
							translation 8.64301 11.7014 -1.32886
							rotation -9.78757e-008 1 1.02931e-006 2.72272
							scaleOrientation -0.314411 0.314406 -0.895709 1.6807
							scale 0.7093 1 0.999997
							children [
								USE Sheep
								Sound {
									minFront 100000
									maxFront 100000
									minBack 100000
									maxBack 100000
									source DEF _Audio1 AudioClip {
										url "01.wav"
								DEF _Touch1 TouchSensor {
							ROUTE _Touch1.touchTime TO _Audio1.startTime

And in babylon file sheep2 is inside an array of sheep called instances :

  "instances": [
          "name": "sheep2",
          "position": [
          "rotation": [
          "scaling": [
          "freezeWorldMatrix": false,
          "tags": "sheep",
          "checkCollisions": false,
          "pickable": true

As you see there was a touchSensor on vrml file who play directly the sound of sheep, but not on babylon one, I make the script outside in the javascript by looking at sheep tags

// sheeps
				let sheeps = scene.getMeshesByTags("sheep");
				for (sheep of sheeps) {
					sheep.isPickable = true;
					sheep.actionManager = new BABYLON.ActionManager(scene);
					sheep.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickTrigger, function () {									
						let ready = checkAudioContext();	

						if(ready) {

I don’t know yet too much about DOM events and the triggers, hope someone here can help you more on that part. If you have any question don’t hesitate, I will be happy to help.

If you need to compare vrml/babylon format on a project feel free to check original one : ( need to unzip it )
virtualworlds/islands/babylon at main · deimos411/virtualworlds · GitHub

Have a good day,

Hi @Deimos411,

Thanks you for your detailed response explaining your workflow which I will study.

Just reiterating, “Duplicate Linked” in Blender seems generate the instance. Instance refers to instances of a mesh in .babylon json. During loading this will probably generate a babylon instance rather than a clone. So this seems like a good way to do DEF/USE for Shapes (or Transforms with Shapes). For reuse of sounds it seems like it is necessary to code, or perhaps one could clone a Sound derived from the DEF sound node for any USE sound nodes.

It seems your original iles.wrl still plays well in freeWrl and also in x_ite, a pretty complete vrml player with proto support for the web:

Did you find a way to systematically deal with Inlines ?

I didn’t know about x_ite, it’s really impressive! Thank you for the link. I will try to use it so it will be possible to see the original vrml worlds without a plugin.

To go from vrml to babylon I use first Castle Engine to export vrml to x3d, then MeshLab to export into .obj and then Blender to export into babylon. Maybe not the fastest or optimised way to do. I’m sure there is an option in MeshLab to separate meshes on export options, but the result is that I start restoring a whole world as a single mesh.

So about the inlines, I have only one world using it it’s Savanna that I finish to restore last month where all animals where divided into two inlines, simple one and normal one for LOD purpose.

DEF Elephant Transform { # children: 11
		#translation -3.16244 6.61142 2.99789
		translation -3.16244 5.61142 2.99789
		rotation 3.31292e-017 -1 -2.31785e-017 2.51327
		scaleOrientation 0.908661 -0.295242 0.295242 1.66643
		scale 0.0172184 0.0169215 0.694444
		children [
				  LOD {
					   range 125 
					   level [ 
							  Inline {
									  url "objets/elephant/elephann.wrl"
							  Inline {
									  url "objets/elephant/elephans.wrl"

156 polygons vs 720
3 Ko vs 14 ko vrml file size
inline models : Index of /wrls/worlds/safari/objets

I didn’t use LOD of course today because the amount of polygons is fine, so everything is keep inside one blender file. I look in babylon format documentation and it’s seems there is not like an equivalent of vrml inline in babylon, so it’s mainly done outside of the file by loading objects via import mesh.

1 Like

Cool elephants ! Low poly models are still important, for example for mobile.

x-ite is great, and follows very closely the spec., also in terms of events and runtime. There is also x3dom which is more geared towards tight integration with a surrounding web page.

I am familiar with Castle and Meshlab. Castle will do a very good job converting to X3D, and Meshlab has support for a lot of nodes.

Looking more into .babylon, I realized that only ‘raw’ geometry is included. So all higher order geometries have to be triangulated which is what .obj has anyways.

This, among many other things, makes it more daunting to produce a direct x3d loader. MeshBuilder can do this for many X3D geometries, however. This means that it will easiest to build a Babylon scene using Babylon methods, and then perhaps serialize to .babylon.

Inlines can be perhaps accomplished roughly with SceneLoader.Append (with some consideration of keeping name scopes apart, perhaps just by a prefix, and no EXPORT/IMPORT).

Another issue is the LH Babylon coordinate system (which seems to introduce mathematical complications). But there is some support for dealing with RH meshes/animations/perhaps cameras.

Since the change of meaningful success of coming up with an importer is pretty low given the size of the task and very limited hours of dedication, patience, a lot of no-keyboard planning, and a way to compartmentalize concerns will be important. Luckily, BJS is fun to work with.

Given your workflow, it sounds like it will quite helpful to just be able to import Shapes with their Appearances (materials), with the correct Transforms. I think this may be an achievable goal, for the most used geometries (IFS, primitives, extrusions could be possible, some 2D).

As a first step, I produced an X3D default value transformer which fills in default values for all fields for any node which are not explicitly provided. For example, Box has a default size of ‘2 2 2’ in X3D.

Is x3d 3ds max? If so, then you could use the exporters here to export from 3ds max directly to. Babylon or. Glb

Every stage of a conversion process you can lose a little more.

If x3d is something else, nevermind.

Thanks, X3D is really old VRML, in an XML encoding, so something else. It is a large format, and has lot of runtime, dynamic aspects, using a declarative approach, quite different from game engines. But some things translate well, such as meshes and materials.

@deimos411 : Ahh, I remember the “City of Trees” world. Reminded me of the video game Myst.

VRML was where I started with 3D in the 1990s.

Stay Safe, gryff :slight_smile:


Hi @andreasplesch,

I will be curious to see the first steps of your importer when it’s done.