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

GLTF2 Exporter #11917

Merged
merged 23 commits into from
Aug 15, 2017
Merged

GLTF2 Exporter #11917

merged 23 commits into from
Aug 15, 2017

Conversation

fernandojsg
Copy link
Collaborator

@fernandojsg fernandojsg commented Aug 10, 2017

This is a WIP GLTF v2 Exporter.

image

The code is not clean yet but I wanted to have a place to discuss this implementation from the very beginning so I hope we could end up with a fully featured exporter.

Features / TO-DO:

  • 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
    • Light: Need KHR_Light extension
    • 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
  • Samplers

  • Images:

    • uri using map.image.src
    • uri base64
    • bufferView
    • Deal with flipY images
  • Accessors

    • Use the same bufferView for the same componentType instead of creating a new one for each attribute
    • 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

Output from the current example scene: https://pastebin.com/s8Hd1AWZ

NOTE: I've added a simple example (gltf_exporter.html) just to have something quick to test while developing.

/cc @donmccurdy @takahirox

@fernandojsg
Copy link
Collaborator Author

fernandojsg commented Aug 10, 2017

One of the issues I've found with the images is that GLTF lacks of support for flipY. If we're embedding the textures directly on the file we could flip them ourselves, but what if we're using url?

@fernandojsg fernandojsg force-pushed the gltfexporter branch 2 times, most recently from e7fe438 to 6c894ca Compare August 10, 2017 13:16
@fernandojsg
Copy link
Collaborator Author

In MeshStandardMaterial we have metalnessMap and roughtnessMap which one should we use for metallicRoughnessTexture? From the loader I see it's sharing the same value for both maps, but what about the opposite?
https:/mrdoob/three.js/blob/dev/examples/js/loaders/GLTF2Loader.js#L2140-L2146

@donmccurdy
Copy link
Collaborator

One of the issues I've found with the images is that GLTF lacks of support for flipY. If we're embedding the textures directly on the file we could flip them ourselves, but what if we're using url?

is OBJExporter geometry-only? I guess this hasn't come up yet. Maybe support for flipY could be added to a texture-related extension, but I would lean toward embedding the image data if it's manageable (see below).

In MeshStandardMaterial we have metalnessMap and roughtnessMap which one should we use for metallicRoughnessTexture? From the loader I see it's sharing the same value for both maps, but what about the opposite?

Roughness and metalness must be packed together in a single texture for glTF. Also occlusionTexture could point to that same texture, but that is not required.

@mrdoob
Copy link
Owner

mrdoob commented Aug 11, 2017

What's examples/321103__nsstudios__blip1.wav for? 🤔

@mrdoob
Copy link
Owner

mrdoob commented Aug 11, 2017

Include userData in extras?

Yep!

@mrdoob
Copy link
Owner

mrdoob commented Aug 11, 2017

Geometry

I think for the time I would just do geometry.toBufferGeometry().

@donmccurdy
Copy link
Collaborator

KHR_Material_common

^I would omit this. Most of the extension probably won't be added to glTF 2.0, just a slimmed down Phong-only version, which isn't finished yet.

@fernandojsg
Copy link
Collaborator Author

@mrdoob

What's examples/321103__nsstudios__blip1.wav for? 🤔

My fault 👼 I don't know what I was doing there :)

Include userData in extras?

Right now you can store everything you want in userData right? So how to store it? Serializing the json? base64? just hope that userdata is just a JSON or array and just leave it like that?

geometry.toBufferGeometry()

Cool, I'll give it a try thanks.

@fernandojsg
Copy link
Collaborator Author

@donmccurdy

Roughness and metalness must be packed together in a single texture for glTF. Also occlusionTexture could point to that same texture, but that is not required.

Ok, I've just read that we could have roughtness in G, metalness in B and occlusion in R.

^I would omit this. Most of the extension probably won't be added to glTF 2.0, just a slimmed down Phong-only version, which isn't finished yet.

So what we do when the material is not MeshStandardMaterial ? just store a pbr filling the attributes we could match?

