Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GLTFExporter #11951

Closed
76 of 87 tasks
fernandojsg opened this issue Aug 15, 2017 · 87 comments
Closed
76 of 87 tasks

GLTFExporter #11951

fernandojsg opened this issue Aug 15, 2017 · 87 comments

Comments

@fernandojsg
Copy link
Collaborator

fernandojsg commented Aug 15, 2017

I would like to use this issue to keep track of the GLTF2 exporter features. I've copied the initial list of features discussed on the PR #11917 and I'll keep updating the list as we progress in the implementation.

Features / TO-DO

  • Export options

    • trs to export TRS instead of matrix
    • input:
      • Single scene
      • Array of scenes
      • Single object
      • Array of objects
    • truncateDrawRange: force exporting just the attribute values defined by drawRange:
    • Non-index buffer geometry
    • Indexed buffer geometry
  • Include userData in extras?

  • Scenes

    • Support for multiple scenes
  • Nodes

    • Meshes
      • Primitive mode:
        • TRIANGLES
        • TRIANGLE_STRIP
        • TRIANGLE_SPAN
        • POINTS
        • LINES
        • LINE_STRIP
        • LINE_LOOP
      • Geometry types:
        • BufferGeometry
        • Geometry
      • Primitive attributes:
        • POSITION
        • NORMAL
        • TEXCOORD_0
        • TEXCOORD_1
        • COLOR_0
        • JOINTS_0
        • WEIGHTS_0
        • TANGENT
      • Multi-material meshes as primitives
    • Lights
    • Camera
    • Skin
  • Materials:

    • Ignore if default material is being used
    • Export as lines if material.wireframe === true
    • pbrMetallicRoughness for MeshStandardMaterial
      • Attributes:
        • baseColorFactor
        • metallicFactor
        • roughnessFactor
        • baseColorTexture: It's supported (material.map) but the texCoord is always set to 0.
      • doubleSided
      • KHR_material_unlit
  • Samplers

  • Images

    • uri using map.image.src
    • uri base64
    • bufferView
    • Deal with flipY images
    • Merge channels into one texture
  • Accessors

    • Use the same bufferView for the same componentType instead of creating a new one for each attribute (WIP @takahirox)
    • Support sparse?
    • Attributes:
      • bufferView
      • byteOffset: Currently it's using 0 always as I'm creating a new bufferView for each accessor.
      • componentType
      • count
      • max
      • min
      • type:
        • SCALAR
        • VEC2
        • VEC3
        • VEC4
  • BufferViews: Currently I'm creating a new bufferView for each Accessor, this should be fixed to use just one for these attributes that share the same componentType

    • Attributes:
      • buffer
      • byteOffset
      • byteLength
      • byteStride
      • target
  • Buffers: Currently I'm saving everything to a single buffer so it will be just one entry in the buffers array.

    • byteLength
    • uri
  • Animations

  • misc:

  • GLB

Example

Current demo:
image

Exported gltf loaded on @donmccurdy 's gltf viewer
image

GLTF: https://gist.github.com/fernandojsg/0e86638d81839708bcbb78ab67142640

@donmccurdy
Copy link
Collaborator

donmccurdy commented Aug 15, 2017

This is looking really good!

By the way, we are planning to remove THREE.GLTFLoader and rename GLTF2LoaderGLTFLoader sometime soon*. Might be a good idea to rename the exporter as GLTFExporter before r87 lands, to avoid any confusion and so there won't be a name change required between releases. Oops, I missed that you already named it that way.. carry on! 😆


* @mrdoob, any preference on when that should happen? IMO we could do this now, unless we want to keep GLTFLoader in r87 with just a deprecation warning, and remove it in r88?

@mrdoob
Copy link
Owner

mrdoob commented Aug 15, 2017

I think the sooner the better. As long as the new GLTFLoader is able to detect 1.0 and warn the user that we only support 2.0+.

@takahirox
Copy link
Collaborator

IIRC we can detect by seeing asset as I mentioned before.

@donmccurdy
Copy link
Collaborator

IIRC we can detect by seeing asset as I mentioned before.

✅ Yep! #11864

@takahirox
Copy link
Collaborator

Cool! But I've found a minor bug. I'm making PR now. Let's merge before we rename.

@fernandojsg fernandojsg changed the title GLTF2 Exporter GLTF Exporter Aug 16, 2017
@takahirox
Copy link
Collaborator

Can we specify the items that someone is working on in the checklist?

@fernandojsg
Copy link
Collaborator Author

@takahirox sure! people could just write comments here and I could update the list and point to a PR if there's something going on already

@fernandojsg
Copy link
Collaborator Author

The next thing I'll be working is on the textures, to convert them to base64 instead of using just the url

@takahirox
Copy link
Collaborator

Thanks! I wanna help making glTF exporter. I'm looking into what I can help in the checklist...

