TransformNode to Matrix4 for CSS3D

Hey everyone, I’m working on converting a camera + mesh scene to a CSS3D setup (to control an iFrame as seen in this forum thread).

But I noticed Babylonjs is missing a convenience function to convert a TransformNode into a matrix4 value used by CSS3D. Any chance someone from the community could help us write a convenience function to help with this conversion?

This would convert the Transform, Rotation Quaternion, and Scale to the Matrix4 format used by CSS3D. That way we could set the Matrix4 string to the ‘style’ value of the HTMLElement.

Try using TransformNode.getWorldMatrix() and take a look for an example of how to convert the returned matrix to CSS3D. That playground has a CSS3DRenderer class in it with two functions, getCameraCSSMatrix and getObjectCSSMatrix, that convert matrixes to CSS3D format.


Yeah that’s the example I’m trying to fix. Check out the edited playground below…

Try changing the rotation of the object called ‘no name’ in the inspector.


—Not Working—
Rotating X & Y at the same time

My assumption is that the getWorldMatrix() function isn’t exactly what CSS3D needs (which makes sense for the issues we’re seeing in the demo). But we haven’t figured out the proper conversion yet.

For anyone that finds this thread in the future, the issue on my end are hard limitations of CSS3D, so we can’t work around them as far as I’ve seen.

Check out this amazing visualizer for Matrix4 manipulation for CSS3D. You’ll see that we can’t modify all three rotation Euler angles at the same time. And the RotateZ value cannot be modified within the Matrix4 directly (but there is a special RotateZ style you can set if you need it, but it’s not a single value directly editable within the Matrix4).


After further research, I think the limitations are still possible to workaround. Check out this CSS3D demo with threejs (Github Link), it has correct rotations for all three Euler angles (X,Y,Z) and can rotate all axis at the same time.

The CSS3DRenderer script in the playground I posted earlier was a port of this project from the Babylonjs community, so it’s entirely possible that there’s a simple problem with the code port that’s preventing it from operating equivalently.

I’m not seeing in the code where the object is rotating. It looks like the camera is moving around the object, which works the same way in the playground example with an ArcRotateCamera:

1 Like

I keep looking at this matrix and scratching my head …

	renderObject(object, scene, camera, cameraCSSMatrix ) {
        if (object instanceof CSS3DObject) {
            var style
			var objectMatrixWorld = object.getWorldMatrix().clone()
			var camMatrix = camera.getWorldMatrix()
			var innerMatrix = objectMatrixWorld.m

			// Set scaling
			const youtubeVideoWidth = 4.8
			const youtubeVideoHeight = 3.6

			innerMatrix[0] *= 0.01 / youtubeVideoWidth
			innerMatrix[2] *= -0.01 / youtubeVideoWidth
			innerMatrix[5] *= 0.01 / youtubeVideoHeight
            innerMatrix[6] *= -0.0155 / youtubeVideoHeight

			// Set position from camera
			innerMatrix[12] = -camMatrix.m[12] + object.position.x
			innerMatrix[13] = -camMatrix.m[13] + object.position.y
			innerMatrix[14] = camMatrix.m[14] - object.position.z
			innerMatrix[15] = camMatrix.m[15] * 0.00001

I can’t figure out where they’re coming from even after looking at the threejs demo.

@docEdub You are 100% correct, I posted that 3js example late at night and didn’t realize that, it’s just rotating the camera!

As for who came up with the matrix math or why it’s used, I’m not sure. I’ve been poking at it and using the Matrix4 visualizer to figure things out to try to get multi-axis rotation (and z-rotation) working properly.

@docEdub : I did locate another good CSS3D demo, that successfully has all three rotation axis working properly.

So from what I’m reading, the rotation system works properly if you avoid setting the Matrix4 directly and use the RotateX/Y/Z style functions instead.

1 Like

Found another hint that full rotation should work, and perhaps even with using the Matrix4 values directly set.

If we look at the original CSS3D example from Threejs, we can see that their Periodic Table demo has the ‘sphere’ demonstration, which as far as I can see, shows full rotation working on at least the X & Y euler angle axis at the same time.

So perhaps there’s something off about the original ported code between Threejs → Babylonjs? I’ll look into that first before attempting to move away from directly setting the Matrix4 values of the CSS3D transforms.

Blame the early Babylonians but I do not think they are on the new forum their wax tablets have internet problems


Funnily enough I actually did figure out where CSS3DRenderer came from, an engineer from a group called eMagix seems to be the earliest lead for the original Threejs code, from a link I saw at the top of the Threejs CSS3DRenderer class while looking into this rotation issue.

1 Like