@fernandojsg fernandojsg force-pushed the gltfexporter branch 4 times, most recently from 444c090 to 91f0a99 Compare August 11, 2017 19:27
@fernandojsg
Copy link
Collaborator Author

@mrdoob I can't find toBufferGeometry is still not implemented?

@fernandojsg
Copy link
Collaborator Author

my fault, I believe you were referring to BufferGeometry.fromGeometry

@fernandojsg
Copy link
Collaborator Author

GLTF doesn't have support for the material.flatShading = true property so the exporter will save the normals as they're on the geometry (smooth by vertex) and the loader will just use them showing smooth shading instead of flat.
I believe the best way to get this working is to just compute normals per face instead of per vertex when exporting if flatShading = true. This means that we should duplicate vertices as each one would as many normals as face it's connected to.
What do you think @mrdoob ?

@fernandojsg fernandojsg changed the title GLTF Exporter GLTF2 Exporter Aug 14, 2017
// ---------------------------------------------------------------------
// Ambient light
// ---------------------------------------------------------------------
scene1.add( new THREE.AmbientLight( 0xffffff ) );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have noticed that the glTF examples are over-bright. This should be something like:

scene1.add( new THREE.AmbientLight( 0xffffff, 0.2 ) );

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, done!

// ---------------------------------------------------------------------
// DirectLight
// ---------------------------------------------------------------------
var light = new THREE.DirectionalLight( 0xffffff );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is OK. Same as:

var light = new THREE.DirectionalLight( 0xffffff, 1 );

@WestLangley
Copy link
Collaborator

Just so everyone is on the same page, with the exception of MeshLambertMaterial, vertex normals are neither used, nor required, when rendering with flat shading.

@fernandojsg
Copy link
Collaborator Author

@WestLangley yes, but as GLTF doesn't allow us to define a flat shading material (AFAIK, /cc @donmccurdy) the only way we could differentiate between flat and smooth is by processing the vertex shader before exporting them

@fernandojsg fernandojsg changed the title GLTF2 Exporter GLTF2 Exporter (WIP) Aug 14, 2017
@fernandojsg fernandojsg changed the title GLTF2 Exporter (WIP) GLTF2 Exporter Aug 14, 2017
@fernandojsg
Copy link
Collaborator Author

The exporter is already fully functional, the most important parts that are missing in this PR:

  • Normals for flat shading
  • Textures processing:
    • Convert images to base64
    • Flip images if flipY=true
    • Merge roughnessTexture + metalnessTexture + aoTexture

Here is the current example exported and imported on @donmccurdy 's viewer (note that ambient light is different too)
image

image

I believe it's better to review the current features so we could keep evolving it in smaller feature-based PRs that would be easier to review than growing this one too much.

@donmccurdy
Copy link
Collaborator

@fernandojsg If normals are omitted, glTF requires viewers to display the mesh with flat shading (source).

@mrdoob
Copy link
Owner

mrdoob commented Aug 15, 2017

I believe the best way to get this working is to just compute normals per face instead of per vertex when exporting if flatShading = true. This means that we should duplicate vertices as each one would as many normals as face it's connected to.

Sounds a bit too complicated. I would ignore this for now.

@mrdoob
Copy link
Owner

mrdoob commented Aug 15, 2017

The exporter is already fully functional, the most important parts that are missing in this PR:

Do you want to merge this in the meantime?

@fernandojsg
Copy link
Collaborator Author

@donmccurdy cool, I didn't know that, thanks! So a first approach could be to just delete de normals for the mesh with flatShading=true.
@mrdoob yes please, so we could keep working on the details separately without growing the PR so much.

@mrdoob mrdoob merged commit 53f6e36 into mrdoob:dev Aug 15, 2017
@mrdoob
Copy link
Owner

mrdoob commented Aug 15, 2017

Many thanks!

@fernandojsg fernandojsg deleted the gltfexporter branch August 15, 2017 06:55
@fernandojsg fernandojsg mentioned this pull request Aug 15, 2017
87 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants