Page MenuHomePhabricator

STL files are rendered incorrectly by the media viewer 3D extension
Closed, ResolvedPublicBUG REPORT

Assigned To
Authored By
Carsten_Steger
Feb 6 2026, 5:53 PM
Referenced Files
F71728522: image.png
Feb 7 2026, 2:08 PM
F71710306: image.png
Feb 6 2026, 6:11 PM
F71710284: image.png
Feb 6 2026, 6:10 PM
F71709985: image.png
Feb 6 2026, 5:53 PM

Description

I have recently uploaded the file https://commons.wikimedia.org/wiki/File:5-Cell_Schlegel_Diagram.stl to Wikimedia Commons. All the previews have been rendered correctly. However, when I display the file in the media viewer, it is rendered incorrectly: basically, the entire object is displayed in pure white, as if the object was completely overexposed. The display problem occurs under Windows, Linux, macOS, and iOS with Internet Explorer, Firefox and Safari.

When checking different STL files, I noticed that the following files have the same problem:

On the other hand, the STL file https://commons.wikimedia.org/wiki/File:Sphericon.stl is displayed completely in dark gray (which seems to be the ambient color).

I also noted that the preview rendering with 3d2png worked correctly for all of the above files. Therefore, I suspect that there is a bug in the 3D extension of the media viewer.

Steps to replicate the issue:

  • Go to any of the Wikimedia Commons links I have included above.
  • Look at the PNG preview bitmap: it was created correctly in all cases.
  • Display the STL file by clicking into the preview image.

What happens?:

  • The STL file is displayed incorrectly, either much too bright or much too dark.

What should have happened instead?:

  • The STL file should have been displayed as in the preview image rendered with 3d2png.

Software version (on Special:Version page; skip for WMF-hosted wikis like Wikipedia):

  • MediaWiki 1.46.0-wmf.14 (b7744a2) 14:01, 6 February 2026
  • MultimediaViewer – (59f7c50) 18:54, 30 January 2026
  • 3D0.0.1 (dbc9cb3) 01:39, 22 January 2026

**Screenshot of the 3D extension when rendering https://commons.wikimedia.org/wiki/File:5-Cell_Schlegel_Diagram.stl:

image.png (1,655×1,565 px, 118 KB)

Details

Event Timeline

When looking at the current versions of the code:

the first thing that strikes me is that 3d2png.js and mmv3d.js use completely different intensities for the lights they place in the scene.

  • 3d2png:

this.camera.add( new THREE.PointLight( 0xffffff, 0.3 ) );
this.scene.add( new THREE.AmbientLight( 0x666666, 0.5 ) );
light = new THREE.SpotLight( 0x999999, 1 );

  • mmv3d.js:

const headlight = new THREE.PointLight( 0xffffff, 150 );
this.scene.add( new THREE.AmbientLight( 0x666666, 2 ) );
const light = new THREE.SpotLight( 0x999999, 100000 );

The point light in mmv3d is 500 times brighter than that in 3d2png, the ambient light 4 times, and the spot light a whopping 100,000 times. What is the reason for these enormous differences?

Please excuse me for asking what probably is a newbie question: is there a way to test the 3D extension (and any modifications I would like to test) in a standalone manner locally in a browser without having to install a large amount of software?

One observation: when I rotate https://commons.wikimedia.org/wiki/File:Menger_sponge_2.stl in such a way that one of the cube faces is parallel to the image plane, one can see a little bit of shading on the faces that are parallel to the viewing direction. This would indicate to me that the headlight is much too bright.

image.png (1,654×1,563 px, 49 KB)

Another observation: the bounding box of https://commons.wikimedia.org/wiki/File:Sphericon.stl is [-1000:1000]³. I have not found that the geometry is scaled in any way after it has been loaded. Could one of the reasons for the fact that this model seems to be displayed only with the ambient illumination be that the spot light lies within the object?
const light = new THREE.SpotLight( 0x999999, 100000 );
light.position.set( -100, 50, 25 );
Could another reason be that the headlight is too far away from the object and is therefore attenuated to almost 0?

The problem is that the standard lighting system from Three.js is not used here. This differs greatly from previous versions and does not look quite as good for STL files. You can test this here: https://opendem.github.io/WikiMediaExtension3D_Test_GLB_Format/ The adjustments made by the WMF have now resulted in some models no longer displaying at all.

Change #1247633 had a related patch set uploaded (by Dmaza; author: Dmaza):

[mediawiki/extensions/3D@master] [WIP]

https://gerrit.wikimedia.org/r/1247633

dmaza changed the task status from Open to In Progress.Mar 6 2026, 4:07 PM
dmaza claimed this task.

