.obj to .glb - big file size

Hey!!

Due to the change in some projects I have developed a small local tool for the conversion from .obj to .glb (materials are not considered).

Using THREE.OBJLoader I import an .obj and then export it to a .glb using the THREE.GLTFExporter.
This works fine so far.

But I could see that a ~200KB .obj becomes a ~400KB .glb.
If I convert this .obj with Blender I get a ~100KB .glb.

Unfortunately I cannot always reproduce this behaviour. For the most part the threejs exporter is worse than the one from Blender. I have already played with all options of the THREE.GLTFExporter, but could not find any significant changes.

I have a small starting point, but honestly I lack the experience. When I look at the .glb as a JS object, I can see that there are several ArrayBuffers, including an Int8Array and an int32Array. The int32Array has a much smaller size, but when creating the BLOB object for download the int8Array is apparently used.
The glb-JS object also shows me a bytelength of ~400KB, so I am probably wrong with this approach and just misunderstand.

Does anyone have experience with the exporter, or can help me in any other way?

I’m new to this forum, and hope I didn’t do anything wrong, but if I did, my post may be deleted at any time.

Thanks in advance!

I’ve already found out that most of it is due to the “buffer” attribute in the generated .glbs by the GLTFExporter. Here the content is a so-called “data:application/octet-stream;base64”.

The Blender Exporter produces a size of 147116Bytes, whereas I have 414912 Bytes with Three.

Hmm…

check if you have index on the geometry. if exported geometry is not indexed, it can easily be larger than obj.

1 Like

You can avoid getting a Data URI from GLTFExporter by using the {binary: true} option. This should save 20-30% of the size for binary data.

The exported Geometry is not forced to have indices. With indices it should be bigger, or?

I exported as .glb - so it`s set {binary: true}. Otherwise it would export as an .gltf - In my second post I exported as gltf, to get some human readable.

Not really, since without indices every vrtex is copied as many times as there are triangles using it. 5 triangles sharing the vertex would make (5 - 1) * 8 new numbers for positions + normals + uvs, for example. With index, it is only 4 extra numbers

I tried with the option: {forceIndices: true} and getting a even higher filesize, now ~450KB.

Probably because it is not de-duplicating vertices

Yep https://github.com/mrdoob/three.js/blob/aec286294515e5a4f60a00e7daf05fe1558e9aaa/examples/js/exporters/GLTFExporter.js#L1388-L1404 it is pretty dumb in this regard

The real problem is, of course, that OBJLoader destroys indices

Do you have an idea, how to fix that?
I already took a look into: https://github.com/mrdoob/three.js/issues/15649
and some magic like BufferGeometryUtils.mergeBufferGeometries - But have not been able to take advantage of it.

Is there any chance to load an .obj without destroying the indices?

Thanks for your help!

The thing is that qute often obj indices are not useable in 3js “as is”, and you need to rebuild the index - so they said, fck it, lets drop the indices. And who can blame them ) If you have tight control ovr your obj files, you could go on and use obj indices any way. But if not - that merge thing is the only way to go.

Okay… get it. Thanks!

Do you think, this is worth a try?

why not ask @Fyrestar ?

Good idea. I’ll just test it.

Thank you!!

And you are still seeing the data:application/octet-stream;base64 content in your .glb? That seems odd…

No, sorry i made this unclear.
In the .glb there is no “data:application/octet-stream;base64” - just when using binary: false.

I just made a test with binary false, to get some human readable in threejs and blender, to compare the differences. Wanted to point out, that the “buffer” attribute is much bigger in the threejs export then the one from blender.

well if he has duplicated data, his bin file/s will be large any way

anoher cheap option is to use draco. then it will take care of duplicates and compress it even more

I thought of that, too. Maybe the best solution.

Hell yes! It worked.

With @Fyrestar’s toIndexed() I could achieve a massive file reduction.

The .glb is now at about 100KB, even slightly smaller than the one generated by Blender.

Thanks guys!

2 Likes