BTW have you purposely let two variables WEBGL_CONSTANTS and THREE_TO_WEBGL global?

@fernandojsg
Copy link
Collaborator Author

@takahirox cool!
Regarding the two variables, this is something I'm going to address in the following PR to make it part of the WebGLUtils and just import it. It doesn't make sense that each one that needs these constants need to redefine them again every time.

@fernandojsg
Copy link
Collaborator Author

@takahirox btw feel free to propose new items to the list of course! ;)

@takahirox
Copy link
Collaborator

@fernandojsg Sure! About the variables, I wanted to propose to move them to somewhere if they're purposely declared as global so it's nice to know that you do.

@takahirox
Copy link
Collaborator

I wanna work on shared buffer view.

BufferViews: Currently I'm creating a new bufferView for each Accessor, this should be fixed to use just one for these attributes that share the same componentType

The reason why one for the attributes that share the same componentType, not one for all the attributes, is for data alignment, correct?

https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#data-alignment

@fernandojsg
Copy link
Collaborator Author

Cool, I've just added you to the list 👍 Yep, basically you want to share the same buffer view for component with the same type, for example if you have position and normal you'll have two VEC3 accessors but they'll point to the same bufferview. That could be a great starting point ;)

@takahirox
Copy link
Collaborator

takahirox commented Aug 18, 2017

I meant, the reason why we don't let buffer view be shared among different componentType (ex: float and short) is to keep good data alignment, correct?

@fernandojsg
Copy link
Collaborator Author

I believe you can store in the same buffer view different component types as long as they've the same target, for example normal (Vec3), position (Vec3) and uv (Vec2) could be in the same buffer view but indices not. @donmccurdy could you confirm it?

@takahirox
Copy link
Collaborator

takahirox commented Aug 18, 2017

Yep, agreed. And as this glTF specification mentions

https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#data-alignment

The offset of an accessor into a bufferView (i.e., accessor.byteOffset) and the offset of an accessor into a buffer (i.e., accessor.byteOffset + bufferView.byteOffset) must be a multiple of the size of the accessor's component type.

It's a good idea that we separate buffer views between the different componentType(=data type like float and short, not vec2 or vec3) for the simplicity. If we separate them between different data length componentType, it'd be more optimized.

@takahirox
Copy link
Collaborator

BTW is there any special reasons why the current exporter supports only accessor.componentType float, uint, and ushort? glTF 2.0 can handle char, uchar, and short, in addition to them.

https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#accessorcomponenttype-white_check_mark

@fernandojsg
Copy link
Collaborator Author

@takahirox not really, I just defined these by now because are the ones used for the type of attributes we support right now (positions, normals, colors, uvs, indices..).
The next step I'm working on is the textures so there we'll need others like uchar for example

@takahirox
Copy link
Collaborator

takahirox commented Aug 18, 2017

OK, so I first will work on the accessor.componentTypes unless you already started to impl.

@takahirox
Copy link
Collaborator

takahirox commented Aug 19, 2017

Almost ready but my PR should conflict with #11978.
So I send mine once #11978 is merged and I fix the conflict.

@takahirox
Copy link
Collaborator

Would you add animation to the list?

@fernandojsg
Copy link
Collaborator Author

@takahirox sure, it could be great to add animation. I just didn't add it because I wasn't familiar enough with the current state of the animation features on three.js, but if you feel like taking over it, it would be great ;)

@marcatec
Copy link
Contributor

Do you plan to support BufferGeometry groups?
Do the GLTF specs cover that or would it result in creating a new Mesh for every group?
This must also take care of, the material property of a Mesh being an array of materials.

@donmccurdy
Copy link
Collaborator

@marcatec The glTF spec does have a "mesh" vs. "primitive" distinction that would allow you to create BufferGeometry groups that could each reference a different material. Currently THREE.GLTFLoader does not optimize loading primitives — it creates separate meshes — but that could be implemented.

@Friksel
Copy link

Friksel commented Nov 20, 2017

Great work, great list and good to know there is already so much support on the format! Also works very well together with gltf blender exporter too. Can't wait for lights support! Keep up the great work.

@homerjam
Copy link

I concur, great work!

Are there plans to add support for other materials apart from StandardMaterial?

Thanks!

@fernandojsg
Copy link
Collaborator Author

I've just noticed that the validator throws an error on every normal element on a bufferview that is not normalized. eg If I stored uninitialized values like [0,0,0] it will throw that error.
As it's a error and not a warning/notice I see it's sensitive to fix. What do you think about ensure the normal bufferview elements are normalized? Even so, for values that can't be normalized such as [0,0,0], should we use a valid unit vector? /cc @donmccurdy

@takahirox
Copy link
Collaborator

takahirox commented Mar 25, 2018

Seems like NORMAL should be normalized.

https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#meshes

NORMAL | "VEC3" | 5126 (FLOAT) | Normalized XYZ vertex normals

