Hi there. Hoping someone might be able to assist. I am working on a static scene in Blender and I am trying to export it as a .gltf with textures into threeJS.
I am using Blender 2.8, the KhronosGroup GLTF exporter and threeJS r118. My current problems are threefold:
- I am unable to see any of the meshes that use image textures. They appear to be entirely transparent, and they are the only objects in the scene that are not displayed. All other non-image textured meshes seem to be displaying in threeJS.
- The wrought-iron headboard mesh, which does not even use an image texture, is also not visible in my threeJS scene. This mesh was created by bringing an SVG into Blender as a curve and then converting it to a mesh and solidifying it.
- The scene lighting in various viewers and in threeJS seems to be far too bright for what I have enabled, even without my HDRI environment texture in the background.
Below is the link to the folder containing my .gltf, .bin, image textures and .blend file, as well as my .html file containing my threeJS scene configuration (index.html):
And here is everything that I have tried in troubleshooting these issues thus far:
- Checked the .gltf, .bin and textures in https://gltf-viewer.donmccurdy.com/ - the textures are all displaying perfectly fine there
- Checked the .gltf, .bin and textures in https://sandbox.babylonjs.com/ - the textures are all displaying perfectly fine there
- Verified that all of the image textures are loading properly in the browser Network tab (no 404s)
- Verified that every material in Blender file is using PrincipledBSDF
- Verified that all meshes in Blender file had UV maps attached
- Verified that all meshes have their normals facing in the correct direction (I checked this using the Face Orientation and Backface Culling settings)
- Verified that all mesh textures (minus the window glass) did not have 0 set for their Alpha properties
- Verified that all mesh textures images were saved as either .JPG or .PNG and are sized to a power of 2
- Verified that all modifiers have been applied prior to/during the export process
- Verified that my export included UVs, Normals, Tangents, Vertex Colors, etc.
- Verified that the headboard mesh was converted to an actual mesh from its original curve (I didn’t rename it, so it is still labeled “curve”, but it was indeed converted).
- Went through and removed any orphan materials/textures/meshes
- Tried removing some of the Gamma nodes from my PrincipledBSDF materials in the Shader editor
- Enabled “physicallyCorrectLights” and sRGBE output encoding on my threeJS renderer
Now, in my threeJS scene, I am seeing some console errors that I think may be of relevance here. But I am still fairly new to debugging .gltf files, and after days of Googling and browsing these forums, I am still not sure where to begin in debugging these particular errors: “THREE.WebGLProgram: Unsupported encoding: undefined” and “Uncaught TypeError: Cannot read property ‘elements’ of undefined”.
Meanwhile, in the McCurdy GLTF viewer, I am able to see all of the image textures as intended, but I am also seeing quite a few ominous error messages there as well (eg. “UNUSED_OBJECT”, “ACCESSOR_VECTOR3_NON_UNIT”, “ACCESSOR_INDEX_TRIANGLE_DEGENERATE”). Again, I am newer to importing from Blender to threeJS and am uncertain how to go about addressing these types of errors.
Two additional questions:
- Any way to get this working with all of the textures embedded in the .gltf vs. using the .gltf + .bin + textures combo? Or should I continue to keep these separated?
- Is 200mb unusually large for a static scene like this? I have gone through optimized the image textures and re-meshed most of the pillows which has helped greatly in reducing vertice and face counts, but it still seems much too large for a single scene file with no animations.
I have gone through as much of the documentation as I could, but am clearly still doing something incorrect here or have overlooked something. So any guidance you can provide is immensely appreciated!
The main problem (why the textures aren’t appearing) is that you have multiple versions of three.js mixed on the page. It’s always best to get all three.js library files, including loaders and controls, from the same place. Not doing so can cause weird issues, although this is definitely the weirdest I’ve seen caused by it.
Replace all of the script imports with ones from a single source, like jsdelivr:
Is 200mb unusually large for a static scene like this?
Yes, with enough work I think you could create almost exactly the same scene with less than 10mb of data. The textures are the main problem. I think I would start by resizing them all to 2K or less, instead of 4K, and then optimize them with something like https://squoosh.app/. A few, like
None_normal.png, are especially big — it’s 25 MB and 4096x4096 pixels, but only covers about a 100x100px area on screen. You want a little extra detail if the user can move around, of course, but that’s the kind of thing to look for.
Also — thank you for providing the extra details on things you tried while troubleshooting this.
It’s also important to remember that png files go to the GPU uncompressed. So if you have 200MB of PNG files, that could translate to like, 3.2 GB of raw data on the GPU. I can almost imagine that running against memory limits placed by the browser, even if you’re running that on a RTX 2080 TI. I know Chrome limits me to about 1GB of memory in JS, but that’s JS memory, not Web GL memory. I don’t know what the limits are for that. However, you typically don’t need super high resolution images to get great effects. You can get plenty of quality from simple 256x256 and 512x512 images for most things. For download times, you might also check out the WebP format, which, depending on your file could be a bit smaller. Alternatively, if you’re really adventurous, there is the brand new BASIS image format, which I’ve read has the advantage over PNG that it’s not only compressed to download, but is also compressed on the GPU, so you’ll use less memory. However, so far, I’ve found the compression artifacts to be too extreme to be worth it to me, personally. Future versions have lossless compression, however, which I personally feel would be worth a second a look.
Oh geez, of course! Thank you so much for catching that. Hah, I figured it would end up being something colossally goofy on my part, totally overlooking that my scripts were hodge-podged. I’m glad that was an easy fix.
So the textured objects seem to be loading and visible in my scene now, but I am still noticing the overexposure issue with the lighting. Any thoughts there? Should I play around with my renderer settings in threeJS or is it more likely the world envt. settings in Blender? I thought I had removed the ambient lighting from the world, but it does still appear gray in the .blend file, so perhaps I need to revisit that.
Should I additionally be concerned about any of the warnings that appear in the GLTF viewer? They sound kind of bad , but if everything is loading OK perhaps it is still fine?
And thank you both for the additional information on the file size and texture optimizations as well! Now that I’m looking back at the images, I’m not even sure where I am using None_normal.png, but you’re right – it is massive. I can get rid of that and crunch down all of the rest. That is all immensely helpful and will save me a lot of MBs.
None of the errors seem too bad. Deleting unused UV sets would reduce the file size a little (maybe 1MB?) but not a lot, so I wouldn’t worry about it. Some viewers (like Facebook’s old 3D Posts) required stricter validation, in which case you would need to take time to fix these. Blender has a Recalculate Normals feature that might fix the
ACCESSOR_VECTOR3_NON_UNIT issue — that’s the only thing here that’s really an error, the rest are just hints.
Either way. Personally I would probably just not export lights from Blender (you can disable the option on the exporter) and set up lighting in three.js.
Thanks, Don! That is good to know regarding the severity of the errors. And I appreciate the tip about the lighting – I will try swapping them out with threeJS lights.