@dmaza Thank you very much for your patch! I would love to test it, but don't know how I could do that. In any event, the code changes in your patch look very good to me. I have one suggestion that could be added to the patch because of your changes. Currently, mmv.3d.js contains the following call (line 45 with your patch applied):
this.camera = new THREE.PerspectiveCamera( 60, dimensions.ratio, 0.001, 500000 );
The huge z range of 0.001 to 500000 leads to a very inefficient use of the precision of the depth buffer. Since your patch scales the models to a much smaller depth range, at least the far value of 500000 of the frustum could be drastically reduced, which should result in better quality depth rendering.

@dmaza Thank you very much for your patch! I would love to test it, but don't know how I could do that. In any event, the code changes in your patch look very good to me. I have one suggestion that could be added to the patch because of your changes. Currently, mmv.3d.js contains the following call (line 45 with your patch applied):
this.camera = new THREE.PerspectiveCamera( 60, dimensions.ratio, 0.001, 500000 );
The huge z range of 0.001 to 500000 leads to a very inefficient use of the precision of the depth buffer. Since your patch scales the models to a much smaller depth range, at least the far value of 500000 of the frustum could be drastically reduced, which should result in better quality depth rendering.

Thank you for pointing that out. I've adjusted the far/near plane to more sensible defaults. I did see some z-fighting/actifacts in some models like this https://commons.wikimedia.org/wiki/File:Massospondylus_skull_BP-1-5241_3D_scan.stl#/media/File:Massospondylus_skull_BP-1-5241_3D_scan.stl but I wasn't sure what was causing it. It looks like this was the issue

As far as testing the changes, unfortunately the only way is to install a local copy of mediawiki and the 3D extension with it's dependencies.

As far as testing the changes, unfortunately the only way is to install a local copy of mediawiki and the 3D extension with it's dependencies.

@Carsten_Steger That's exactly why we created a simple HTML/JS Testviewer. I've added the latest adjustments here: https://opendem.github.io/WikiMediaExtension3D_Test_GLB_Format/stl_test_3_2026.html

The code is available on Github: https://github.com/OpenDEM/WikiMediaExtension3D_Test_GLB_Format
No build is necessary, only a local web server due to CORS issues.
I have added another critical .stl model.

@dmaza If you have time, please take a look at the code to see if I have taken all changes into account correctly. Visually, it looks the same, as far as I can tell.

Does this also work with external thumbnailers such as 3d2png?

Hmm, good question — I don't know. I just thought I'd mention it because it wasn't referred previously. :)

@OpenDEM Thank you for the link to https://opendem.github.io/WikiMediaExtension3D_Test_GLB_Format/stl_test_3_2026.html and for integrating the code changes there! I uploaded and tested my model 5-Cell_Schlegel_Diagram.stl there. The lighting much better with the code changes and my model is displayed correctly. Therefore, thank you all very much for the effort you have put into this patch!

When browsing through the predefined models on the above link, I noted that the brightness could be increased a little bit. The brightest gray values I got were around 210, so it seems that the brightness of the lights could be increased by 15-20%. This might create a more vivid impression of the models.

Also, what confused me at first is that the lights are attached to the scene, so the lighting remains static when you turn the object. Based on the interaction with the object that the MMV provides, my mental model was that I turn the object in front of my eye. Therefore, I would have expected the light sources to remain stationary relative to my view position. However, the mental model that seems to be behind the model is that you walk around the object, in which case the light position would remain stationary. This model wasn't the most intuitive to me. I know that the current lighting model is completely valid, too, so which one to might be a matter of preference.

One drawback of attaching the light to the scene might be that the orientation in which the model is defined in the STL file determines which parts are lit. For example, in the STL Ganesha Cologne Zoo file on the above link, the rear part of the statue is illuminated while the front part is partly in the shadows. This might make the interpretation of the 3D model somewhat more difficult and it somewhat obscures the more important part of the model. A similar problem occurs for the STL Lion Cologne Zoo model: its head is in the shadow. Mightn't it be better to attach the light sources to the camera instead of the scene instead to avoid this kind of behavior?

Hi @Carsten_Steger, Unfortunately, I'm not a three.js expert, but @donmccurdy is. I hope he can answer your questions.

Change #1247633 merged by jenkins-bot:

[mediawiki/extensions/3D@master] Improve scene lighting and normalize model scale

https://gerrit.wikimedia.org/r/1247633

Test wiki created on Patch demo by DMaza (WMF) using patch(es) linked to this task:
https://f903956008.catalyst.wmcloud.org/w/

As far as testing the changes, unfortunately the only way is to install a local copy of mediawiki and the 3D extension with it's dependencies.

@Carsten_Steger That's exactly why we created a simple HTML/JS Testviewer. I've added the latest adjustments here: https://opendem.github.io/WikiMediaExtension3D_Test_GLB_Format/stl_test_3_2026.html

The code is available on Github: https://github.com/OpenDEM/WikiMediaExtension3D_Test_GLB_Format
No build is necessary, only a local web server due to CORS issues.
I have added another critical .stl model.

@dmaza If you have time, please take a look at the code to see if I have taken all changes into account correctly. Visually, it looks the same, as far as I can tell.

Yes, I think so. Except for this line this.camera = new THREE.PerspectiveCamera(60, dimensions.ratio, 0.001, 500000);, near/far is now 0.5, 500

Wouldn't patch demo also be an option to test this?

You are right. Here it is https://f903956008.catalyst.wmcloud.org/w/. Sometimes it fails to load the models due to rate limiting (I think) but generally it works

Does this also work with external thumbnailers such as 3d2png?

Patch Demo does not support 3d2png unfortunately afaik

@OpenDEM Thank you for the link to https://opendem.github.io/WikiMediaExtension3D_Test_GLB_Format/stl_test_3_2026.html and for integrating the code changes there! I uploaded and tested my model 5-Cell_Schlegel_Diagram.stl there. The lighting much better with the code changes and my model is displayed correctly. Therefore, thank you all very much for the effort you have put into this patch!

When browsing through the predefined models on the above link, I noted that the brightness could be increased a little bit. The brightest gray values I got were around 210, so it seems that the brightness of the lights could be increased by 15-20%. This might create a more vivid impression of the models.

Also, what confused me at first is that the lights are attached to the scene, so the lighting remains static when you turn the object. Based on the interaction with the object that the MMV provides, my mental model was that I turn the object in front of my eye. Therefore, I would have expected the light sources to remain stationary relative to my view position. However, the mental model that seems to be behind the model is that you walk around the object, in which case the light position would remain stationary. This model wasn't the most intuitive to me. I know that the current lighting model is completely valid, too, so which one to might be a matter of preference.

One drawback of attaching the light to the scene might be that the orientation in which the model is defined in the STL file determines which parts are lit. For example, in the STL Ganesha Cologne Zoo file on the above link, the rear part of the statue is illuminated while the front part is partly in the shadows. This might make the interpretation of the 3D model somewhat more difficult and it somewhat obscures the more important part of the model. A similar problem occurs for the STL Lion Cologne Zoo model: its head is in the shadow. Mightn't it be better to attach the light sources to the camera instead of the scene instead to avoid this kind of behavior?

Based on my limited knowledge, adding lights to the scene is the standard way to do it. We had a high intensity spotlight attached to the camera, and when it got too close to the object, it caused a 'blow out' effect and made everything flat and white. We could potentially play around with a dim spotlight, dynamic intensity, offset and other properties depending on the distance to the object and bounding sphere radius, but it feels like complicating things since the goal is to move to RoomEnvironment anyway.

@dmaza Thank you very much for setting up the Patch Demo instance! I have tested the patch there and it worked very well. Thank you for fixing the problem!

Based on my limited knowledge, adding lights to the scene is the standard way to do it. We had a high intensity spotlight attached to the camera, and when it got too close to the object, it caused a 'blow out' effect and made everything flat and white. We could potentially play around with a dim spotlight, dynamic intensity, offset and other properties depending on the distance to the object and bounding sphere radius, but it feels like complicating things since the goal is to move to RoomEnvironment anyway.

The problem was caused by a combination of two things:

  • the fact that a spotlight was used and
  • the fact that the model was not scaled to a certain size.

The intensity of spotlights is attenuated according to the distance of a point on the surface of the object to the spotlight's position: objects that are farther from the spotlight's position appear dimmer. The second effect was that the camera was moved to a position sufficiently far away from the object so that it was contained in the view frustum. Both effects taken together meant that the whole approach to illuminate the object was not invariant to the size of the object. If the object was very small, the camera was very close to the object, so the spotlight was attenuated too little and the brightness was much to high. If the object was in a certain size range (based on my observations with a radius of around 10), the lighting worked. It the object was larger, it appeared too dim because the spotlight was attenuated too much. If the size was larger still, the light source might even have been positioned inside the object, so that only the ambient light remained. All of this would also have happened if the light sources had been attached to the scene instead of the camera. Thanks to your change, the root causes have now been solved: directional lights are not attenuated based on the distance of the light source to the object (in effect, a directional light is infinitely far away from the scene). This alone would have solved the brightness problem. Scaling the object to a fixed size makes the rendering even better since the depth buffer precision can be used much better, which, as you have noted, reduces or eliminates z-fighting. Hence, your solution would work in both cases: if the light source is attached to the scene or to the camera.

In any event, if the goal is to move to a RoomEnvironment, these points may be moot.

Marking as resolved since models are no longer rendered "pure white"

Test wiki on Patch demo by DMaza (WMF) using patch(es) linked to this task was deleted:

https://f903956008.catalyst.wmcloud.org/w/