diff --git a/extensions/2.0/Vendor/EXT_property_animation/README.md b/extensions/2.0/Vendor/EXT_property_animation/README.md
new file mode 100644
index 0000000000..74ebcda090
--- /dev/null
+++ b/extensions/2.0/Vendor/EXT_property_animation/README.md
@@ -0,0 +1,161 @@
+# EXT\_property\_animation
+
+## Contributors
+
+* Alexey Knyazev
+* Bryce Hutchings, Microsoft [@brycehutchings](https://twitter.com/brycehutchings)
+* Don McCurdy, Google [@donrmccurdy](https://twitter.com/donrmccurdy)
+* 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 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" : [
+ {
+ "sampler" : 2,
+ "target" : {
+ "node" : 0,
+ "path" : "scale"
+ }
+ }
+ ],
+ "extensions" : {
+ "EXT_property_animation" : {
+ "channels" : [
+ {
+ "sampler" : 0,
+ "target" : "/materials/1/pbrMetallicRoughness/roughnessFactor"
+ },
+ {
+ "sampler" : 1,
+ "target" : "/materials/1/pbrMetallicRoughness/baseColorFactor"
+ }
+ ]
+ }
+ },
+ "samplers" : [
+ {
+ "input" : 6,
+ "interpolation" : "CUBICSPLINE",
+ "output" : 7
+ },
+ {
+ "input" : 8,
+ "interpolation" : "LINEAR",
+ "output" : 9
+ },
+ {
+ "input" : 10,
+ "interpolation" : "LINEAR",
+ "output" : 11
+ }
+ ]
+ }
+]
+ ```
+`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.
+
+### 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. 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. Extensions should define properties that are intended
+to be animatable in their specification by referring to the syntax defined
+here.
+
+#### Valid target templates
+
+
+|`channel.path`|Accessor Type|Component Type(s)|Description|
+|----|----------------|-----------------|-----------|
+|`"/nodes/{}/translation"`|`"VEC3"`|`5126` (FLOAT)|XYZ translation vector|
+|`"/nodes/{}/rotation"`|`"VEC4"`|`5126` (FLOAT)
`5120` (BYTE) normalized
`5121` (UNSIGNED_BYTE) normalized
`5122` (SHORT) normalized
`5123` (UNSIGNED_SHORT) normalized|XYZW rotation quaternion|
+|`"/nodes/{}/scale"`|`"VEC3"`|`5126` (FLOAT)|XYZ scale vector|
+|`"/cameras/{}/orthographic/xmag"`|`"SCALAR"`|`5126` (FLOAT)|Horizontal magnification of the view|
+|`"/cameras/{}/orthographic/ymag"`|`"SCALAR"`|`5126` (FLOAT)|Vertical magnification of the view|
+|`"/cameras/{}/orthographic/zfar"`|`"SCALAR"`|`5126` (FLOAT)|Distance to the far clipping plane|
+|`"/cameras/{}/orthographic/znear"`|`"SCALAR"`|`5126` (FLOAT)|Distance to the near clipping plane|
+|`"/cameras/{}/perspective/aspectRatio"`|`"SCALAR"`|`5126` (FLOAT)|Aspect ratio of the field of view|
+|`"/cameras/{}/perspective/yfov"`|`"SCALAR"`|`5126` (FLOAT)|Vertical field of view in radians|
+|`"/cameras/{}/perspective/zfar"`|`"SCALAR"`|`5126` (FLOAT)|Distance to the far clipping plane|
+|`"/cameras/{}/perspective/znear"`|`"SCALAR"`|`5126` (FLOAT)|Distance to the near clipping plane|
+|`"/materials/{}/pbrMetallicRoughness/baseColorFactor"`|`"VEC4"`|`5126` (FLOAT)
`5120` (BYTE) normalized
`5121` (UNSIGNED_BYTE) normalized
`5122` (SHORT) normalized
`5123` (UNSIGNED_SHORT) normalized|The material's base color factor|
+|`"/materials/{}/pbrMetallicRoughness/metallicFactor"`|`"SCALAR"`|`5126` (FLOAT)|The metalness of the material|
+|`"/materials/{}/pbrMetallicRoughness/roughnessFactor"`|`"SCALAR"`|`5126` (FLOAT)|The roughness of the material|
+|`"/materials/{}/alphaCutoff"`|`"SCALAR"`|`5126` (FLOAT)|The alpha cutoff value of the material|
+|`"/materials/{}/emissiveFactor"`|`"SCALAR"`|`5126` (FLOAT)|The emissive color of the material|
+|`"/materials/{}/normalTexture/scale"`|`"SCALAR"`|`5126` (FLOAT)|Multiplier applied to each normal vector of the normal texture|
+|`"/materials/{}/occlusionTexture/strength"`|`"SCALAR"`|`5126` (FLOAT)|Multiplier controlling the amount of occlusion applied|
+|`"/materials/{}/extensions/KHR_materials_pbrSpecularGlossiness/diffuseFactor"`|`"VEC4"`|`5126` (FLOAT)
`5120` (BYTE) normalized
`5121` (UNSIGNED_BYTE) normalized
`5122` (SHORT) normalized
`5123` (UNSIGNED_SHORT) normalized|The reflected diffuse factor of the material|
+|`"/materials/{}/extensions/KHR_materials_pbrSpecularGlossiness/specularFactor"`|`"VEC3"`|`5126` (FLOAT)
`5120` (BYTE) normalized
`5121` (UNSIGNED_BYTE) normalized
`5122` (SHORT) normalized
`5123` (UNSIGNED_SHORT) normalized|The specular RGB color of the material|
+|`"/materials/{}/extensions/KHR_materials_pbrSpecularGlossiness/glossinessFactor"`|`"SCALAR"`|`5126` (FLOAT)|Angle, in radians, from centre of spotlight where falloff ends|
+|`"/extensions/KHR_lights/lights/{}/color"`|`"VEC3"`|`5126` (FLOAT)
`5120` (BYTE) normalized
`5121` (UNSIGNED_BYTE) normalized
`5122` (SHORT) normalized
`5123` (UNSIGNED_SHORT) normalized|RGB value for light's color in linear space|
+|`"/extensions/KHR_lights/lights/{}/intensity"`|`"SCALAR"`|`5126` (FLOAT)|Brightness of light|
+|`"/extensions/KHR_lights/lights/{}/innerConeAngle"`|`"SCALAR"`|`5126` (FLOAT)|Angle, in radians, from centre of spotlight where falloff begins|
+|`"/extensions/KHR_lights/lights/{}/outerConeAngle"`|`"SCALAR"`|`5126` (FLOAT)|Brightness of light|
+|`"/materials/{}{}/extensions/KHR_texture_transform/offset"`|`"VEC2"`|`5126` (FLOAT)|The offset of the UV coordinate origin as a factor of the texture dimensions|
+|`"/materials/{}{}/extensions/KHR_texture_transform/rotation"`|`"SCALAR"`|`5126` (FLOAT)|Rotate the UVs by this many radians counter-clockwise around the origin|
+|`"/materials/{}{}/extensions/KHR_texture_transform/scale"`|`"VEC2"`|`5126` (FLOAT)|The scale factor applied to the components of the UV coordinates|
+|`"/nodes/{}/extensions/AVR_lights_static/strength"`|`"SCALAR"`|`5126` (FLOAT)|The influence of the lightmap on the final output|
+
+#### `extras`
+
+A channel may target `extras` at any allowed JSON Pointer value but
+interpretation of the animated values is entirely application specific.
+
+## 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.
+
+Where ever a property defines limitations to acceptable values an animation's
+sampler must conform to those limitations.
+
+## 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.
diff --git a/extensions/2.0/Vendor/EXT_property_animation/schema/EXT_property_animation.channel.schema.json b/extensions/2.0/Vendor/EXT_property_animation/schema/EXT_property_animation.channel.schema.json
new file mode 100644
index 0000000000..46ab8520ee
--- /dev/null
+++ b/extensions/2.0/Vendor/EXT_property_animation/schema/EXT_property_animation.channel.schema.json
@@ -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" ]
+}
diff --git a/extensions/2.0/Vendor/EXT_property_animation/schema/animation.EXT_property_animation.schema.json b/extensions/2.0/Vendor/EXT_property_animation/schema/animation.EXT_property_animation.schema.json
new file mode 100644
index 0000000000..89d0f791c0
--- /dev/null
+++ b/extensions/2.0/Vendor/EXT_property_animation/schema/animation.EXT_property_animation.schema.json
@@ -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": { }
+ }
+}