Agreed with ensuring because Three.js normal doesn't have such a limitation.

@fernandojsg
Copy link
Collaborator Author

Yep, but what to do when you don't have an actual normal, like an unused value of [0,0,0], just create a valid one and that's all right? let's say [1,0,0]. So we should modify the bufferview code to detect that we're parsing a normal attribute and normalize each one before saving it to the dataview.

@takahirox
Copy link
Collaborator

takahirox commented Mar 25, 2018

what to do when you don't have an actual normal, like an unused value of [0,0,0]

Hm.... replacing with a valid one and displaying warning?

So we should modify the bufferview code to detect that we're parsing a normal attribute and normalize each one before saving it to the dataview.

I prefer doing that in processMesh() because it'd be simpler, like

var originalNormal = geometry.attributes.normal;

if ( hasNonNormalizedValues( originalNormal ) ) {

    geometry.attributes.normal = createNormalizedAttribute( originalNormal );

}

processAccessorHere();

geometry.attributes.normal = originalNormal;

If we do that in processBufferView(), the code would become a bit complex because we need to care if data is shared among different attributes, for example position and normal. (I know it's very rare use case but Three.js doesn't restrict.)

@fernandojsg
Copy link
Collaborator Author

Yep I like that approach, I was afraid to modify the normals after exporting, but it should be ok if we save a reference put them back again after finishing. 👍 Would you mind pushing a PR with these changes? or want me to do it?

@takahirox
Copy link
Collaborator

OK, I will. (Are you in hurry to fix that?)

@fernandojsg
Copy link
Collaborator Author

@takahirox cool, thanks! but no rush I was just reviewing the state of the exporter ^_^

@takahirox
Copy link
Collaborator

takahirox commented Mar 25, 2018

OK, then I'll do tomorrow this week.

@donmccurdy
Copy link
Collaborator

Right, glTF does not allow for omitting normals on particular vertices but not others in a single primitive. We'll need to provide some sort of value, strip these vertices, or throw an error.

@fernandojsg
Copy link
Collaborator Author

I would prefer to make things easier for the user so my vote is for creating a new normals array normalizing them and adding a (0,1,0) value for the empty ones.

@donmccurdy
Copy link
Collaborator

Seems good. If it's slow for large models we might want a checkNormals option or something like that, so users who don't need this can opt out, rather than scanning every vertex.

@fernandojsg
Copy link
Collaborator Author

Yep I was just about to write the same! :D

@takahirox
Copy link
Collaborator

If it's slow for large models we might want a checkNormals option or something like that, so users who don't need this can opt out, rather than scanning every vertex.

I'm gonna make PR without that option first. Let's add when/if necessary. Personally I suppose this check doesn't slow much.

@fernandojsg
Copy link
Collaborator Author

fernandojsg commented Mar 26, 2018

I'm gonna make PR without that option first. Let's add when/if necessary. Personally I suppose this check doesn't slow much.

I was normalizing the whole buffers when loading each stroke on a-painter and it quite slow

@takahirox
Copy link
Collaborator

Even if just checking if they're normalized?

@fernandojsg
Copy link
Collaborator Author

@takahirox you will need to compute the length anyway so I guess it won't change that much

@takahirox
Copy link
Collaborator

Hm, ok. I'll evaluate with the PR.

@donmccurdy
Copy link
Collaborator

It is the first GLTFExporter feature we've introduced that does any computation with each vertex (except relative/absolute morph target conversion) so yeah potentially slower.. either way though.

@garyo
Copy link
Contributor

garyo commented Oct 11, 2018

Great work! IMHO should be merged into core three.js, rather than in "examples".
Would love to see KHR_lights_punctual support!

@donmccurdy donmccurdy changed the title GLTF Exporter GLTFExporter Nov 30, 2018
@donmccurdy
Copy link
Collaborator

PR #15519 adds KHR_lights_punctual. :)

@donmccurdy
Copy link
Collaborator

I think this issue can probably be closed — the remaining items are less critical convenience or optimization, and can be tracked elsewhere:

  • reuse bufferviews
  • automatically merge metal/rough/ao textures

@mrdoob mrdoob removed this from the rXX milestone Apr 18, 2019
@vini-guerrero
Copy link

Hey guys, does anyone know how can I export a custom shaped mesh by morph changes applying the morphs and removing it from the final object?
Like this question https://stackoverflow.com/questions/57423471/how-to-export-morph-changed-meshes-from-threejs-application
Thanks in advance!

@donmccurdy
Copy link
Collaborator

@vini-guerrero Please use the forums (https://discourse.threejs.org/) or Stack Overflow for help, rather than GitHub issues.

@qxx861305133
Copy link

error

@Mugen87
Copy link
Collaborator

Mugen87 commented Dec 30, 2022

@qxx861305133 This issue will be resolved with the next release r149. The problematic JS syntax (optional chaining) has been removed (see #25172).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests