vpenades / SharpGLTF

glTF reader and writer for .NET Standard
MIT License
467 stars 75 forks source link

How to disable buffer interleaving? #43

Closed wlinna closed 4 years ago

wlinna commented 4 years ago

Hello, is it possible to use separate buffers? In this issue it is said that

by default, sharpGLTF stores all vertex buffers in interleaved mode

, but I couldn't find an option to disable this default behavior. Setting WriteSettings.MergeBuffers = false didn't help

model.SaveGLB(saveFileName, new WriteSettings { MergeBuffers = false });

This isn't very urgent for us since our post-processing steps will write the final result with separate buffers anyway, but it would be nice to be able to skip that step for quick testing.

Thanks and good work!

vpenades commented 4 years ago

Model writing behaves differently depending on if you write to Binary GLB, or Json glTF.

In binary mode, by default all buffers are merged and embedded in the binary (it's required by glTF standard)

In json mode, Buffers are merged to a single .bin file if MergeBuffers is true, or written separately if MergeBuffers is false.

So if you want to save a model and write all its internal buffers as separate files, you should write to glTF instead of GLB, and keep MergeBuffers as false.

wlinna commented 4 years ago

That's not what I meant.

I wanted to disable interleaving, and trying MergeBuffers = false was merely a desperate attempt to do so.

vpenades commented 4 years ago

Okey, it's an entirely different thing. I understand you're refering to Strided Vertex Buffers.

By default, SharpGLTF is not able to change the internal layout of an existing gltf document. So if you want to load an existing glTF , and save it with a different vertex buffer layout, this is not possible, or at least, not possible in an easy way.

When you create a new scene with the Toolkit.SceneBuilder , at the end of the scene creation process, you convert the sceneBuilder to a gltf (schema2) model. The conversion from SceneBuilder to Schema2.ModelRoot has a settings structure SceneBuilderSchema2Settings with a UseStridedBuffers property that is set to true by default. If you set it to false, it will write the vertex attributes in separated vertex buffers. So Positions will go in one buffer, normals in another buffer, and so on.

It is also possible to convert from a Schema2.ModelRoot to a SceneBuilder, you can see a round trip example here

In that same example, I am disabling the creation of strided vertex buffers in this line:

https://github.com/vpenades/SharpGLTF/blob/f7fafa852b07737556a9985ab92fff56c4418f48/tests/SharpGLTF.Toolkit.Tests/Scenes/SceneBuilderTests.cs#L491

If you need to perform a roundtrip conversion, that is, load a glTF, convert it to a SceneBuilder, and then convert it back to a glTF, you need to be aware that although I did my best to make the conversion as faithful as possible, it's not a feature that's been throughfully tested. So feel free to report any bugs you may encounter.