-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
EXT_property_animation extension proposal #1301
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
# EXT\_property\_animation | ||
|
||
## Contributors | ||
|
||
* Bryce Hutchings, Microsoft [@brycehutchings](https://twitter.com/brycehutchings) | ||
* Gary Hsu, Microsoft [@bghgary](https://twitter.com/bghgary) | ||
* Jamie Marconi, Microsoft [@najadojo](https://twitter.com/najadojo) | ||
* Lewis Weaver, Microsoft | ||
|
||
## Status | ||
|
||
Draft | ||
|
||
## Dependencies | ||
|
||
Written against the glTF 2.0 spec. | ||
|
||
## Overview | ||
|
||
This extension adds a specification for animation data targeting arbitrary | ||
properties, such as material colors, texture transform matrices and | ||
extension properties. | ||
|
||
## Extending Animations | ||
|
||
Property animations can be added to an animation by adding the | ||
`EXT_property_animation` extension to any glTF animation. For example, the | ||
following defines an animation with two channels that modify a material's | ||
baseColorFactor and roughnessFactor. | ||
```json | ||
"animations" : [ | ||
{ | ||
"channels" : [], | ||
"extensions" : { | ||
"EXT_property_animation" : { | ||
"channels" : [ | ||
{ | ||
"sampler" : 0, | ||
"target" : "/materials/1/pbrMetallicRoughness/roughnessFactor" | ||
donmccurdy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}, | ||
{ | ||
"sampler" : 1, | ||
"target" : "/materials/1/pbrMetallicRoughness/baseColorFactor" | ||
} | ||
] | ||
} | ||
}, | ||
"samplers" : [ | ||
{ | ||
"input" : 6, | ||
"interpolation" : "CUBICSPLINE", | ||
"output" : 7 | ||
}, | ||
{ | ||
"input" : 8, | ||
"interpolation" : "LINEAR", | ||
"output" : 9 | ||
} | ||
] | ||
} | ||
] | ||
``` | ||
`EXT_property_animation` adds a channels list separate from the core | ||
specification's such that a different set of target values can be described. | ||
|
||
### sampler | ||
|
||
`sampler` has the same meaning and interpretation as the core specification's | ||
`sampler` property. The property animation keyframes are defined in the normal | ||
samplers list and the `sampler` reference indexes into this list for the | ||
enclosing animation. | ||
|
||
The sampler's output accessor type must match the targeted property's type. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd propose to provide a full list of allowed accessor types for each animatable core spec property. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Must all keyframe values comply with limitations specific to the animated property (e.g. |
||
|
||
### target | ||
|
||
`target` is a [JSON Pointer](https://tools.ietf.org/html/rfc6901) in the glTF | ||
JSON specifying a leaf property value. The property need not be present in the | ||
original JSON; default or implicit properties can be animated. `target` must | ||
reference a leaf property on an object that fits the data types supported by | ||
accessor elements. These types are `MAT4`, `MAT3`, `MAT2`, `VEC4`, `VEC3`, | ||
`VEC2`, and `SCALAR`. Properties that don't fit these data types cannot be | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there any use of matrix interpolation? |
||
animated. Animation of boolean or enum values is prevented as well as any | ||
indexed object reference within the glTF JSON (i.e. a property animation can't | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At the current state of glTF 2.0 core spec, we could say that animation of all |
||
describe the value `"material": 0` or a new vertex buffer accessor such as | ||
`"POSITION" : 4`). | ||
|
||
Because the [JSON Pointer](https://tools.ietf.org/html/rfc6901) is able to | ||
reference any JSON property `EXT_property_animation` allows animation of all | ||
current and future glTF extensions. The path value would simply include | ||
`/extensions/EXT_my_extension/my_property`. | ||
|
||
## Extension compatibility and fallback behavior | ||
|
||
When possible, authoring tools should define reasonable initial values | ||
for properties intended to be animated and mark the `EXT_property_animation` | ||
extension as optional. Models including the extension optionally will still | ||
render in all clients that support the core glTF 2.0 specification. Clients | ||
that do not support the extension will fallback to an un-animated initial | ||
state. | ||
|
||
## glTF Schema Updates | ||
|
||
* **JSON schema**: [animation.EXT_property_animation.schema.json](schema/animation.EXT_property_animation.schema.json) | ||
|
||
## Known Implementations | ||
|
||
* [Blender glTF 2.0 Exporter](https://github.com/najadojo/glTF-Blender-Exporter/compare/master...najadojo:EXT_property_animation) | ||
Experiment/Proof of concept to export material property animations. | ||
* [three.js](https://github.com/mrdoob/three.js/compare/dev...najadojo:EXT_property_animation) | ||
Experiment/Proof of concept to import material property animations. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
"$schema": "http://json-schema.org/draft-04/schema", | ||
"title": "Animation Channel", | ||
"type": "object", | ||
"description": "Targets an animation's sampler at a node's property.", | ||
"allOf": [ { "$ref": "glTFProperty.schema.json" } ], | ||
"properties": { | ||
"sampler": { | ||
"allOf": [ { "$ref": "glTFid.schema.json" } ], | ||
"description": "The index of a sampler in this animation used to compute the value for the target.", | ||
"gltf_detailedDescription": "The index of a sampler in this animation used to compute the value for the target." | ||
}, | ||
"target": { | ||
"description": "The JSON Pointer of the property to be animated.", | ||
"gltf_detailedDescription": "Must reference a leaf property on an object that fits the data types supported by accessor elements; animation of boolean or enum values is prevented as well as any indexed object reference within the glTF JSON.", | ||
"type": "string" | ||
}, | ||
"extensions": { }, | ||
"extras": { } | ||
}, | ||
"required": [ "sampler", "target" ] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"$schema": "http://json-schema.org/draft-04/schema", | ||
"title": "EXT_property_animation glTF extension", | ||
"type": "object", | ||
"description": "glTF extension for arbitrary animated properties.", | ||
"allOf": [ { "$ref": "glTFProperty.schema.json" } ], | ||
"properties": { | ||
"channels": { | ||
"type": "array", | ||
"description": "An array of channels, each of which targets an animation's sampler at a property. Different channels of the same animation can't have equal targets.", | ||
"items": { | ||
"$ref": "EXT_property_animation.channel.schema.json" | ||
}, | ||
"minItems": 1 | ||
}, | ||
"extensions": { }, | ||
"extras": { } | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Empty lists are forbidden by the current schema. Why not just re-use the existing
path
property (since the schema allows arbitrary strings there)?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated the sample such that it doesn't fall into this problem. We can't use the
path
as it exists because its defined as an enum value with only the four existing supported values.There may be assets that wish only to animate some property values but not TRS or weights. Suggestions welcome for schema change or a best practice note for an identity animation that would go in core spec
channels
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The schema allows any string in addition to pre-defined four values.
glTF/specification/2.0/schema/animation.channel.target.schema.json
Lines 27 to 29 in 09a404d
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does but the validator and more than one engine makes this a strict enum value. Plus this schema requires a node reference which isn't required with the JSON Pointer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Node reference is not required
glTF/specification/2.0/schema/animation.channel.target.schema.json
Line 35 in 09a404d
The latest validator revision (wip) no longer treats unknown enum values as errors.
The documentation about extensions explicitly says that they can extend allowed enums.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see how it may work although this distinction complicates promotion a bit (so schemas must be remade for minor version updates).
Looking again at the animation example above, it seems that
target
isn't referenced by any other property but inlined intochannel
, so it's neither case, right?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what you mean. What schema changes are you talking about?
target
is being referenced through animations[n].channels[m].target. Basically, any enum that will be parsed and interpreted by an implementation loading the core spec falls into case 2.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated properties reside in the extension object for now. If/when the same functionality goes into
2.x
core version, the schema will be different. That would complicate implementations willing to support all combinations of core versions / extensions.I'd say that
target
is contained withinchannel
object, not referenced by it. So an engine may transitively treat the wholechannel
object as "unknown" as well asanimation
. Given that there're no external (indexed) references to any of animation-related objects, I don't see much difference with top-levelimage
with updatedmimeType
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose it depends on implementation. If an implementation is a top-down loader, then I see a difference. Images referenced only by an extension will never be loaded if the extension is never read and thus the types in the image can be extended without fear of existing implementations falling over.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly. Given that the spec allows an asset to have only, e.g.,
images
collection, we can't assume that an arbitrary implementation won't try to load them in advance unless we want to incorporate "top-down" approach into spec's compatibility strategy (which may be a good idea after all).The existing schema prevents us from extending
animation.channel.target
with an extension object becauseanimation.channel.target.path
is required. With versioning concerns in mind, this means that the safest way of designing the extension schema is to use a new top-level collection.