├── .gitattribute ├── .vscode └── tasks.json ├── README.md ├── samples ├── README.md ├── Seed-san │ ├── README.md │ ├── screenshot │ │ └── screenshot.png │ └── vrm │ │ └── Seed-san.vrm ├── VRM1_Constraint_Twist_Sample │ ├── README.md │ ├── screenshot │ │ └── screenshot.jpg │ └── vrm │ │ └── VRM1_Constraint_Twist_Sample.vrm ├── VRMC_materials_mtoon_UV_Animation_Test │ ├── README.md │ ├── screenshot │ │ └── screenshot.jpg │ └── vrm │ │ └── VRMC_materials_mtoon_UV_Animation_Test.vrm ├── VRMC_vrm_expressions_isBinary_Overridden │ ├── README.md │ ├── screenshot │ │ └── screenshot.jpg │ └── vrm │ │ └── VRMC_vrm_expressions_isBinary_Overridden.vrm └── VRMC_vrm_expressions_isBinary_Overrides │ ├── README.md │ ├── screenshot │ └── screenshot.jpg │ └── vrm │ └── VRMC_vrm_expressions_isBinary_Overrides.vrm └── specification ├── 0.0 ├── README.ja.md ├── README.md └── schema │ ├── vrm.blendshape.bind.schema.json │ ├── vrm.blendshape.group.schema.json │ ├── vrm.blendshape.materialbind.schema.json │ ├── vrm.blendshape.schema.json │ ├── vrm.firstperson.degreemap.schema.json │ ├── vrm.firstperson.meshannotation.schema.json │ ├── vrm.firstperson.schema.json │ ├── vrm.humanoid.bone.schema.json │ ├── vrm.humanoid.schema.json │ ├── vrm.material.schema.json │ ├── vrm.meta.schema.json │ ├── vrm.schema.json │ ├── vrm.secondaryanimation.collidergroup.schema.json │ ├── vrm.secondaryanimation.schema.json │ └── vrm.secondaryanimation.spring.schema.json ├── VRMC_materials_hdr_emissiveMultiplier-1.0 ├── README.ja.md ├── README.md └── schema │ └── VRMC_materials_hdr_emissiveMultiplier.json ├── VRMC_materials_mtoon-1.0 ├── MToon_comparision.md ├── README.ja.md ├── README.md ├── figures │ ├── mtoon-lit-shade.png │ └── mtoon-shading-ramp.png └── schema │ ├── VRMC_materials_mtoon.schema.json │ └── mtoon.shadingShiftTexture.schema.json ├── VRMC_node_constraint-1.0 ├── README.ja.md ├── README.md └── schema │ ├── VRMC_node_constraint.aimConstraint.schema.json │ ├── VRMC_node_constraint.constraint.schema.json │ ├── VRMC_node_constraint.rollConstraint.schema.json │ ├── VRMC_node_constraint.rotationConstraint.schema.json │ └── VRMC_node_constraint.schema.json ├── VRMC_springBone-1.0 ├── README.ja.md ├── README.md └── schema │ ├── VRMC_springBone.collider.schema.json │ ├── VRMC_springBone.colliderGroup.schema.json │ ├── VRMC_springBone.joint.schema.json │ ├── VRMC_springBone.schema.json │ ├── VRMC_springBone.shape.schema.json │ └── VRMC_springBone.spring.schema.json ├── VRMC_springBone_extended_collider-1.0 ├── README.ja.md ├── README.md └── schema │ ├── VRMC_springBone_extended_collider.schema.json │ └── VRMC_springBone_extended_collider.shape.schema.json ├── VRMC_vrm-1.0 ├── README.ja.md ├── README.md ├── expressions.ja.md ├── expressions.md ├── figures │ ├── override-isbinary-en.png │ ├── override-isbinary-ja.png │ └── range_map.png ├── firstPerson.ja.md ├── firstPerson.md ├── humanoid.ja.md ├── humanoid.md ├── lookAt.ja.md ├── lookAt.md ├── meta.ja.md ├── meta.md ├── schema │ ├── VRMC_vrm.expressions.expression.materialColorBind.schema.json │ ├── VRMC_vrm.expressions.expression.morphTargetBind.schema.json │ ├── VRMC_vrm.expressions.expression.schema.json │ ├── VRMC_vrm.expressions.expression.textureTransformBind.schema.json │ ├── VRMC_vrm.expressions.schema.json │ ├── VRMC_vrm.firstPerson.meshAnnotation.schema.json │ ├── VRMC_vrm.firstPerson.schema.json │ ├── VRMC_vrm.humanoid.humanBones.humanBone.schema.json │ ├── VRMC_vrm.humanoid.humanBones.schema.json │ ├── VRMC_vrm.humanoid.schema.json │ ├── VRMC_vrm.lookAt.rangeMap.schema.json │ ├── VRMC_vrm.lookAt.schema.json │ ├── VRMC_vrm.meta.schema.json │ └── VRMC_vrm.schema.json ├── tpose.ja.md └── tpose.md └── VRMC_vrm_animation-1.0 ├── README.ja.md ├── README.md ├── how_to_transform_human_pose.ja.md ├── how_to_transform_human_pose.md └── schema ├── VRMC_vrm_animation.expressions.expression.schema.json ├── VRMC_vrm_animation.expressions.schema.json ├── VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json ├── VRMC_vrm_animation.humanoid.humanBones.schema.json ├── VRMC_vrm_animation.humanoid.schema.json ├── VRMC_vrm_animation.lookAt.schema.json └── VRMC_vrm_animation.schema.json /.gitattribute: -------------------------------------------------------------------------------- 1 | *.md text eol=lf 2 | *.json text eol=lf 3 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "doctoc level3", 8 | "type": "shell", 9 | "command": "npx doctoc --maxlevel 3 ${file}", 10 | "problemMatcher": [] 11 | }, 12 | { 13 | "label": "doctoc", 14 | "type": "shell", 15 | "command": "npx doctoc ${file}", 16 | "problemMatcher": [] 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vrm-specification 2 | vrm specification 3 | -------------------------------------------------------------------------------- /samples/README.md: -------------------------------------------------------------------------------- 1 | # VRM Samples 2 | 3 | ## Practical 4 | Practical models for using as avatars. 5 | 6 | | Model | Screenshot | Description | 7 | |--------------------------------------------------------------|-------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------| 8 | | [Seed-san](Seed-san) | ![](Seed-san/screenshot/screenshot.png) | PBR materials, MToon materials, SpringBones, Constraints (Rotation), Expressions (Morph, UV Transform), LookAt (Expression) | 9 | | [VRM1_Constraint_Twist_Sample](VRM1_Constraint_Twist_Sample) | ![](VRM1_Constraint_Twist_Sample/screenshot/screenshot.jpg) | Expressions (Morph), LookAt (Bones), MToon materials, SpringBones, Constraints (Roll and Aim) | 10 | 11 | ## Feature Tests 12 | Models to test specific features of the VRM extension suite. 13 | 14 | | Model | Screenshot | Description | 15 | |----------------------------------------------------------------------------------|-----------------------------------------------------------------------|---------------------------------------------------------------------| 16 | | [VRMC_vrm_expressions_isBinary_Overrides](VRMC_vrm_expressions_isBinary_Overrides) | ![](VRMC_vrm_expressions_isBinary_Overrides/screenshot/screenshot.jpg) | Tests if the expression with isBinary successfully overrides the other expression. | 17 | | [VRMC_vrm_expressions_isBinary_Overridden](VRMC_vrm_expressions_isBinary_Overridden) | ![](VRMC_vrm_expressions_isBinary_Overridden/screenshot/screenshot.jpg) | Tests if the expression with isBinary is successfully overridden by the other expression. | 18 | | [VRMC_materials_mtoon_UV_Animation_Test](VRMC_materials_mtoon_UV_Animation_Test) | ![](VRMC_materials_mtoon_UV_Animation_Test/screenshot/screenshot.jpg) | Tests if the UV animation features of MToon is supported correctly. | 19 | -------------------------------------------------------------------------------- /samples/Seed-san/README.md: -------------------------------------------------------------------------------- 1 | # Seed-san 2 | 3 | ## Screenshot 4 | 5 | ![screenshot](screenshot/screenshot.png) 6 | 7 | ## License Information 8 | 9 | [VRM Public License 1.0](https://vrm.dev/en/licenses/1.0/index) 10 | 11 | Seed-san model by VirtualCast, Inc. 12 | -------------------------------------------------------------------------------- /samples/Seed-san/screenshot/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrm-c/vrm-specification/c24d76d99a18738dd2c266be1c83f089064a7b5e/samples/Seed-san/screenshot/screenshot.png -------------------------------------------------------------------------------- /samples/Seed-san/vrm/Seed-san.vrm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrm-c/vrm-specification/c24d76d99a18738dd2c266be1c83f089064a7b5e/samples/Seed-san/vrm/Seed-san.vrm -------------------------------------------------------------------------------- /samples/VRM1_Constraint_Twist_Sample/README.md: -------------------------------------------------------------------------------- 1 | # VRM1_Constraint_Twist_Sample 2 | 3 | ## Screenshot 4 | 5 | ![screenshot](screenshot/screenshot.jpg) 6 | 7 | ## License Information 8 | 9 | [VRM Public License 1.0](https://vrm.dev/licenses/1.0/) 10 | 11 | (c) 2022 pixiv Inc. 12 | -------------------------------------------------------------------------------- /samples/VRM1_Constraint_Twist_Sample/screenshot/screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrm-c/vrm-specification/c24d76d99a18738dd2c266be1c83f089064a7b5e/samples/VRM1_Constraint_Twist_Sample/screenshot/screenshot.jpg -------------------------------------------------------------------------------- /samples/VRM1_Constraint_Twist_Sample/vrm/VRM1_Constraint_Twist_Sample.vrm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrm-c/vrm-specification/c24d76d99a18738dd2c266be1c83f089064a7b5e/samples/VRM1_Constraint_Twist_Sample/vrm/VRM1_Constraint_Twist_Sample.vrm -------------------------------------------------------------------------------- /samples/VRMC_materials_mtoon_UV_Animation_Test/README.md: -------------------------------------------------------------------------------- 1 | # VRMC_materials_mtoon UV Animation Test 2 | 3 | ## Screenshot 4 | 5 | ![screenshot](screenshot/screenshot.jpg) 6 | 7 | ## Description 8 | 9 | This model is an example of the [VRMC_materials_mtoon](../../specification/VRMC_materials_mtoon-1.0/) extension. 10 | 11 | There are three quads in this model. 12 | Each quad has different UV animation settings. 13 | 14 | ## License Information 15 | 16 | [VRM Public License 1.0](https://vrm.dev/licenses/1.0/) 17 | 18 | (c) 2022 pixiv Inc. 19 | -------------------------------------------------------------------------------- /samples/VRMC_materials_mtoon_UV_Animation_Test/screenshot/screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrm-c/vrm-specification/c24d76d99a18738dd2c266be1c83f089064a7b5e/samples/VRMC_materials_mtoon_UV_Animation_Test/screenshot/screenshot.jpg -------------------------------------------------------------------------------- /samples/VRMC_materials_mtoon_UV_Animation_Test/vrm/VRMC_materials_mtoon_UV_Animation_Test.vrm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrm-c/vrm-specification/c24d76d99a18738dd2c266be1c83f089064a7b5e/samples/VRMC_materials_mtoon_UV_Animation_Test/vrm/VRMC_materials_mtoon_UV_Animation_Test.vrm -------------------------------------------------------------------------------- /samples/VRMC_vrm_expressions_isBinary_Overridden/README.md: -------------------------------------------------------------------------------- 1 | # VRMC_vrm expressions isBinary Overridden Test 2 | 3 | ## Screenshot 4 | 5 | ![screenshot](screenshot/screenshot.jpg) 6 | 7 | ## Description 8 | 9 | This model is an example of the [VRMC_vrm](../../specification/VRMC_vrm-1.0/) extension. 10 | 11 | When an expression with isBinary is overridden by other expressions, the expression must be completely suppressed if the effect received is greater than 0.0, [as the specification says](https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_vrm-1.0/expressions.md#interaction-between-override-and-isbinary). 12 | This model tests if the overridden expression with isBinary `blink` is successfully suppressed by the overriding expression `happy` when the value of `happy` is greater than 0.0. 13 | 14 | The big green plane with several check marks indicates that the expression values are within the expected range. 15 | If cross marks are displayed or red regions are visible, it indicates that the implementation of the expressions is incorrect. 16 | 17 | There also are yellow bars below the big plane that indicate the output value of the expressions. 18 | 19 | The expressions of this model are defined as follows: 20 | 21 | ```json 22 | "expressions": { 23 | "preset": { 24 | "happy": { 25 | "overrideBlink": "blend", 26 | "textureTransformBinds": [ ... ] 27 | }, 28 | "blink": { 29 | "isBinary": true, 30 | "textureTransformBinds": [ ... ] 31 | } 32 | } 33 | } 34 | ``` 35 | 36 | ## License Information 37 | 38 | [VRM Public License 1.0](https://vrm.dev/licenses/1.0/) 39 | 40 | (c) 2025 pixiv Inc. 41 | -------------------------------------------------------------------------------- /samples/VRMC_vrm_expressions_isBinary_Overridden/screenshot/screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrm-c/vrm-specification/c24d76d99a18738dd2c266be1c83f089064a7b5e/samples/VRMC_vrm_expressions_isBinary_Overridden/screenshot/screenshot.jpg -------------------------------------------------------------------------------- /samples/VRMC_vrm_expressions_isBinary_Overridden/vrm/VRMC_vrm_expressions_isBinary_Overridden.vrm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrm-c/vrm-specification/c24d76d99a18738dd2c266be1c83f089064a7b5e/samples/VRMC_vrm_expressions_isBinary_Overridden/vrm/VRMC_vrm_expressions_isBinary_Overridden.vrm -------------------------------------------------------------------------------- /samples/VRMC_vrm_expressions_isBinary_Overrides/README.md: -------------------------------------------------------------------------------- 1 | # VRMC_vrm expressions isBinary Overrides Test 2 | 3 | ## Screenshot 4 | 5 | ![screenshot](screenshot/screenshot.jpg) 6 | 7 | ## Description 8 | 9 | This model is an example of the [VRMC_vrm](../../specification/VRMC_vrm-1.0/) extension. 10 | 11 | When an expression with isBinary overrides other expressions, the binary output value MUST be used to affect other expressions, [as the specification says](https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_vrm-1.0/expressions.md#interaction-between-override-and-isbinary). 12 | This model tests if the overriding expression with isBinary `happy` successfully suppresses the overridden expression `blink` when the value of `happy` is greater than 0.5. 13 | 14 | The big green plane with several check marks indicates that the expression values are within the expected range. 15 | If cross marks are displayed or red regions are visible, it indicates that the implementation of the expressions is incorrect. 16 | 17 | There also are yellow bars below the big plane that indicate the output value of the expressions. 18 | 19 | The expressions of this model are defined as follows: 20 | 21 | ```json 22 | "expressions": { 23 | "preset": { 24 | "happy": { 25 | "overrideBlink": "blend", 26 | "isBinary": true, 27 | "textureTransformBinds": [ ... ] 28 | }, 29 | "blink": { 30 | "textureTransformBinds": [ ... ] 31 | } 32 | } 33 | } 34 | ``` 35 | 36 | ## License Information 37 | 38 | [VRM Public License 1.0](https://vrm.dev/licenses/1.0/) 39 | 40 | (c) 2025 pixiv Inc. 41 | -------------------------------------------------------------------------------- /samples/VRMC_vrm_expressions_isBinary_Overrides/screenshot/screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrm-c/vrm-specification/c24d76d99a18738dd2c266be1c83f089064a7b5e/samples/VRMC_vrm_expressions_isBinary_Overrides/screenshot/screenshot.jpg -------------------------------------------------------------------------------- /samples/VRMC_vrm_expressions_isBinary_Overrides/vrm/VRMC_vrm_expressions_isBinary_Overrides.vrm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrm-c/vrm-specification/c24d76d99a18738dd2c266be1c83f089064a7b5e/samples/VRMC_vrm_expressions_isBinary_Overrides/vrm/VRMC_vrm_expressions_isBinary_Overrides.vrm -------------------------------------------------------------------------------- /specification/0.0/schema/vrm.blendshape.bind.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "vrm.blendshape.bind", 3 | "type": "object", 4 | "properties": { 5 | "mesh": { 6 | "type": "integer", 7 | "minimum": 0 8 | }, 9 | "index": { 10 | "type": "integer", 11 | "minimum": 0 12 | }, 13 | "weight": { 14 | "description": "SkinnedMeshRenderer.SetBlendShapeWeight", 15 | "type": "number", 16 | "minimum": 0, 17 | "maximum": 100 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /specification/0.0/schema/vrm.blendshape.group.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "vrm.blendshape.group", 3 | "type": "object", 4 | "properties": { 5 | "name": { 6 | "description": "Expression name", 7 | "type": "string" 8 | }, 9 | "presetName": { 10 | "description": "Predefined Expression name", 11 | "type": "string", 12 | "enum": ["unknown","neutral","a","i","u","e","o","blink","joy","angry","sorrow","fun","lookup","lookdown","lookleft","lookright","blink_l","blink_r"] 13 | }, 14 | "binds": { 15 | "description": "Low level blendshape references.", 16 | "type": "array", 17 | "items": { 18 | "$ref": "vrm.blendshape.bind.schema.json" 19 | } 20 | }, 21 | "materialValues": { 22 | "description": "Material animation references.", 23 | "type": "array", 24 | "items": { 25 | "$ref": "vrm.blendshape.materialbind.schema.json" 26 | } 27 | }, 28 | "isBinary": { 29 | "description": "0 or 1. Do not allow an intermediate value. Value should rounded", 30 | "type": "boolean" 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /specification/0.0/schema/vrm.blendshape.materialbind.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "vrm.blendshape.materialbind", 3 | "type": "object", 4 | "properties": { 5 | "materialName": { 6 | "type": "string" 7 | }, 8 | "propertyName": { 9 | "type": "string" 10 | }, 11 | "targetValue": { 12 | "type": "array", 13 | "items": { 14 | "type": "number" 15 | } 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /specification/0.0/schema/vrm.blendshape.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "vrm.blendshape", 3 | "description": "BlendShapeAvatar of UniVRM", 4 | "type": "object", 5 | "properties": { 6 | "blendShapeGroups": { 7 | "type": "array", 8 | "items": { 9 | "$ref": "vrm.blendshape.group.schema.json" 10 | } 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /specification/0.0/schema/vrm.firstperson.degreemap.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "vrm.firstperson.degreemap", 3 | "description": "Eye controller setting.", 4 | "type": "object", 5 | "properties": { 6 | "curve": { 7 | "description": "None linear mapping params. time, value, inTangent, outTangent", 8 | "type": "array", 9 | "items": { 10 | "type": "number" 11 | } 12 | }, 13 | "xRange": { 14 | "description": "Look at input clamp range degree.", 15 | "type": "number" 16 | }, 17 | "yRange": { 18 | "description": "Look at map range degree from xRange.", 19 | "type": "number" 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /specification/0.0/schema/vrm.firstperson.meshannotation.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "vrm.firstperson.meshannotation", 3 | "type": "object", 4 | "properties": { 5 | "mesh": { 6 | "type": "integer" 7 | }, 8 | "firstPersonFlag": { 9 | "type": "string" 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /specification/0.0/schema/vrm.firstperson.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "vrm.firstperson", 3 | "type": "object", 4 | "properties": { 5 | "firstPersonBone": { 6 | "description": "The bone whose rendering should be turned off in first-person view. Usually Head is specified.", 7 | "type": "integer" 8 | }, 9 | "firstPersonBoneOffset": { 10 | "description": "The target position of the VR headset in first-person view. It is assumed that an offset from the head bone to the VR headset is added.", 11 | "type": "object", 12 | "properties": { 13 | "x": { 14 | "type": "number" 15 | }, 16 | "y": { 17 | "type": "number" 18 | }, 19 | "z": { 20 | "type": "number" 21 | } 22 | } 23 | }, 24 | "meshAnnotations": { 25 | "description": "Switch display \/ undisplay for each mesh in first-person view or the others.", 26 | "type": "array", 27 | "items": { 28 | "$ref": "vrm.firstperson.meshannotation.schema.json" 29 | } 30 | }, 31 | "lookAtTypeName": { 32 | "description": "Eye controller mode.", 33 | "type": "string", 34 | "enum": ["Bone","BlendShape"] 35 | }, 36 | "lookAtHorizontalInner": { 37 | "$ref": "vrm.firstperson.degreemap.schema.json" 38 | }, 39 | "lookAtHorizontalOuter": { 40 | "$ref": "vrm.firstperson.degreemap.schema.json" 41 | }, 42 | "lookAtVerticalDown": { 43 | "$ref": "vrm.firstperson.degreemap.schema.json" 44 | }, 45 | "lookAtVerticalUp": { 46 | "$ref": "vrm.firstperson.degreemap.schema.json" 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /specification/0.0/schema/vrm.humanoid.bone.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "vrm.humanoid.bone", 3 | "type": "object", 4 | "properties": { 5 | "bone": { 6 | "description": "Human bone name.", 7 | "type": "string", 8 | "enum": ["hips","leftUpperLeg","rightUpperLeg","leftLowerLeg","rightLowerLeg","leftFoot","rightFoot","spine","chest","neck","head","leftShoulder","rightShoulder","leftUpperArm","rightUpperArm","leftLowerArm","rightLowerArm","leftHand","rightHand","leftToes","rightToes","leftEye","rightEye","jaw","leftThumbProximal","leftThumbIntermediate","leftThumbDistal","leftIndexProximal","leftIndexIntermediate","leftIndexDistal","leftMiddleProximal","leftMiddleIntermediate","leftMiddleDistal","leftRingProximal","leftRingIntermediate","leftRingDistal","leftLittleProximal","leftLittleIntermediate","leftLittleDistal","rightThumbProximal","rightThumbIntermediate","rightThumbDistal","rightIndexProximal","rightIndexIntermediate","rightIndexDistal","rightMiddleProximal","rightMiddleIntermediate","rightMiddleDistal","rightRingProximal","rightRingIntermediate","rightRingDistal","rightLittleProximal","rightLittleIntermediate","rightLittleDistal","upperChest"] 9 | }, 10 | "node": { 11 | "description": "Reference node index", 12 | "type": "integer" 13 | }, 14 | "useDefaultValues": { 15 | "description": "Unity's HumanLimit.useDefaultValues", 16 | "type": "boolean" 17 | }, 18 | "min": { 19 | "description": "Unity's HumanLimit.min", 20 | "type": "object", 21 | "properties": { 22 | "x": { 23 | "type": "number" 24 | }, 25 | "y": { 26 | "type": "number" 27 | }, 28 | "z": { 29 | "type": "number" 30 | } 31 | } 32 | }, 33 | "max": { 34 | "description": "Unity's HumanLimit.max", 35 | "type": "object", 36 | "properties": { 37 | "x": { 38 | "type": "number" 39 | }, 40 | "y": { 41 | "type": "number" 42 | }, 43 | "z": { 44 | "type": "number" 45 | } 46 | } 47 | }, 48 | "center": { 49 | "description": "Unity's HumanLimit.center", 50 | "type": "object", 51 | "properties": { 52 | "x": { 53 | "type": "number" 54 | }, 55 | "y": { 56 | "type": "number" 57 | }, 58 | "z": { 59 | "type": "number" 60 | } 61 | } 62 | }, 63 | "axisLength": { 64 | "description": "Unity's HumanLimit.axisLength", 65 | "type": "number" 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /specification/0.0/schema/vrm.humanoid.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "vrm.humanoid", 3 | "type": "object", 4 | "properties": { 5 | "humanBones": { 6 | "type": "array", 7 | "items": { 8 | "$ref": "vrm.humanoid.bone.schema.json" 9 | } 10 | }, 11 | "armStretch": { 12 | "description": "Unity's HumanDescription.armStretch", 13 | "type": "number" 14 | }, 15 | "legStretch": { 16 | "description": "Unity's HumanDescription.legStretch", 17 | "type": "number" 18 | }, 19 | "upperArmTwist": { 20 | "description": "Unity's HumanDescription.upperArmTwist", 21 | "type": "number" 22 | }, 23 | "lowerArmTwist": { 24 | "description": "Unity's HumanDescription.lowerArmTwist", 25 | "type": "number" 26 | }, 27 | "upperLegTwist": { 28 | "description": "Unity's HumanDescription.upperLegTwist", 29 | "type": "number" 30 | }, 31 | "lowerLegTwist": { 32 | "description": "Unity's HumanDescription.lowerLegTwist", 33 | "type": "number" 34 | }, 35 | "feetSpacing": { 36 | "description": "Unity's HumanDescription.feetSpacing", 37 | "type": "number" 38 | }, 39 | "hasTranslationDoF": { 40 | "description": "Unity's HumanDescription.hasTranslationDoF", 41 | "type": "boolean" 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /specification/0.0/schema/vrm.material.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "vrm.material", 3 | "type": "object", 4 | "properties": { 5 | "name": { 6 | "type": "string" 7 | }, 8 | "shader": { 9 | "description": "This contains shader name. VRM/MToon, VRM/UnlitTransparentZWrite, and VRM_USE_GLTFSHADER (and legacy materials as Standard, UniGLTF/UniUnlit, VRM/UnlitTexture, VRM/UnlitCutout, VRM/UnlitTransparent) . If VRM_USE_GLTFSHADER is specified, use same index of gltf's material settings", 10 | "type": "string" 11 | }, 12 | "renderQueue": { 13 | "type": "integer" 14 | }, 15 | "floatProperties": { 16 | "type": "object", 17 | "additionalProperties": { 18 | "type": "number" 19 | } 20 | }, 21 | "vectorProperties": { 22 | "type": "object", 23 | "additionalProperties": { 24 | "type": "array", 25 | "items": { 26 | "type": "number" 27 | } 28 | } 29 | }, 30 | "textureProperties": { 31 | "type": "object", 32 | "additionalProperties": { 33 | "type": "integer" 34 | } 35 | }, 36 | "keywordMap": { 37 | "type": "object", 38 | "additionalProperties": { 39 | "type": "boolean" 40 | } 41 | }, 42 | "tagMap": { 43 | "type": "object", 44 | "additionalProperties": { 45 | "type": "string" 46 | } 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /specification/0.0/schema/vrm.meta.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "vrm.meta", 3 | "type": "object", 4 | "properties": { 5 | "title": { 6 | "description": "Title of VRM model", 7 | "type": "string" 8 | }, 9 | "version": { 10 | "description": "Version of VRM model", 11 | "type": "string" 12 | }, 13 | "author": { 14 | "description": "Author of VRM model", 15 | "type": "string" 16 | }, 17 | "contactInformation": { 18 | "description": "Contact Information of VRM model author", 19 | "type": "string" 20 | }, 21 | "reference": { 22 | "description": "Reference of VRM model", 23 | "type": "string" 24 | }, 25 | "texture": { 26 | "description": "Thumbnail of VRM model", 27 | "type": "integer" 28 | }, 29 | "allowedUserName": { 30 | "description": "A person who can perform with this avatar", 31 | "type": "string", 32 | "enum": ["OnlyAuthor","ExplicitlyLicensedPerson","Everyone"] 33 | }, 34 | "violentUssageName": { 35 | "description": "Permission to perform violent acts with this avatar", 36 | "type": "string", 37 | "enum": ["Disallow","Allow"] 38 | }, 39 | "sexualUssageName": { 40 | "description": "Permission to perform sexual acts with this avatar", 41 | "type": "string", 42 | "enum": ["Disallow","Allow"] 43 | }, 44 | "commercialUssageName": { 45 | "description": "For commercial use", 46 | "type": "string", 47 | "enum": ["Disallow","Allow"] 48 | }, 49 | "otherPermissionUrl": { 50 | "description": "If there are any conditions not mentioned above, put the URL link of the license document here.", 51 | "type": "string" 52 | }, 53 | "licenseName": { 54 | "description": "License type", 55 | "type": "string", 56 | "enum": ["Redistribution_Prohibited","CC0","CC_BY","CC_BY_NC","CC_BY_SA","CC_BY_NC_SA","CC_BY_ND","CC_BY_NC_ND","Other"] 57 | }, 58 | "otherLicenseUrl": { 59 | "description": "If “Other” is selected, put the URL link of the license document here.", 60 | "type": "string" 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /specification/0.0/schema/vrm.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "vrm", 3 | "description": "VRM extension is for 3d humanoid avatars (and models) in VR applications.", 4 | "type": "object", 5 | "properties": { 6 | "exporterVersion": { 7 | "description": "Version of exporter that vrm created. UniVRM-0.46", 8 | "type": "string" 9 | }, 10 | "specVersion": { 11 | "description": "Version of VRM specification. 0.0", 12 | "type": "string" 13 | }, 14 | "meta": { 15 | "$ref": "vrm.meta.schema.json" 16 | }, 17 | "humanoid": { 18 | "$ref": "vrm.humanoid.schema.json" 19 | }, 20 | "firstPerson": { 21 | "$ref": "vrm.firstperson.schema.json" 22 | }, 23 | "blendShapeMaster": { 24 | "$ref": "vrm.blendshape.schema.json" 25 | }, 26 | "secondaryAnimation": { 27 | "$ref": "vrm.secondaryanimation.schema.json" 28 | }, 29 | "materialProperties": { 30 | "type": "array", 31 | "items": { 32 | "$ref": "vrm.material.schema.json" 33 | } 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /specification/0.0/schema/vrm.secondaryanimation.collidergroup.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "vrm.secondaryanimation.collidergroup", 3 | "type": "object", 4 | "properties": { 5 | "node": { 6 | "description": "The node of the collider group for setting up collision detections.", 7 | "type": "integer" 8 | }, 9 | "colliders": { 10 | "type": "array", 11 | "items": { 12 | "type": "object", 13 | "properties": { 14 | "offset": { 15 | "description": "The local coordinate from the node of the collider group in *left-handed* Y-up coordinate.", 16 | "type": "object", 17 | "properties": { 18 | "x": { 19 | "type": "number" 20 | }, 21 | "y": { 22 | "type": "number" 23 | }, 24 | "z": { 25 | "type": "number" 26 | } 27 | } 28 | }, 29 | "radius": { 30 | "description": "The radius of the collider.", 31 | "type": "number" 32 | } 33 | } 34 | } 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /specification/0.0/schema/vrm.secondaryanimation.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "vrm.secondaryanimation", 3 | "description": "The setting of automatic animation of string-like objects such as tails and hairs.", 4 | "type": "object", 5 | "properties": { 6 | "boneGroups": { 7 | "type": "array", 8 | "items": { 9 | "$ref": "vrm.secondaryanimation.spring.schema.json" 10 | } 11 | }, 12 | "colliderGroups": { 13 | "type": "array", 14 | "items": { 15 | "$ref": "vrm.secondaryanimation.collidergroup.schema.json" 16 | } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /specification/0.0/schema/vrm.secondaryanimation.spring.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "vrm.secondaryanimation.spring", 3 | "type": "object", 4 | "properties": { 5 | "comment": { 6 | "description": "Annotation comment", 7 | "type": "string" 8 | }, 9 | "stiffiness": { 10 | "description": "The resilience of the swaying object (the power of returning to the initial pose).", 11 | "type": "number" 12 | }, 13 | "gravityPower": { 14 | "description": "The strength of gravity.", 15 | "type": "number" 16 | }, 17 | "gravityDir": { 18 | "description": "The direction of gravity. Set (0, -1, 0) for simulating the gravity. Set (1, 0, 0) for simulating the wind.", 19 | "type": "object", 20 | "properties": { 21 | "x": { 22 | "type": "number" 23 | }, 24 | "y": { 25 | "type": "number" 26 | }, 27 | "z": { 28 | "type": "number" 29 | } 30 | } 31 | }, 32 | "dragForce": { 33 | "description": "The resistance (deceleration) of automatic animation.", 34 | "type": "number" 35 | }, 36 | "center": { 37 | "description": "The reference point of a swaying object can be set at any location except the origin. When implementing UI moving with warp, the parent node to move with warp can be specified if you don't want to make the object swaying with warp movement.", 38 | "type": "integer" 39 | }, 40 | "hitRadius": { 41 | "description": "The radius of the sphere used for the collision detection with colliders.", 42 | "type": "number" 43 | }, 44 | "bones": { 45 | "description": "Specify the node index of the root bone of the swaying object.", 46 | "type": "array", 47 | "items": { 48 | "type": "integer" 49 | } 50 | }, 51 | "colliderGroups": { 52 | "description": "Specify the index of the collider group for collisions with swaying objects.", 53 | "type": "array", 54 | "items": { 55 | "type": "integer" 56 | } 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /specification/VRMC_materials_hdr_emissiveMultiplier-1.0/README.ja.md: -------------------------------------------------------------------------------- 1 | # VRMC_materials_hdr_emissiveMultiplier 2 | 3 | ## Contributors 4 | 5 | * 角 真宇 6 | * 小渕 豊 7 | * 進藤 哲郎 8 | 9 | ## Status 10 | 11 | Archived 12 | 13 | Superseded by [KHR_materials_emissive_strength](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md) 14 | 15 | ## Dependencies 16 | 17 | Written against the glTF 2.0 spec. 18 | 19 | ## Overview 20 | 21 | この拡張は、マテリアルの EmissiveFactor の値に乗算してこれを上書きします。 22 | 1 よりも大きい値の EmissiveFactor を持つことができます。 23 | 24 | マテリアルの `extensions` に定義します。 25 | 26 | ```json 27 | { 28 | "materials": [ 29 | { 30 | "name": "MyPBRMaterial", 31 | // emission 32 | "emissiveTexture": { 33 | }, 34 | "emissiveFactor": [1, 1, 1], 35 | // extension 36 | "extensions": { 37 | "VRMC_materials_hdr_emissiveMultiplier": { 38 | "emissiveMultiplier": 2.0, 39 | } 40 | } 41 | } 42 | ] 43 | } 44 | ``` 45 | 46 | ## Defined Properties 47 | 48 | | | 型 | 説明 | 必須 | 49 | |--------------------|--------|---------------------------------|:-----| 50 | | emissiveMultiplier | number | A multiplier for emissiveFactor | ✅ | 51 | 52 | 対象 material の material.emissiveFactor を emissiveMultiplier で乗算した値で上書きします。 53 | この値はリニアです。 54 | 55 | ## export 時の変換例 56 | 57 | 以下のように変換してください。 58 | 59 | ```js 60 | // linear color space 61 | let hdr_emissive_factor = [r, g, b]; 62 | 63 | let max_component = r; 64 | if(g>max_component) 65 | { 66 | max_component = g; 67 | } 68 | if(b>max_component) 69 | { 70 | max_component = b; 71 | } 72 | 73 | if(max_component>1) 74 | { 75 | // linear color space 76 | let emissiveFactor = [r/max_component, g/max_component, b/max_component]; 77 | let emissiveMultiplier = max_component; 78 | // VRMC_materials_hdr_emissiveMultiplier により1を越える emissive factor 値を表します 79 | } 80 | else{ 81 | // linear color space 82 | let emissiveFactor = [r, g, b]; 83 | let emissiveMultiplier = null; 84 | // VRMC_materials_hdr_emissiveMultiplier 拡張は不要です 85 | } 86 | ``` 87 | -------------------------------------------------------------------------------- /specification/VRMC_materials_hdr_emissiveMultiplier-1.0/README.md: -------------------------------------------------------------------------------- 1 | # VRMC_materials_hdr_emissiveMultiplier 2 | 3 | *Version 1.0* 4 | 5 | ## Contributors 6 | 7 | * Sumi Masataka 8 | * Obuchi Yutaka 9 | * Shindo Tetsuro 10 | 11 | ## Status 12 | 13 | Archived 14 | 15 | Superseded by [KHR_materials_emissive_strength](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md) 16 | 17 | ## Dependencies 18 | 19 | Written against the glTF 2.0 spec. 20 | 21 | ## Overview 22 | 23 | This extension multiplies and overrides the material's EmissiveFactor value. 24 | You can have an EmissiveFactor with a value greater than 1. 25 | 26 | Define it in the material `extensions`. 27 | 28 | ```json 29 | { 30 | "materials": [ 31 | { 32 | "name": "MyPBRMaterial", 33 | // emission 34 | "emissiveTexture": { 35 | }, 36 | "emissiveFactor": [1, 1, 1], 37 | // extension 38 | "extensions": { 39 | "VRMC_materials_hdr_emissiveMultiplier": { 40 | "emissiveMultiplier": 2.0, 41 | } 42 | } 43 | } 44 | ] 45 | } 46 | ``` 47 | 48 | ## Defined Properties 49 | 50 | | | Type | Description | Required | 51 | |--------------------|--------|---------------------------------|:---------| 52 | | emissiveMultiplier | number | A multiplier for emissiveFactor | ✅ | 53 | 54 | Overwrite material.emissiveFactor of the target material with the value multiplied by emissiveMultiplier. 55 | This value is linear. 56 | 57 | ## Conversion example at the time of export 58 | 59 | Convert as follows. 60 | 61 | ```js 62 | // linear color space 63 | let hdr_emissive_factor = [r, g, b]; 64 | 65 | let max_component = r; 66 | if (g> max_component) 67 | { 68 | max_component = g; 69 | } 70 | if (b> max_component) 71 | { 72 | max_component = b; 73 | } 74 | 75 | if (max_component> 1) 76 | { 77 | // linear color space 78 | let emissiveFactor = [r / max_component, g / max_component, b / max_component]; 79 | let emissiveMultiplier = max_component; 80 | // VRMC_materials_hdr_emissiveMultiplier represents an emissive factor value greater than 1. 81 | } 82 | else { 83 | // linear color space 84 | let emissiveFactor = [r, g, b]; 85 | let emissiveMultiplier = null; 86 | // VRMC_materials_hdr_emissiveMultiplier extension not required 87 | } 88 | ``` 89 | -------------------------------------------------------------------------------- /specification/VRMC_materials_hdr_emissiveMultiplier-1.0/schema/VRMC_materials_hdr_emissiveMultiplier.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "VRMC_materials_hdr_emissiveMultiplier", 3 | "type": "object", 4 | "description": "A multiplier for emissiveFactor", 5 | "allOf": [ 6 | { 7 | "$ref": "glTFProperty.schema.json" 8 | } 9 | ], 10 | "properties": { 11 | "emissiveMultiplier": { 12 | "type": "number", 13 | "description": "A multiplier for emissiveFactor", 14 | "default": 1.0, 15 | "minimum": 0.0 16 | }, 17 | "extensions": {}, 18 | "extras": {} 19 | }, 20 | "required": [ 21 | "emissiveMultiplier" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /specification/VRMC_materials_mtoon-1.0/MToon_comparision.md: -------------------------------------------------------------------------------- 1 | # **This document is outdated.** 2 | 3 | * 0.0 is derived from property name of unity shader 4 | * 1.0 is json.key 5 | 6 | | 0.0 | 1.0draft | new color space*1 or type | memo | 7 | |---------------------------|-------------------------------------------------------------------------------------------|---------------------------------|-------------------------| 8 | | _MToonVersion | materials.i.extensions.VRMC_materials_mtoon.version | int->str | | 9 | | _BlendMode | materials.i.alphaMode *3 | int->Enum(str) | | 10 | | | materials.i.extensions.VRMC_materials_mtoon.transparentWithZWrite | bool | | 11 | | _CullMode | materials.i.doubleSided | int->bool | none=>true, back=>false | 12 | | renderQueue | materials.i.extensions.VRMC_materials_mtoon.renderQueueOffsetNumber *2 | int | | 13 | | _Color | materials.i.pbrMetallicRoughness.baseColorFactor | Linear | | 14 | | _MainTex | materials.i.pbrMetallicRoughness.baseColorTexture.index | sRGB | | 15 | | _ShadeColor | materials.i.extensions.VRMC_materials_mtoon.shadeFactor | Linear | | 16 | | _ShadeTexture | materials.i.extensions.VRMC_materials_mtoon.shadeMultiplyTexture | sRGB | | 17 | | _Cutoff | materials.i.alphaCutoff | mixed decimal | | 18 | | _ShadeShift | materials.i.extensions.VRMC_materials_mtoon.shadingShiftFactor | mixed decimal | | 19 | | _ShadeToony | materials.i.extensions.VRMC_materials_mtoon.shadingToonyFactor | mixed decimal | | 20 | | _ReceiveShadowRate | materials.i.extensions.VRMC_materials_mtoon.shadowReceiveMultiplierFactor | mixed decimal | | 21 | | _ReceiveShadowTexture | ~~shadowReceiveMultiplierMultiplyTexture~~ | Linear | Will be deleted | 22 | | _ShadingGradeRate | ~~litAndShadeMixingMultiplierFactor~~ | mixed decimal | Will be deleted | 23 | | _ShadingGradeTexture | ~~litAndShadeMixingMultiplierMultiplyTexture~~ | Linear | Will be deleted | 24 | | _LightColorAttenuation | ~~lightColorAttenuationFactor~~ | mixed decimal | Will be deleted | 25 | | _IndirectLightIntensity | materials.i.extensions.VRMC_materials_mtoon.giIntensityFactor | mixed decimal | | 26 | | _BumpMap | materials.i.extensions.VRMC_materials_mtoon.normalTexture.index | Linear | | 27 | | _BumpScale | materials.i.extensions.VRMC_materials_mtoon.normalTexture.scale | mixed decimal | | 28 | | _EmissionColor | materials.i.emissiveFactor | Linear | | 29 | | _EmissionMap | materials.i.emissiveTexture.index | sRGB | | 30 | | _SphereAdd | materials.i.extensions.additiveTexture | sRGB | | 31 | | _RimColor | materials.i.extensions.rimFactor | Linear | | 32 | | _RimTexture | materials.i.extensions.rimMultiplyTexture | sRGB | | 33 | | _RimLightingMix | materials.i.extensions.rimLightingMixFactor | mixed decimal | | 34 | | _RimFresnelPower | materials.i.extensions.rimFresnelPowerFactor | mixed decimal | | 35 | | _RimLift | materials.i.extensions.rimLiftFactor | mixed decimal | | 36 | | _OutlineWidthMode | materials.i.extensions.outlineWidthMode | int->Enum(str) | | 37 | | _OutlineColor | materials.i.extensions.outlineWidthFactor | Linear | | 38 | | _OutlineWidthTexture | materials.i.extensions.outlineWidthMultiplyTexture | Linear | | 39 | | _OutlineScaledMaxDistance | materials.i.extensions.outlineScaledMaxDistanceFactor | mixed decimal | | 40 | | _OutlineLightingMix | materials.i.extensions.outlineColorMode | int->Enum(str) | | 41 | | _OutlineWidth | materials.i.extensions.outlineFactor | mixed decimal | | 42 | | _OutlineLightingMix | materials.i.extensions.outlineLightingMixFactor | mixed decimal | | 43 | | _MainTex | materials.i.pbrMetallicRoughness.baseColorTexture.extensions.KHR_texture_transform.offset | _Maintex[0:2] ->2 mixed decimal | | 44 | | _MainTex | materials.i.pbrMetallicRoughness.baseColorTexture.extensions.KHR_texture_transform.scale | _Maintex[2:4] ->2 mixed decimal | | 45 | | _UvAnimMaskTexture | materials.i.extensions.uvAnimationMaskTexture | Linear | | 46 | | _UvAnimScrollX | materials.i.extensions.uvAnimationScrollXSpeedFactor | mixed decimal | | 47 | | _UvAnimScrollY | materials.i.extensions.uvAnimationScrollYSpeedFactor | mixed decimal | | 48 | | _UvAnimRotation | materials.i.extensions.uvAnimationRotationSpeedFactor | mixed decimal | | 49 | 50 | *1 (0.0 is confused by implementation then no discription) 51 | *2 (0.0 is value, 1.0draft is offset from basical value(undefined@2019/12/6)) 52 | *3 transparentWithZWrite to alphaMode=transparent and extensions.vrmc_materials_mtoon.transparentWithZWrite=true 53 | -------------------------------------------------------------------------------- /specification/VRMC_materials_mtoon-1.0/figures/mtoon-lit-shade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrm-c/vrm-specification/c24d76d99a18738dd2c266be1c83f089064a7b5e/specification/VRMC_materials_mtoon-1.0/figures/mtoon-lit-shade.png -------------------------------------------------------------------------------- /specification/VRMC_materials_mtoon-1.0/figures/mtoon-shading-ramp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrm-c/vrm-specification/c24d76d99a18738dd2c266be1c83f089064a7b5e/specification/VRMC_materials_mtoon-1.0/figures/mtoon-shading-ramp.png -------------------------------------------------------------------------------- /specification/VRMC_materials_mtoon-1.0/schema/VRMC_materials_mtoon.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "VRMC_materials_mtoon", 3 | "type": "object", 4 | "description": "", 5 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 6 | "properties": { 7 | "specVersion": { 8 | "type": "string", 9 | "description": "Specification version of VRMC_materials_mtoon" 10 | }, 11 | "transparentWithZWrite": { 12 | "type": "boolean", 13 | "default": "false", 14 | "description": "enable depth buffer when `alphaMode` is `BLEND`" 15 | }, 16 | "renderQueueOffsetNumber": { 17 | "type": "integer", 18 | "description": "", 19 | "default": 0, 20 | "minimum": -9, 21 | "maximum": 9 22 | }, 23 | "shadeColorFactor": { 24 | "type": "array", 25 | "description": "", 26 | "items": { 27 | "type": "number", 28 | "minimum": 0.0, 29 | "maximum": 1.0 30 | }, 31 | "default": [ 1.0, 1.0, 1.0 ], 32 | "minItems": 3, 33 | "maxItems": 3 34 | }, 35 | "shadeMultiplyTexture": { 36 | "allOf": [ { "$ref": "textureInfo.schema.json" } ], 37 | "description": "" 38 | }, 39 | "shadingShiftFactor": { 40 | "type": "number", 41 | "description": "Lighting", 42 | "default": 0.0 43 | }, 44 | "shadingShiftTexture": { 45 | "allOf": [ { "$ref": "mtoon.shadingShiftTexture.schema.json" } ] 46 | }, 47 | "shadingToonyFactor": { 48 | "type": "number", 49 | "description": "", 50 | "default": 0.9, 51 | "minimum": 0.0, 52 | "maximum": 1.0 53 | }, 54 | "giEqualizationFactor": { 55 | "type": "number", 56 | "description": "", 57 | "default": 0.9, 58 | "minimum": 0.0, 59 | "maximum": 1.0 60 | }, 61 | "matcapFactor": { 62 | "type": "array", 63 | "description": "", 64 | "items": { 65 | "type": "number", 66 | "minimum": 0.0, 67 | "maximum": 1.0 68 | }, 69 | "default": [ 1.0, 1.0, 1.0 ], 70 | "minItems": 3, 71 | "maxItems": 3 72 | }, 73 | "matcapTexture": { 74 | "allOf": [ { "$ref": "textureInfo.schema.json" } ], 75 | "description": "MatCap" 76 | }, 77 | "parametricRimColorFactor": { 78 | "type": "array", 79 | "description": "Rim", 80 | "items": { 81 | "type": "number", 82 | "minimum": 0.0, 83 | "maximum": 1.0 84 | }, 85 | "default": [ 0.0, 0.0, 0.0 ], 86 | "minItems": 3, 87 | "maxItems": 3 88 | }, 89 | "rimMultiplyTexture": { 90 | "allOf": [ { "$ref": "textureInfo.schema.json" } ], 91 | "description": "" 92 | }, 93 | "rimLightingMixFactor": { 94 | "type": "number", 95 | "description": "", 96 | "default": 1.0, 97 | "minimum": 0.0, 98 | "maximum": 1.0 99 | }, 100 | "parametricRimFresnelPowerFactor": { 101 | "type": "number", 102 | "description": "", 103 | "default": 5.0, 104 | "minimum": 0.0 105 | }, 106 | "parametricRimLiftFactor": { 107 | "type": "number", 108 | "description": "", 109 | "default": 0.0 110 | }, 111 | "outlineWidthMode": { 112 | "title": "OutlineWidthMode", 113 | "type": "string", 114 | "enum": [ 115 | "none", 116 | "worldCoordinates", 117 | "screenCoordinates" 118 | ], 119 | "default": "none", 120 | "description": "Outline" 121 | }, 122 | "outlineWidthFactor": { 123 | "type": "number", 124 | "description": "", 125 | "default": 0.0, 126 | "minimum": 0.0 127 | }, 128 | "outlineWidthMultiplyTexture": { 129 | "allOf": [ { "$ref": "textureInfo.schema.json" } ], 130 | "description": "" 131 | }, 132 | "outlineColorFactor": { 133 | "type": "array", 134 | "description": "", 135 | "items": { 136 | "type": "number", 137 | "minimum": 0.0, 138 | "maximum": 1.0 139 | }, 140 | "default": [ 0.0, 0.0, 0.0 ], 141 | "minItems": 3, 142 | "maxItems": 3 143 | }, 144 | "outlineLightingMixFactor": { 145 | "type": "number", 146 | "description": "", 147 | "default": 1.0, 148 | "minimum": 0.0, 149 | "maximum": 1.0 150 | }, 151 | "uvAnimationMaskTexture": { 152 | "allOf": [ { "$ref": "textureInfo.schema.json" } ], 153 | "description": "" 154 | }, 155 | "uvAnimationScrollXSpeedFactor": { 156 | "type": "number", 157 | "default": 0, 158 | "description": "" 159 | }, 160 | "uvAnimationScrollYSpeedFactor": { 161 | "type": "number", 162 | "default": 0, 163 | "description": "" 164 | }, 165 | "uvAnimationRotationSpeedFactor": { 166 | "type": "number", 167 | "default": 0, 168 | "description": "" 169 | }, 170 | "extensions": { }, 171 | "extras": { } 172 | }, 173 | "required": [ 174 | "specVersion" 175 | ] 176 | } 177 | -------------------------------------------------------------------------------- /specification/VRMC_materials_mtoon-1.0/schema/mtoon.shadingShiftTexture.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema", 3 | "title": "Shading Shift Texture Info", 4 | "type": "object", 5 | "allOf": [ { "$ref": "textureInfo.schema.json" } ], 6 | "properties": { 7 | "index": { }, 8 | "texCoord": { }, 9 | "scale": { 10 | "type": "number", 11 | "description": "The scalar multiplier applied to the texture.", 12 | "default": 1.0 13 | }, 14 | "extensions": { }, 15 | "extras": { } 16 | } 17 | } -------------------------------------------------------------------------------- /specification/VRMC_node_constraint-1.0/schema/VRMC_node_constraint.aimConstraint.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema", 3 | "title": "Aim Constraint", 4 | "type": "object", 5 | "description": "A constraint that makes it look at a source object.", 6 | "allOf": [ { "$ref": "glTFChildOfRootProperty.schema.json" } ], 7 | "properties": { 8 | "source": { 9 | "allOf": [ { "$ref": "glTFid.schema.json" } ], 10 | "description": "The index of the node constrains the node." 11 | }, 12 | "aimAxis": { 13 | "description": "The aim axis of the constraint.", 14 | "type": "string", 15 | "enum": [ "PositiveX", "NegativeX", "PositiveY", "NegativeY", "PositiveZ", "NegativeZ" ] 16 | }, 17 | "weight": { 18 | "type": "number", 19 | "description": "The weight of the constraint.", 20 | "minimum": 0.0, 21 | "maximum": 1.0, 22 | "default": 1.0 23 | }, 24 | "extensions": { }, 25 | "extras": { } 26 | }, 27 | "required": [ "source", "aimAxis" ] 28 | } 29 | -------------------------------------------------------------------------------- /specification/VRMC_node_constraint-1.0/schema/VRMC_node_constraint.constraint.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema", 3 | "title": "Constraint", 4 | "type": "object", 5 | "description": "Contains roll, aim, or rotation", 6 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 7 | "properties": { 8 | "roll": { 9 | "$ref": "VRMC_node_constraint.rollConstraint.schema.json" 10 | }, 11 | "aim": { 12 | "$ref": "VRMC_node_constraint.aimConstraint.schema.json" 13 | }, 14 | "rotation": { 15 | "$ref": "VRMC_node_constraint.rotationConstraint.schema.json" 16 | }, 17 | "extensions": { }, 18 | "extras": { } 19 | }, 20 | "oneOf": [ 21 | { "required": [ "roll" ] }, 22 | { "required": [ "aim" ] }, 23 | { "required": [ "rotation" ] } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /specification/VRMC_node_constraint-1.0/schema/VRMC_node_constraint.rollConstraint.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema", 3 | "title": "Roll Constraint", 4 | "type": "object", 5 | "description": "A constraint that transfers a rotation around one axis of a source.", 6 | "allOf": [ { "$ref": "glTFChildOfRootProperty.schema.json" } ], 7 | "properties": { 8 | "source": { 9 | "allOf": [ { "$ref": "glTFid.schema.json" } ], 10 | "description": "The index of the node constrains the node." 11 | }, 12 | "rollAxis": { 13 | "description": "The roll axis of the constraint.", 14 | "type": "string", 15 | "enum": [ "X", "Y", "Z" ] 16 | }, 17 | "weight": { 18 | "type": "number", 19 | "description": "The weight of the constraint.", 20 | "minimum": 0.0, 21 | "maximum": 1.0, 22 | "default": 1.0 23 | }, 24 | "extensions": { }, 25 | "extras": { } 26 | }, 27 | "required": [ "source", "rollAxis" ] 28 | } 29 | -------------------------------------------------------------------------------- /specification/VRMC_node_constraint-1.0/schema/VRMC_node_constraint.rotationConstraint.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema", 3 | "title": "Rotation Constraint", 4 | "type": "object", 5 | "description": "A constraint that links the rotation with a source.", 6 | "allOf": [ { "$ref": "glTFChildOfRootProperty.schema.json" } ], 7 | "properties": { 8 | "source": { 9 | "allOf": [ { "$ref": "glTFid.schema.json" } ], 10 | "description": "The index of the node constrains the node." 11 | }, 12 | "weight": { 13 | "type": "number", 14 | "description": "The weight of the constraint.", 15 | "minimum": 0.0, 16 | "maximum": 1.0, 17 | "default": 1.0 18 | }, 19 | "extensions": { }, 20 | "extras": { } 21 | }, 22 | "required": [ "source" ] 23 | } 24 | -------------------------------------------------------------------------------- /specification/VRMC_node_constraint-1.0/schema/VRMC_node_constraint.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema", 3 | "title": "VRMC_node_constraint extension", 4 | "type": "object", 5 | "description": "glTF extension that defines constraints.", 6 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 7 | "properties": { 8 | "specVersion": { 9 | "type": "string", 10 | "description": "Specification version of VRMC_node_constraint" 11 | }, 12 | "constraint": { 13 | "$ref": "VRMC_node_constraint.constraint.schema.json" 14 | }, 15 | "extensions": { }, 16 | "extras": { } 17 | }, 18 | "required": [ "specVersion", "constraint" ] 19 | } 20 | -------------------------------------------------------------------------------- /specification/VRMC_springBone-1.0/schema/VRMC_springBone.collider.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Collider", 3 | "type": "object", 4 | "description": "collider definition for SpringBone", 5 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 6 | "properties": { 7 | "node": { 8 | "allOf": [ { "$ref": "glTFid.schema.json" } ], 9 | "description": "The node index." 10 | }, 11 | "shape": { 12 | "allOf": [ { "$ref": "VRMC_springBone.shape.schema.json" } ], 13 | "description": "" 14 | }, 15 | "extensions": { }, 16 | "extras": { } 17 | }, 18 | "required": [ 19 | "node", 20 | "shape" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /specification/VRMC_springBone-1.0/schema/VRMC_springBone.colliderGroup.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "ColliderGroup", 3 | "type": "object", 4 | "description": "collider group definition for SpringBone", 5 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 6 | "properties": { 7 | "name": { 8 | "type": "string", 9 | "description": "Name of the ColliderGroup" 10 | }, 11 | "colliders": { 12 | "type": "array", 13 | "items": { 14 | "$ref": "glTFid.schema.json" 15 | }, 16 | "description": "An array of colliders.", 17 | "minItems": 1 18 | }, 19 | "extensions": { }, 20 | "extras": { } 21 | }, 22 | "required": [ 23 | "colliders" 24 | ] 25 | } -------------------------------------------------------------------------------- /specification/VRMC_springBone-1.0/schema/VRMC_springBone.joint.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "SpringBoneJoint", 3 | "type": "object", 4 | "description": "A bone joint of VRMCSpringBone.", 5 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 6 | "properties": { 7 | "node": { 8 | "allOf": [ { "$ref": "glTFid.schema.json" } ], 9 | "description": "The node index." 10 | }, 11 | "hitRadius": { 12 | "type": "number", 13 | "description": "The radius of spring sphere.", 14 | "default": 0.0, 15 | "minimum": 0.0 16 | }, 17 | "stiffness": { 18 | "type": "number", 19 | "description": "The force to return to the initial pose.", 20 | "default": 1.0, 21 | "minimum": 0.0 22 | }, 23 | "gravityPower": { 24 | "type": "number", 25 | "description": "Gravitational acceleration.", 26 | "default": 0.0, 27 | "minimum": 0.0 28 | }, 29 | "gravityDir": { 30 | "type": "array", 31 | "description": "The direction of gravity. A gravity other than downward direction also works.", 32 | "items": { 33 | "type": "number" 34 | }, 35 | "minItems": 3, 36 | "maxItems": 3, 37 | "default": [ 38 | 0.0, 39 | -1.0, 40 | 0.0 41 | ] 42 | }, 43 | "dragForce": { 44 | "type": "number", 45 | "description": "Air resistance. Deceleration force.", 46 | "default": 0.5, 47 | "minimum": 0.0, 48 | "maximum": 1.0 49 | }, 50 | "extensions": { }, 51 | "extras": { } 52 | }, 53 | "required": [ 54 | "node" 55 | ] 56 | } 57 | -------------------------------------------------------------------------------- /specification/VRMC_springBone-1.0/schema/VRMC_springBone.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "VRMCSpringBone", 3 | "type": "object", 4 | "description": "SpringBone makes objects such as costumes and hair swaying", 5 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 6 | "properties": { 7 | "specVersion": { 8 | "type": "string", 9 | "description": "Specification version of VRMC_springBone" 10 | }, 11 | "colliders": { 12 | "type": "array", 13 | "description": "An array of colliders.", 14 | "items": { 15 | "$ref": "VRMC_springBone.collider.schema.json" 16 | }, 17 | "minItems": 1 18 | }, 19 | "colliderGroups": { 20 | "type": "array", 21 | "description": "An array of colliderGroups.", 22 | "items": { 23 | "$ref": "VRMC_springBone.colliderGroup.schema.json" 24 | }, 25 | "minItems": 1 26 | }, 27 | "springs": { 28 | "type": "array", 29 | "description": "An array of springs.", 30 | "items": { 31 | "$ref": "VRMC_springBone.spring.schema.json" 32 | }, 33 | "minItems": 1 34 | }, 35 | "extensions": { }, 36 | "extras": { } 37 | }, 38 | "required": [ "specVersion" ] 39 | } 40 | -------------------------------------------------------------------------------- /specification/VRMC_springBone-1.0/schema/VRMC_springBone.shape.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "ColliderShape", 3 | "type": "object", 4 | "description": "Shape of collider. Have one of sphere and capsule", 5 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 6 | "properties": { 7 | "sphere": { 8 | "type": "object", 9 | "title": "ColliderShapeSphere", 10 | "properties": { 11 | "offset": { 12 | "type": "array", 13 | "description": "The sphere center. vector3", 14 | "items": { 15 | "type": "number" 16 | }, 17 | "default": [0.0, 0.0, 0.0], 18 | "minItems": 3, 19 | "maxItems": 3 20 | }, 21 | "radius": { 22 | "type": "number", 23 | "description": "The sphere radius", 24 | "default": 0.0, 25 | "minimum": 0.0 26 | } 27 | } 28 | }, 29 | "capsule": { 30 | "type": "object", 31 | "title": "ColliderShapeCapsule", 32 | "properties": { 33 | "offset": { 34 | "type": "array", 35 | "description": "The capsule head. vector3", 36 | "items": { 37 | "type": "number" 38 | }, 39 | "default": [0.0, 0.0, 0.0], 40 | "minItems": 3, 41 | "maxItems": 3 42 | }, 43 | "radius": { 44 | "type": "number", 45 | "description": "The capsule radius", 46 | "default": 0.0, 47 | "minimum": 0.0 48 | }, 49 | "tail": { 50 | "type": "array", 51 | "description": "The capsule tail. vector3", 52 | "items": { 53 | "type": "number" 54 | }, 55 | "default": [0.0, 0.0, 0.0], 56 | "minItems": 3, 57 | "maxItems": 3 58 | } 59 | } 60 | }, 61 | "extensions": { }, 62 | "extras": { } 63 | }, 64 | "oneOf": [ 65 | { "required": [ "sphere" ] }, 66 | { "required": [ "capsule" ] } 67 | ] 68 | } -------------------------------------------------------------------------------- /specification/VRMC_springBone-1.0/schema/VRMC_springBone.spring.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Spring", 3 | "type": "object", 4 | "description": "A bone group of VRMCSpringBone.", 5 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 6 | "properties": { 7 | "name": { 8 | "type": "string", 9 | "description": "Name of the Spring" 10 | }, 11 | "joints": { 12 | "type": "array", 13 | "description": "Joints of the spring. Except for the first element, a previous joint of the array must be an ancestor of the joint.", 14 | "items": { 15 | "$ref": "VRMC_springBone.joint.schema.json" 16 | }, 17 | "minItems": 1 18 | }, 19 | "colliderGroups": { 20 | "type": "array", 21 | "description": "Indices of ColliderGroups that detect collision with this spring.", 22 | "items": { 23 | "$ref": "glTFid.schema.json", 24 | "description": "Index in colliderGroups." 25 | }, 26 | "minItems": 1 27 | }, 28 | "center": { 29 | "allOf": [ { "$ref": "glTFid.schema.json" } ], 30 | "description": "An index of node which is used as a root of center space." 31 | }, 32 | "extensions": { }, 33 | "extras": { } 34 | }, 35 | "required": [ 36 | "joints" 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /specification/VRMC_springBone_extended_collider-1.0/README.ja.md: -------------------------------------------------------------------------------- 1 | # VRMC_springBone_extended_collider-1.0 2 | 3 | *Version 1.0* 4 | 5 | 6 | 7 | 8 | 9 | - [Contributors](#contributors) 10 | - [Status](#status) 11 | - [Dependencies](#dependencies) 12 | - [Overview](#overview) 13 | - [Extended Colliders](#extended-colliders) 14 | - [Inside Sphere Collider](#inside-sphere-collider) 15 | - [Inside Capsule Collider](#inside-capsule-collider) 16 | - [Plane Collider](#plane-collider) 17 | - [glTF Schema Updates](#gltf-schema-updates) 18 | - [Extending Colliders](#extending-colliders) 19 | - [Exporter Implemantation](#exporter-implemantation) 20 | - [Fallback: Inside Sphere Collider / Inside Sphere Collider](#fallback-inside-sphere-collider---inside-sphere-collider) 21 | - [Fallback: Plane Collider](#fallback-plane-collider) 22 | - [VRMC_springBone_extended_collider](#vrmc_springbone_extended_collider) 23 | - [Properties](#properties) 24 | - [JSON Schema](#json-schema) 25 | - [VRMC_springBone_extended_collider.specVersion ✅](#vrmc_springbone_extended_colliderspecversion-) 26 | - [VRMC_springBone_extended_collider.shape](#vrmc_springbone_extended_collidershape) 27 | - [Shape](#shape) 28 | - [Properties](#properties-1) 29 | - [JSON Schema](#json-schema-1) 30 | - [Shape.sphere](#shapesphere) 31 | - [Shape.capsule](#shapecapsule) 32 | - [Shape.plane](#shapeplane) 33 | - [ShapeSphere](#shapesphere) 34 | - [Properties](#properties-2) 35 | - [ShapeSphere.offset](#shapesphereoffset) 36 | - [ShapeSphere.radius](#shapesphereradius) 37 | - [ShapeSphere.inside](#shapesphereinside) 38 | - [ShapeCapsule](#shapecapsule) 39 | - [Properties](#properties-3) 40 | - [ShapeCapsule.offset](#shapecapsuleoffset) 41 | - [ShapeCapsule.radius](#shapecapsuleradius) 42 | - [ShapeCapsule.tail](#shapecapsuletail) 43 | - [ShapeCapsule.inside](#shapecapsuleinside) 44 | - [ShapePlane](#shapeplane) 45 | - [Properties](#properties-4) 46 | - [ShapePlane.offset](#shapeplaneoffset) 47 | - [ShapePlane.normal](#shapeplanenormal) 48 | - [Properties](#properties-5) 49 | - [Appendix: Reference Implementations](#appendix-reference-implementations) 50 | - [Inside Sphere Collider](#inside-sphere-collider-1) 51 | - [Inside Capsule Collider](#inside-capsule-collider-1) 52 | - [Plane Collider](#plane-collider-1) 53 | 54 | 55 | 56 | ## Contributors 57 | 58 | - 0b5vr 59 | 60 | ## Status 61 | 62 | Complete 63 | 64 | ## Dependencies 65 | 66 | glTF 2.0仕様に向けて策定されています。 67 | 68 | 本仕様は [`VRMC_springBone`](https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_springBone-1.0/README.ja.md) に依存します。 69 | 70 | ## Overview 71 | 72 | `VRMC_springBone_extended_collider` 仕様は、 `VRMC_springBone` で定義されたコライダーの形状を追加するglTF拡張です。 73 | 本拡張は、球の内部コライダー・カプセルの内部コライダー・平面コライダーを定義します。 74 | 75 | 本拡張によって追加されるコライダーは、 `VRMC_springBone` で定義されるコライダーと同様に、スプリングボーンの可動範囲を当たり判定によって制限するために使用されます。 76 | 77 | ### Extended Colliders 78 | 79 | 本拡張によって追加されるコライダーは、球の内部コライダー・カプセルの内部コライダー・平面コライダーの3種類です。 80 | 81 | 各コライダーについて、参考実装を[Appendix: Reference Implementations](#appendix-reference-implementations)に示します。 82 | 83 | #### Inside Sphere Collider 84 | 85 | 通常の球コライダーがスプリングボーンを球の外側に制限するのに対して、球の内部コライダーはスプリングボーンを球の内部に制限します。 86 | 87 | 球の内部コライダーは、通常の球コライダーと同様に、ローカル座標系における位置と半径で定義されます。 88 | 89 | #### Inside Capsule Collider 90 | 91 | 通常のカプセルコライダーがスプリングボーンをカプセルの外側に制限するのに対して、カプセルの内部コライダーはスプリングボーンをカプセルの内部に制限します。 92 | 93 | カプセルの内部コライダーは、通常のカプセルコライダーと同様に、ローカル座標系における始点の位置・終点の位置・半径で定義されます。 94 | 95 | #### Plane Collider 96 | 97 | 平面コライダーは、スプリングボーンが平面の片側に制限します。 98 | 平面は無限平面として定義され、有限の大きさを持ちません。 99 | 100 | 平面コライダーは、ローカル座標系における位置と法線ベクトルで定義されます。 101 | 102 | ## glTF Schema Updates 103 | 104 | ### Extending Colliders 105 | 106 | コンストレイントは、 `VRMC_springBone` で定義されたコライダーに `VRMC_springBone_extended_collider` 拡張を追加することで記述されます。 107 | 108 | ```json 109 | { 110 | "extensionsUsed": [ 111 | "VRMC_springBone", 112 | "VRMC_springBone_extended_collider" 113 | ], 114 | "extensions": { 115 | "VRMC_springBone": { 116 | "specVersion": "1.0", 117 | "colliders": [ 118 | { 119 | "node": 0, 120 | "shape": { 121 | "sphere": { 122 | "radius": 0.0, 123 | "offset": [0.0, -10000.0, 0.0] 124 | } 125 | }, 126 | "extensions": { 127 | "VRMC_springBone_extended_collider": { 128 | "specVersion": "1.0", 129 | "shape": { 130 | "sphere": { 131 | "radius": 0.5, 132 | "offset": [0.0, 0.0, 0.0], 133 | "inside": true 134 | } 135 | } 136 | } 137 | } 138 | }, 139 | // ... 140 | ] 141 | } 142 | }, 143 | // 通常のglTF 2.0の情報 144 | "nodes": [ 145 | // ... 146 | ] 147 | } 148 | ``` 149 | 150 | ### Exporter Implemantation 151 | 152 | > *このセクションはnon-normativeです。* 153 | 154 | `VRMC_springBone_extended_collider` 拡張でコライダーが定義されている場合、 `VRMC_springBone_extended_collider` に対応していない環境において適切にフォールバック処理がされるよう、 `VRMC_springBone` で定義されたコライダーには無視もしくは近似されるような値を出力することを推奨します。 155 | 156 | #### Fallback: Inside Sphere Collider / Inside Capsule Collider 157 | 158 | 内部コライダーとなる球・カプセルコライダーが定義されたファイルを出力する際、 `VRMC_springBone_extended_collider` に対応しない環境において、フォールバックのコライダーが影響を及ぼさないよう、位置を原点から遠く離した球コライダーとするなどの回避策を検討してください。 159 | 160 | 以下に、フォールバックのコライダーが影響を及ぼさないように出力する場合の例を示します。 161 | 162 | ```json 163 | // 遠方に半径0の球コライダーを配置し、フォールバック環境において擬似的に無視されるようにする例 164 | "colliders": [ 165 | { 166 | "node": 0, 167 | "shape": { 168 | "sphere": { 169 | "radius": 0.0, 170 | "offset": [0.0, -10000.0, 0.0] 171 | } 172 | }, 173 | "extensions": { 174 | "VRMC_springBone_extended_collider": { 175 | "specVersion": "1.0-draft", 176 | "shape": { 177 | "sphere": { 178 | "radius": 0.5, 179 | "offset": [0.0, 0.0, 0.0], 180 | "inside": true 181 | } 182 | } 183 | } 184 | } 185 | } 186 | ] 187 | ``` 188 | 189 | #### Fallback: Plane Collider 190 | 191 | 平面コライダーが定義されたファイルを出力する際、 `VRMC_springBone_extended_collider` に対応しない環境において、フォールバックのコライダーでも平面コライダーに近い挙動を実現できるよう、半径を十分に大きくした球コライダーとするなどの回避策を検討してください。 192 | 193 | 以下に、フォールバックのコライダーで平面コライダーを近似するように出力する場合の例を示します。 194 | 195 | ```json 196 | // 半径1000の球コライダーを配置し、フォールバック環境において平面コライダーを近似する例 197 | // float 型の精度は約6桁。0.1mm 精度ということで1000にしています。 198 | "colliders": [ 199 | { 200 | "node": 0, 201 | "shape": { 202 | "sphere": { 203 | "radius": 1000.0, 204 | // plane の offset - normal * radius を指定してください 205 | "offset": [0.0, -1000.0, 0.0] 206 | } 207 | }, 208 | "extensions": { 209 | "VRMC_springBone_extended_collider": { 210 | "specVersion": "1.0-draft", 211 | "shape": { 212 | "palne": { 213 | "offset": [0.0, 0.0, 0.0], 214 | "normal": [0.0, 1.0, 0.0], 215 | } 216 | } 217 | } 218 | } 219 | } 220 | ] 221 | ``` 222 | 223 | ### VRMC_springBone_extended_collider 224 | 225 | 本拡張のルートオブジェクトです。 226 | 227 | #### Properties 228 | 229 | ||型|説明|必須| 230 | |:-|:-|:-|:-| 231 | |`specVersion`|`string`|この拡張のバージョン|✅ Yes| 232 | |`shape`|[Shape](#shape)|コライダーの形状|No| 233 | 234 | #### JSON Schema 235 | 236 | [VRMC_springBone_extended_collider.schema.json](schema/VRMC_springBone_extended_collider.schema.json) 237 | 238 | #### VRMC_springBone_extended_collider.specVersion ✅ 239 | 240 | `VRMC_springBone_extended_collider` 拡張のバージョンを示します。値は `"1.0"` でなければなりません。 241 | 242 | - 型: `string` 243 | - 必須: Yes 244 | 245 | #### VRMC_springBone_extended_collider.shape 246 | 247 | コライダーの形状を定義します。 248 | 249 | - 型: [Shape](#shape) 250 | - 必須: No 251 | 252 | ### Shape 253 | 254 | コライダーの形状を定義します。 255 | 256 | [ShapeSphere](#shapesphere)、[ShapeCapsule](#shapecapsule)、[ShapePlane](#shapeplane) のいずれか1つを含まなければいけません。 257 | 258 | #### Properties 259 | 260 | ||型|説明|必須| 261 | |:-|:-|:-|:-| 262 | |`sphere`|[ShapeSphere](#shapesphere)|球コライダー|No| 263 | |`capsule`|[ShapeCapsule](#shapecapsule)|カプセルコライダー|No| 264 | |`plane`|[ShapePlane](#shapeplane)|平面コライダー|No| 265 | 266 | #### JSON Schema 267 | 268 | [VRMC_springBone_extended_collider.shape.schema.json](schema/VRMC_springBone_extended_collider.shape.schema.json) 269 | 270 | #### Shape.sphere 271 | 272 | 球コライダーを定義します。 273 | 274 | - 型: [ShapeSphere](#shapesphere) 275 | - 必須: No 276 | 277 | #### Shape.capsule 278 | 279 | カプセルコライダーを定義します。 280 | 281 | - 型: [ShapeCapsule](#shapecapsule) 282 | - 必須: No 283 | 284 | #### Shape.plane 285 | 286 | 平面コライダーを定義します。 287 | 288 | - 型: [ShapePlane](#shapeplane) 289 | - 必須: No 290 | 291 | ### ShapeSphere 292 | 293 | 球コライダーの形状を定義します。 294 | 295 | #### Properties 296 | 297 | ||型|説明|必須| 298 | |:-|:-|:-|:-| 299 | |`offset`|`number[3]`|ローカル座標系における球の中心位置|No| 300 | |`radius`|`number`|球の半径|No| 301 | |`inside`|`boolean`|`true` の場合、内部コライダー|No| 302 | 303 | #### ShapeSphere.offset 304 | 305 | ローカル座標系における球の中心位置を示します。 306 | 307 | - 型: `number[3]` 308 | - 必須: No, 初期値: [0.0, 0.0, 0.0] 309 | 310 | #### ShapeSphere.radius 311 | 312 | 球の半径を示します。 313 | 314 | - 型: `number` 315 | - 必須: No, 初期値: 0.0 316 | - 最小値: 0.0 317 | 318 | #### ShapeSphere.inside 319 | 320 | `true` の場合、内部コライダーとして扱います。 321 | 322 | - 型: `boolean` 323 | - 必須: No, 初期値: `false` 324 | 325 | ### ShapeCapsule 326 | 327 | カプセルコライダーの形状を定義します。 328 | 329 | #### Properties 330 | 331 | ||型|説明|必須| 332 | |:-|:-|:-|:-| 333 | |`offset`|`number[3]`|ローカル座標系におけるカプセルの始点位置|No| 334 | |`radius`|`number`|カプセルの半径|No| 335 | |`tail`|`number[3]`|ローカル座標系におけるカプセルの終点位置|No| 336 | |`inside`|`boolean`|`true` の場合、内部コライダー|No| 337 | 338 | #### ShapeCapsule.offset 339 | 340 | ローカル座標系におけるカプセルの始点位置を示します。 341 | 342 | - 型: `number[3]` 343 | - 必須: No, 初期値: [0.0, 0.0, 0.0] 344 | 345 | #### ShapeCapsule.radius 346 | 347 | カプセルの半径を示します。 348 | 349 | - 型: `number` 350 | - 必須: No, 初期値: 0.0 351 | - 最小値: 0.0 352 | 353 | #### ShapeCapsule.tail 354 | 355 | ローカル座標系におけるカプセルの終点位置を示します。 356 | 357 | - 型: `number[3]` 358 | - 必須: No, 初期値: [0.0, 0.0, 0.0] 359 | 360 | #### ShapeCapsule.inside 361 | 362 | `true` の場合、内部コライダーとして扱います。 363 | 364 | - 型: `boolean` 365 | - 必須: No, 初期値: `false` 366 | 367 | ### ShapePlane 368 | 369 | 平面コライダーの形状を定義します。 370 | 371 | #### Properties 372 | 373 | ||型|説明|必須| 374 | |:-|:-|:-|:-| 375 | |`offset`|`number[3]`|ローカル座標系における平面の位置|No| 376 | |`normal`|`number[3]`|ローカル座標系における平面の法線ベクトル|No| 377 | 378 | #### ShapePlane.offset 379 | 380 | ローカル座標系における平面の位置を示します。 381 | 382 | - 型: `number[3]` 383 | - 必須: No, 初期値: [0.0, 0.0, 0.0] 384 | 385 | #### ShapePlane.normal 386 | 387 | ローカル座標系における平面の法線ベクトルを示します。 388 | 正規化されていなければなりません。 389 | 390 | - 型: `number[3]` 391 | - 必須: No, 初期値: [0.0, 0.0, 1.0] 392 | 393 | ## Appendix: Reference Implementations 394 | 395 | > 以下の情報はNon-normativeです。 396 | 397 | 以下に、本拡張で定義するコライダーの参考実装を示します。 398 | 399 | 以下のリファレンス実装により計算した `distance` と `direction` の適用について、 `VRMC_springBone` 拡張のリファレンス実装も合わせて参照してください。 400 | 401 | ### Inside Sphere Collider 402 | 403 | 以下は、擬似コードによる球の内部コライダーの参考実装です。 404 | 405 | ```ts 406 | var transformedOffset = collider.offset * collider.worldMatrix; 407 | var delta = nextTail - transformedOffset; 408 | 409 | // ジョイントとコライダーの距離。負の値は衝突していることを示す 410 | var distance = collider.radius - jointRadius - delta.magnitude; 411 | 412 | // ジョイントとコライダーの距離の方向。衝突している場合、この方向にジョイントを押し出す 413 | var direction = -delta.normalized; 414 | ``` 415 | 416 | > Implementation Note: 内部コライダーでない通常の球コライダーとの実装の差異は、距離の計算および方向の計算の部分のみです。他の箇所について、通常の球コライダーの実装を流用することができます。 417 | 418 | ### Inside Capsule Collider 419 | 420 | 以下は、擬似コードによるカプセルの内部コライダーの参考実装です。 421 | 422 | ```ts 423 | var transformedOffset = collider.offset * collider.worldMatrix; 424 | var transformedTail = collider.tail * collider.worldMatrix; 425 | var offsetToTail = transformedTail - transformedOffset; 426 | 427 | var dot = dot(offsetToTail, delta); 428 | 429 | var delta = nextTail - transformedOffset; 430 | 431 | if (dot < 0.0) { 432 | // ジョイントがカプセルの始点側にある場合 433 | // なにもしない 434 | } else if (dot > lengthSqCapsule) { 435 | // ジョイントがカプセルの終点側にある場合 436 | delta -= offsetToTail; 437 | } else { 438 | // ジョイントがカプセルの始点と終点の間にある場合 439 | delta -= offsetToTail * (dot / offsetToTail.sqMagnitude); 440 | } 441 | 442 | // ジョイントとコライダーの距離。負の値は衝突していることを示す 443 | var distance = collider.radius - jointRadius - delta.magnitude; 444 | 445 | // ジョイントとコライダーの距離の方向。衝突している場合、この方向にジョイントを押し出す 446 | var direction = -delta.normalized; 447 | ``` 448 | 449 | > Implementation Note: 内部コライダーでない通常のカプセルコライダーとの実装の差異は、距離の計算および方向の計算の部分のみです。他の箇所について、通常のカプセルコライダーの実装を流用することができます。 450 | 451 | ### Plane Collider 452 | 453 | 以下は、擬似コードによる平面コライダーの参考実装です。 454 | 455 | ```ts 456 | var transformedOffset = collider.offset * collider.worldMatrix; 457 | var transformedNormal = (colliderNormal * normalMatrixFrom(collider.worldMatrix)).normalized; 458 | var delta = nextTail - transformedOffset; 459 | 460 | // ジョイントとコライダーの距離。負の値は衝突していることを示す 461 | var distance = dot(delta, transformedNormal) - jointRadius; 462 | 463 | // ジョイントとコライダーの距離の方向。衝突している場合、この方向にジョイントを押し出す 464 | var direction = transformedNormal; 465 | ``` 466 | -------------------------------------------------------------------------------- /specification/VRMC_springBone_extended_collider-1.0/schema/VRMC_springBone_extended_collider.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "VRMCSpringBoneExtendedCollider", 3 | "type": "object", 4 | "description": "An extended collider for VRMC_springBone.", 5 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 6 | "properties": { 7 | "specVersion": { 8 | "type": "string", 9 | "description": "Specification version of VRMC_springBone_extended_collider." 10 | }, 11 | "shape": { 12 | "allOf": [ { "$ref": "VRMC_springBone_extended_collider.shape.schema.json" } ], 13 | "description": "The shape of the collider." 14 | }, 15 | "extensions": { }, 16 | "extras": { } 17 | }, 18 | "required": [ "specVersion" ] 19 | } 20 | -------------------------------------------------------------------------------- /specification/VRMC_springBone_extended_collider-1.0/schema/VRMC_springBone_extended_collider.shape.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "ExtendedColliderShape", 3 | "type": "object", 4 | "description": "The shape of the collider. One of sphere, capsule, or plane is defined.", 5 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 6 | "properties": { 7 | "sphere": { 8 | "type": "object", 9 | "title": "ExtendedColliderShapeSphere", 10 | "properties": { 11 | "offset": { 12 | "type": "array", 13 | "description": "The offset of the sphere from the origin in the local space.", 14 | "items": { 15 | "type": "number" 16 | }, 17 | "default": [0.0, 0.0, 0.0], 18 | "minItems": 3, 19 | "maxItems": 3 20 | }, 21 | "radius": { 22 | "type": "number", 23 | "description": "The radius of the sphere.", 24 | "default": 0.0, 25 | "minimum": 0.0 26 | }, 27 | "inside": { 28 | "type": "boolean", 29 | "description": "If true, the collider prevents spring bones from going outside of the sphere instead.", 30 | "default": false 31 | } 32 | } 33 | }, 34 | "capsule": { 35 | "type": "object", 36 | "title": "ExtendedColliderShapeCapsule", 37 | "properties": { 38 | "offset": { 39 | "type": "array", 40 | "description": "The offset of the capsule head from the origin in the local space.", 41 | "items": { 42 | "type": "number" 43 | }, 44 | "default": [0.0, 0.0, 0.0], 45 | "minItems": 3, 46 | "maxItems": 3 47 | }, 48 | "radius": { 49 | "type": "number", 50 | "description": "The radius of the capsule.", 51 | "default": 0.0, 52 | "minimum": 0.0 53 | }, 54 | "tail": { 55 | "type": "array", 56 | "description": "The offset of the capsule tail from the origin in the local space.", 57 | "items": { 58 | "type": "number" 59 | }, 60 | "default": [0.0, 0.0, 0.0], 61 | "minItems": 3, 62 | "maxItems": 3 63 | }, 64 | "inside": { 65 | "type": "boolean", 66 | "description": "If true, the collider prevents spring bones from going outside of the capsule instead.", 67 | "default": false 68 | } 69 | } 70 | }, 71 | "plane": { 72 | "type": "object", 73 | "title": "ExtendedColliderShapePlane", 74 | "properties": { 75 | "offset": { 76 | "type": "array", 77 | "description": "The offset of the plane from the origin in the local space.", 78 | "items": { 79 | "type": "number" 80 | }, 81 | "default": [0.0, 0.0, 0.0], 82 | "minItems": 3, 83 | "maxItems": 3 84 | }, 85 | "normal": { 86 | "type": "array", 87 | "description": "The normal of the plane in the local space. Must be normalized.", 88 | "items": { 89 | "type": "number" 90 | }, 91 | "default": [0.0, 0.0, 1.0], 92 | "minItems": 3, 93 | "maxItems": 3 94 | } 95 | } 96 | }, 97 | "extensions": { }, 98 | "extras": { } 99 | }, 100 | "oneOf": [ 101 | { "required": [ "sphere" ] }, 102 | { "required": [ "capsule" ] }, 103 | { "required": [ "plane" ] } 104 | ] 105 | } 106 | -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/README.ja.md: -------------------------------------------------------------------------------- 1 | # VRMC_vrm 2 | 3 | *Version 1.0* 4 | 5 | ## 目次 6 | 7 | 8 | 9 | 10 | 11 | - [Contributors](#contributors) 12 | - [Status](#status) 13 | - [Dependencies](#dependencies) 14 | - [併用する拡張](#%E4%BD%B5%E7%94%A8%E3%81%99%E3%82%8B%E6%8B%A1%E5%BC%B5) 15 | - [KHR_texture_transform の制限](#khr_texture_transform-%E3%81%AE%E5%88%B6%E9%99%90) 16 | - [VRM1での KHR_texture_transform の非推奨の機能](#vrm1%E3%81%A7%E3%81%AE-khr_texture_transform-%E3%81%AE%E9%9D%9E%E6%8E%A8%E5%A5%A8%E3%81%AE%E6%A9%9F%E8%83%BD) 17 | - [Overview](#overview) 18 | - [JSON Schema](#json-schema) 19 | - [VRMC_vrm の仕様バージョン](#vrmc_vrm-%E3%81%AE%E4%BB%95%E6%A7%98%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3) 20 | - [形式と拡張子](#%E5%BD%A2%E5%BC%8F%E3%81%A8%E6%8B%A1%E5%BC%B5%E5%AD%90) 21 | - [glTF Schema Updates](#gltf-schema-updates) 22 | - [座標の単位](#%E5%BA%A7%E6%A8%99%E3%81%AE%E5%8D%98%E4%BD%8D) 23 | - [使わない項目](#%E4%BD%BF%E3%82%8F%E3%81%AA%E3%81%84%E9%A0%85%E7%9B%AE) 24 | - [保存された TANGENT を無視してもよい](#%E4%BF%9D%E5%AD%98%E3%81%95%E3%82%8C%E3%81%9F-tangent-%E3%82%92%E7%84%A1%E8%A6%96%E3%81%97%E3%81%A6%E3%82%82%E3%82%88%E3%81%84) 25 | - [`meshes[*].primitives[*].attributes.TANGENT`](#meshesprimitivesattributestangent) 26 | - [`meshes[*].primitives[*].targets.TANGENT`](#meshesprimitivestargetstangent) 27 | - [`meshes[*].extras.targetNames` モーフターゲットの名前(推奨)](#meshesextrastargetnames-%E3%83%A2%E3%83%BC%E3%83%95%E3%82%BF%E3%83%BC%E3%82%B2%E3%83%83%E3%83%88%E3%81%AE%E5%90%8D%E5%89%8D%E6%8E%A8%E5%A5%A8) 28 | - [`VRMC_vrm.humanoid` ノードへのヒューマノイドボーンの割り当て(必須)](#vrmc_vrmhumanoid-%E3%83%8E%E3%83%BC%E3%83%89%E3%81%B8%E3%81%AE%E3%83%92%E3%83%A5%E3%83%BC%E3%83%9E%E3%83%8E%E3%82%A4%E3%83%89%E3%83%9C%E3%83%BC%E3%83%B3%E3%81%AE%E5%89%B2%E3%82%8A%E5%BD%93%E3%81%A6%E5%BF%85%E9%A0%88) 29 | - [`VRMC_vrm.meta` モデル情報(必須)](#vrmc_vrmmeta-%E3%83%A2%E3%83%87%E3%83%AB%E6%83%85%E5%A0%B1%E5%BF%85%E9%A0%88) 30 | - [`VRMC_vrm.firstPerson` 一人称(オプション)](#vrmc_vrmfirstperson-%E4%B8%80%E4%BA%BA%E7%A7%B0%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3) 31 | - [Expression, LookAt, SpringBone, Constraints の適用順](#expression-lookat-springbone-constraints-%E3%81%AE%E9%81%A9%E7%94%A8%E9%A0%86) 32 | - [`VRMC_vrm.expressions` 表情(オプション)](#vrmc_vrmexpressions-%E8%A1%A8%E6%83%85%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3) 33 | - [`VRMC_vrm.lookAt` 視線制御(オプション)](#vrmc_vrmlookat-%E8%A6%96%E7%B7%9A%E5%88%B6%E5%BE%A1%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3) 34 | - [Known Implementations](#known-implementations) 35 | - [Resources](#resources) 36 | 37 | 38 | 39 | ## Contributors 40 | 41 | * 進藤 哲郎 42 | * 廣瀬 淳一 43 | * 蘇 柏彰 44 | * 小渕 豊 45 | * 角 真宇 46 | 47 | ## Status 48 | 49 | Complete 50 | 51 | ## Dependencies 52 | 53 | Written against the glTF 2.0 spec. 54 | 55 | ## 併用する拡張 56 | 57 | VRMC_vrm 拡張は、これらの拡張と併用して使用することを想定しています。 58 | 59 | * KHR_materials_unlit 60 | * KHR_texture_transform 61 | * KHR_materials_emissive_strength 62 | * VRMC_materials_mtoon 63 | * VRMC_springBone 64 | * VRMC_node_constraint 65 | 66 | ## KHR_texture_transform の制限 67 | 68 | [KHR_texture_transform](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform/README.md) は、 69 | すべてのマテリアルのテクスチャー [textureInfo](https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/schema/textureInfo.schema.json) に対して、 70 | 個別に `offset`, `rotation`, `scale`, `texCoord` を指定することができます。 71 | 72 | glTF 標準のPBRマテリアルの場合、 73 | 74 | * pbrMetallicRoughness.baseColorTexture(KHR_materials_unlit の場合はこれのみ) 75 | * pbrMetallicRoughness.metallicRoughnessTexture 76 | * normalTexture 77 | * occlusionTexture 78 | * emissiveTexture 79 | 80 | です。 81 | 82 | ### VRM1での KHR_texture_transform の非推奨の機能 83 | 84 | 実装によっては KHR_texture_transform の拡張する項目が個別に設定できないことがあります。 85 | そのため、下記の項目については使用しないことを推奨しています。 86 | 87 | * rotation 88 | * texCoord 89 | 90 | ## Overview 91 | 92 | glTF はシーンを表現するのに対して、 93 | VRMはVRアバター向けの人間型モデル一体を表現します。 94 | 95 | ### モデル空間 96 | 97 | VRMでは、VRMモデルを構成するglTFシーンの原点から相対にトランスフォームを観測する「モデル空間」を定義します。 98 | これは、VRMモデルを扱うアプリケーション上のワールド空間とは区別されます。 99 | 100 | モデル空間は、 [`VRMC_node_constraint`](../VRMC_node_constraint-1.0/README.ja.md) 拡張で利用されます。 101 | 102 | > VRMモデルをアプリケーション上で動かす際は、Humanoidで定義するHipsを動かすだけでなく、 103 | > glTFシーンのルートごとモデルを動かすことにより、モデル空間を尊重することが期待されます。 104 | > 言い換えれば、モデルのルートが常にワールド空間のルートに留まるような利用は推奨されません。 105 | 106 | ### JSON Schema 107 | 108 | ```js 109 | { 110 | "extensionsUsed": [ 111 | "VRMC_vrm" 112 | ], 113 | "extensions": { 114 | "VRMC_vrm": { 115 | // VRM extension 116 | "specVersion": "1.0", 117 | "humanoid": {}, 118 | "meta": {}, 119 | "firstPerson": {}, 120 | "expressions": {}, 121 | "lookAt": {}, 122 | }, 123 | "VRMC_springBone": {}, 124 | "VRMC_node_constraint": {} 125 | }, 126 | // glTF-2.0 127 | "materials": [ 128 | "extensions": { 129 | "VMRC_materials_mtoon": {} 130 | } 131 | ], 132 | } 133 | ``` 134 | 135 | * https://github.com/vrm-c/vrm-specification/tree/master/specification/VRMC_vrm-1.0/schema 136 | 137 | GLTF-2.0のJsonSchema 138 | 139 | * https://github.com/KhronosGroup/glTF/tree/master/specification/2.0/schema 140 | 141 | ### VRMC_vrm の仕様バージョン 142 | 143 | ```json 144 | extensions.VRMC_vrm.specVersion = "1.0" 145 | ``` 146 | 147 | ### 形式と拡張子 148 | 149 | `.glb` 形式で保存し拡張子に `.vrm` を使います。 150 | 151 | ## glTF Schema Updates 152 | 153 | ### 座標の単位 154 | 155 | glTFの [coordinate-system-and-units](https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#coordinate-system-and-units) に準拠してメートル単位です。 156 | 157 | ### 使わない項目 158 | 159 | 以下の項目を使用しません。 160 | 161 | * animations 162 | * cameras 163 | 164 | ### 保存された TANGENT を無視してもよい 165 | 166 | TANGENT を正しく扱うことが技術的に困難なため、書き出しはしない、読み込みはせずに計算することを許容します。 167 | 168 | #### `meshes[*].primitives[*].attributes.TANGENT` 169 | 170 | * import: MikkTSpaceアルゴリズムで計算してください。 171 | 172 | https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#meshes 173 | 174 | > Implementation note: When tangents are not specified, client implementations should calculate tangents using default MikkTSpace algorithms. For best results, the mesh triangles should also be processed using default MikkTSpace algorithms. 175 | 176 | * export: MikkTSpaceアルゴリズムで計算することを期待してエクスポートしないことを推奨。 177 | 178 | #### `meshes[*].primitives[*].targets.TANGENT` 179 | 180 | * morphTarget で tangent がアニメーションすることは非推奨です 181 | * export: 出力しないことを推奨 182 | * import: 無視するを推奨 183 | 184 | ### `meshes[*].extras.targetNames` モーフターゲットの名前(推奨) 185 | 186 | `meshes[*].primitives[*].targets.name` が無いので代替で `meshes[*].extras.targetNames` に格納します。 187 | 188 | * https://github.com/KhronosGroup/glTF/issues/1036 189 | 190 | ## `VRMC_vrm.humanoid` ノードへのヒューマノイドボーンの割り当て(必須) 191 | 192 | 人型モデルを定義するために、人体の部位(ヒューマノイドボーン)を glTF.Node に割り当てます。 193 | 194 | 別ドキュメントにおいて仕様を示します。 195 | 196 | [./humanoid.ja.md](./humanoid.ja.md) 197 | 198 | ## `VRMC_vrm.meta` モデル情報(必須) 199 | 200 | 別ドキュメントにおいて仕様を示します。 201 | 202 | [./meta.ja.md](./meta.ja.md) 203 | 204 | ## `VRMC_vrm.firstPerson` 一人称(オプション) 205 | 206 | VRMは、VRを想定した一人称視点の設定を定義しています。 207 | 208 | 別ドキュメントにおいて仕様を示します。 209 | 210 | [./firstPerson.ja.md](./firstPerson.ja.md) 211 | 212 | ## Expression, LookAt, SpringBone, Constraints の適用順 213 | 214 | * VRMC_vrm.lookAt 215 | * VRMC_vrm.expression 216 | * VRMC_node_constraint 217 | * VRMC_springBone 218 | 219 | は Node, Mesh への変更があり実行順の影響があります。 220 | 推奨される更新の適用順は下記のとおりです。 221 | 222 | 1. ヒューマノイドボーンを解決 223 | 2. 頭の位置が決まるのでLookAtを解決 224 | * Bone型 => leftEye, rightEye ボーンを回転 225 | * Expression型 => 次項 226 | 3. ExpressionUpdate 227 | * 喜怒哀楽 コントローラーなど外部入力 => Expression ウェイトを設定 228 | * LipSync => Expression ウェイトを設定 229 | * AutoBlink => Expression ウェイトを設定 230 | * Expression型のLookAt => Expression のウェイトを設定 231 | 4. Expression を Apply する 232 | 5. コンストレイントを解決 233 | 6. SpringBoneを解決 234 | 235 | ## `VRMC_vrm.expressions` 表情(オプション) 236 | 237 | VRMは、ヒューマノイド向けに Expression を定義しています。 238 | 239 | > VRM-0 仕様で使っていた BlendShape という言葉は MorphTarget と同じものを指しており意味が異なるため、 BlendShape から Expression に改名しました。 240 | 241 | 別ドキュメントにおいて仕様を示します。 242 | 243 | [./expressions.ja.md](./expressions.ja.md) 244 | 245 | ## `VRMC_vrm.lookAt` 視線制御(オプション) 246 | 247 | VRMは、ヒューマノイド向けに視線制御を定義しています。 248 | 249 | 別ドキュメントにおいて仕様を示します。 250 | 251 | [./lookAt.ja.md](./lookAt.ja.md) 252 | 253 | ## Known Implementations 254 | 255 | * https://vrm.dev/vrm_applications/ 256 | 257 | ## Resources 258 | 259 | * https://vrm.dev/ 260 | -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/README.md: -------------------------------------------------------------------------------- 1 | # VRMC_vrm 2 | 3 | *Version 1.0* 4 | 5 | ## Contents 6 | 7 | 8 | 9 | 10 | - [Contributors](#contributors) 11 | - [Status](#status) 12 | - [Dependencies](#dependencies) 13 | - [Extensions used along with VRMC_vrm](#extensions-used-along-with-vrmc_vrm) 14 | - [Limitation of KHR_texture_transform](#limitation-of-khr_texture_transform) 15 | - [Obsolete properties of KHR_texture_transform with VRM1](#obsolete-properties-of-khr_texture_transform-with-vrm1) 16 | - [Overview](#overview) 17 | - [JSON Schema](#json-schema) 18 | - [Version of VRMC_vrm specification](#version-of-vrmc_vrm-specification) 19 | - [Format and Extension](#format-and-extension) 20 | - [glTF schema Updates](#gltf-schema-updates) 21 | - [Coordinate Units](#coordinate-units) 22 | - [Unused Items](#unused-items) 23 | - [Allow ignore stored TANGENT](#allow-ignore-stored-tangent) 24 | - [`meshes[*].primitives[*].attributes.TANGENT`](#meshesprimitivesattributestangent) 25 | - [`meshes[*].primitives[*].targets.TANGENT`](#meshesprimitivestargetstangent) 26 | - [`meshes[*].extras.targetNames` names of morphTargets (recommendation)](#meshesextrastargetnames-names-of-morphtargets-recommendation) 27 | - [`VRMC_vrm.humanoid` Assignment to humanoid bones (required)](#vrmc_vrmhumanoid-assignment-to-humanoid-bones-required) 28 | - [`VRMC_vrm.meta` Model information (required)](#vrmc_vrmmeta-model-information-required) 29 | - [`VRMC_vrm.firstPerson` First person (optional)](#vrmc_vrmfirstperson-first-person-optional) 30 | - [Expression, LookAt, SpringBone, Constraints application order](#expression-lookat-springbone-constraints-application-order) 31 | - [`VRMC_vrm.expressions` Facial expressions (optional)](#vrmc_vrmexpressions-facial-expressions-optional) 32 | - [`VRMC_vrm.lookAt` Eye control (optional)](#vrmc_vrmlookat-eye-control-optional) 33 | - [Known Implementations](#known-implementations) 34 | - [Resources](#resources) 35 | 36 | 37 | 38 | ## Contributors 39 | 40 | * Shindo Tetsuro 41 | * Hirose Junichi 42 | * Su Po-Chang 43 | * Obuchi Yutaka 44 | * Sumi Masataka 45 | 46 | ## Status 47 | 48 | Complete 49 | 50 | ## Dependencies 51 | 52 | Written against the glTF 2.0 spec. 53 | 54 | ## Extensions used along with VRMC_vrm 55 | 56 | VRMC_vrm extension is intended to be used along with these extensions. 57 | 58 | * KHR_materials_unlit 59 | * KHR_texture_transform 60 | * KHR_materials_emissive_strength 61 | * VRMC_materials_mtoon 62 | * VRMC_springBone 63 | * VRMC_node_constraint 64 | 65 | ## Limitation of KHR_texture_transform 66 | 67 | [KHR_texture_transform](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform/README.md) can manipulate `offset`, `rotation`, `sacle` and `texCoord` for each [textureInfo](https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/schema/textureInfo.schema.json) of each Material. 68 | 69 | For the glTF PBR Material, 70 | 71 | * pbrMetallicRoughness.baseColorTexture (only if KHR_materials_unlit is enabled) 72 | * pbrMetallicRoughness.metallicRoughnessTexture 73 | * normalTexture 74 | * occlusionTexture 75 | * emissiveTexture 76 | 77 | ### Obsolete properties of KHR_texture_transform with VRM1 78 | 79 | There are renderer implementations that don't support all properties of KHR_texture_transform for textures of materials. 80 | Therefore, we recommend to _not_ use the below properties of KHR_texture_transform: 81 | 82 | * rotation 83 | * texCoord 84 | 85 | ## Overview 86 | 87 | glTF represent an entire Scene, whereas VRM represent a Humanoid for VR avatar. 88 | 89 | ### Model Space 90 | 91 | VRM defines a "model space" for each VRM model, that observes relative transforms from the root of the glTF scene. 92 | This is distinct from world space defined in the application that uses the VRM model. 93 | 94 | Model space will be used in the [`VRMC_node_constraint`](../VRMC_node_constraint-1.0/README.md) extension. 95 | 96 | > To move VRM models in an application, 97 | > it is expected that the root of the glTF scene is moved, not only the Hips bone defined in Humanoid. 98 | > In other words, you should not leave the root of the model at the origin of world space. 99 | 100 | ### JSON Schema 101 | 102 | ```js 103 | { 104 | "extensionsUsed": [ 105 | "VRMC_vrm" 106 | ], 107 | "extensions": { 108 | "VRMC_vrm": { 109 | // VRM extension 110 | "specVersion": "1.0", 111 | "humanoid": {}, 112 | "meta": {}, 113 | "firstPerson": {}, 114 | "expressions": {}, 115 | "lookAt": {}, 116 | }, 117 | "VRMC_springBone": {}, 118 | "VRMC_node_constraint": {} 119 | }, 120 | // glTF-2.0 121 | "materials": [ 122 | "extensions": { 123 | "VMRC_materials_mtoon": {} 124 | } 125 | ], 126 | } 127 | ``` 128 | 129 | * https://github.com/vrm-c/vrm-specification/tree/master/specification/VRMC_vrm-1.0/schema 130 | 131 | JSON Schema of glTF 2.0 132 | 133 | * https://github.com/KhronosGroup/glTF/tree/master/specification/2.0/schema 134 | 135 | ### Version of VRMC_vrm specification 136 | 137 | ```json 138 | extensions.VRMC_vrm.specVersion = "1.0" 139 | ``` 140 | 141 | ### Format and Extension 142 | 143 | Saved in `.glb` format and using `.vrm` as the extension. 144 | 145 | ## glTF schema Updates 146 | 147 | ### Coordinate Units 148 | 149 | Metric units based on glTF [coordinate-system-and-units](https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#coordinate-system-and-units). 150 | 151 | ### Unused Items 152 | 153 | The following items are not used: 154 | 155 | * animations 156 | * cameras 157 | 158 | #### Allow ignore stored TANGENT 159 | 160 | Because it is difficult to handle the tangent correctly, 161 | it is allowed to not export any tangents. When importing, any stored TANGENT may be ignored, and calculated instead. 162 | 163 | #### `meshes[*].primitives[*].attributes.TANGENT` 164 | 165 | * import: calculate using MikkTSpace algorithm. 166 | 167 | https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#meshes 168 | 169 | > Implementation note: When tangents are not specified, client implementations should calculate tangents using default MikkTSpace algorithms. For best results, the mesh triangles should also be processed using default MikkTSpace algorithms. 170 | 171 | * export: do not export, expected to be calculated with the algorithm. 172 | 173 | #### `meshes[*].primitives[*].targets.TANGENT` 174 | 175 | * morphTarget tangent is not recommended 176 | * export: do not export 177 | * import: do not import 178 | 179 | ### `meshes[*].extras.targetNames` names of morphTargets (recommendation) 180 | 181 | Since there is no `meshes[*].primitives[*].targets.name`, `meshes[*].extras.targetNames` . 182 | 183 | * https://github.com/KhronosGroup/glTF/issues/1036 184 | 185 | ## `VRMC_vrm.humanoid` Assignment to humanoid bones (required) 186 | 187 | Assign a `part of the human body` (humanoid bone) to glTF.Node to define a humanoid model. 188 | 189 | The specifications are shown in another document. 190 | 191 | [./humanoid.md](./humanoid.md) 192 | 193 | ## `VRMC_vrm.meta` Model information (required) 194 | 195 | The specifications are shown in another document. 196 | 197 | [./meta.md](./meta.md) 198 | 199 | ## `VRMC_vrm.firstPerson` First person (optional) 200 | 201 | VRM defines the setting of the first-person viewpoint assuming VR. 202 | 203 | The specifications are shown in another document. 204 | 205 | [./firstPerson.md](./firstPerson.md) 206 | 207 | ## Expression, LookAt, SpringBone, Constraints execution order 208 | 209 | * VRMC_vrm.lookAt 210 | * VRMC_vrm.expression 211 | * VRMC_node_constraint 212 | * VRMC_springBone 213 | 214 | These components affect Node and Mesh, and the execution order matters. 215 | The recommended order of execution in an update loop is as follows. 216 | 217 | 1. Resolve humanoid bones 218 | 2. Resolve LookAt as the position of the head is determined 219 | * Bone type => leftEye, rightEye Rotate bones 220 | * Expression type => Next section 221 | 3. Expression Update 222 | * Emotions and sorrows controller, etc. External input => Set Expression weight 223 | * LipSync => Set Expression weight 224 | * AutoBlink => Set Expression weight 225 | * Expression type LookAt => Set expression weight 226 | 4. Apply Expression 227 | 5. Resolve constraints 228 | 6. Resolve Spring Bone 229 | 230 | ## `VRMC_vrm.expressions` Facial expressions (optional) 231 | 232 | VRM defines Expressions for humanoids. 233 | 234 | > The word BlendShape used in the VRM-0 specification refers to the same thing as MorphTarget and has a different meaning, so we renamed it from BlendShape to Expression. 235 | 236 | The specifications are shown in another document. 237 | 238 | [./expressions.md](./expressions.md) 239 | 240 | ## `VRMC_vrm.lookAt` Eye control (optional) 241 | 242 | VRMs define gaze control for humanoids. 243 | 244 | The specifications are shown in another document. 245 | 246 | [./lookAt.md](./lookAt.md) 247 | 248 | ## Known Implementations 249 | 250 | * https://vrm.dev/vrm_applications/ 251 | 252 | ## Resources 253 | 254 | * https://vrm.dev/ 255 | -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/expressions.ja.md: -------------------------------------------------------------------------------- 1 | # `VRMC_vrm.expressions` 2 | 3 | 本文書では、 `VRMC_vrm` 拡張のうち `expressions` フィールドについての仕様を示します。 4 | 5 | Expression は、 6 | 7 | * MorphTarget 8 | * MaterialColor 9 | * TextureTransform 10 | 11 | のグループに対して意味を指定する機能です。 12 | 13 | > 例えば、 `口をへの字にする MorphTarget` と `目を閉じる MorphTarget` の組み合わせを `sad` にするなど 14 | 15 | 16 | 17 | **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* 18 | 19 | - [Expressionの仕様](#expression%E3%81%AE%E4%BB%95%E6%A7%98) 20 | - [Expression の制御](#expression-%E3%81%AE%E5%88%B6%E5%BE%A1) 21 | - [Preset Expressions](#preset-expressions) 22 | - [感情](#%E6%84%9F%E6%83%85) 23 | - [リップシンク プロシージャル](#%E3%83%AA%E3%83%83%E3%83%97%E3%82%B7%E3%83%B3%E3%82%AF-%E3%83%97%E3%83%AD%E3%82%B7%E3%83%BC%E3%82%B8%E3%83%A3%E3%83%AB) 24 | - [瞬き プロシージャル](#%E7%9E%AC%E3%81%8D-%E3%83%97%E3%83%AD%E3%82%B7%E3%83%BC%E3%82%B8%E3%83%A3%E3%83%AB) 25 | - [視線 プロシージャル](#%E8%A6%96%E7%B7%9A-%E3%83%97%E3%83%AD%E3%82%B7%E3%83%BC%E3%82%B8%E3%83%A3%E3%83%AB) 26 | - [その他](#%E3%81%9D%E3%81%AE%E4%BB%96) 27 | - [Custom Expressions](#custom-expressions) 28 | - [プロシージャルのオーバーライド](#%E3%83%97%E3%83%AD%E3%82%B7%E3%83%BC%E3%82%B8%E3%83%A3%E3%83%AB%E3%81%AE%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC%E3%83%A9%E3%82%A4%E3%83%89) 29 | - [オーバーライドとisBinaryの相互作用について](#%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC%E3%83%A9%E3%82%A4%E3%83%89%E3%81%A8isbinary%E3%81%AE%E7%9B%B8%E4%BA%92%E4%BD%9C%E7%94%A8%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6) 30 | - [MorphTargetBind](#morphtargetbind) 31 | - [MaterialColorBind](#materialcolorbind) 32 | - [TextureTransformBind](#texturetransformbind) 33 | - [Expression 更新のアルゴリズム](#expression-%E6%9B%B4%E6%96%B0%E3%81%AE%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0) 34 | - [MorphTarget](#morphtarget) 35 | - [MaterialColor](#materialcolor) 36 | - [TextureTransform](#texturetransform) 37 | 38 | 39 | 40 | ## Expressionの仕様 41 | 42 | | 名前 | 備考 | 43 | |:-------------------------------------|:------------------------------------------------------| 44 | | expressions[*].isBinary | 0.5より大きい値は1.0, それ以下は0.0になります。 | 45 | | expressions[*].morphTargetBinds | MorphTargetBind(後述) のリスト | 46 | | expressions[*].materialColorBinds | MaterialValueBind(後述) のリスト | 47 | | expressions[*].textureTransformBinds | TextureTransformBind(後述) のリスト | 48 | | expressions[*].overrideMouth | このExpressionのWeightが0でないときに、リップシンク(後述) のウェイトを操作します。 | 49 | | expressions[*].overrideBlink | このExpressionのWeightが0でないときに、瞬き(後述) のウェイトを操作します。 | 50 | | expressions[*].overrideLookAt | このExpressionのWeightが0でないときに、視線(後述) のウェイトを操作します。 | 51 | 52 | ### Expression の制御 53 | 54 | 各Expressionが用いられる際に、その表情の強さを表す「Value」の状態を持つことを想定します。 55 | Valueは [0-1] の範囲の値を持つ数値です。 56 | VRMの実装は、アプリケーションがこの範囲から外れた値を与えた場合は、値をクランプしてください。 57 | 58 | ## Preset Expressions 59 | 60 | 以下は、プリセット表情の一覧です。 61 | これらの表情の定義は `expressions.preset` 内に格納されます。 62 | すべてのプリセット表情はオプショナルです。 63 | 64 | ### 感情 65 | 66 | | 名前 | 備考 | 67 | |:----------|:-------------------| 68 | | happy | 喜。 `joy` から変更 | 69 | | angry | 怒 | 70 | | sad | 哀。 `sorrow` から変更 | 71 | | relaxed | 楽。 `fun` から変更 | 72 | | surprised | 驚。 `1.0で新規追加` | 73 | 74 | 特に具体的な顔の変形について仕様を規定していません。 75 | 76 | ### リップシンク プロシージャル 77 | 78 | プロシージャル: システムから自動的に生成されうる値です。 79 | 80 | > マイク入力を解析したり、テキストから生成するなど 81 | 82 | | 名前 | 備考 | 83 | |:-----|:-----| 84 | | aa | あ | 85 | | ih | い | 86 | | ou | う | 87 | | ee | え | 88 | | oh | お | 89 | 90 | ### 瞬き プロシージャル 91 | 92 | プロシージャル: システムから自動的に生成されうる値です。 93 | 94 | > ランダムで瞬きさせるなど 95 | 96 | | 名前 | 備考 | 97 | |:-----------|:-----------| 98 | | blink | 両方の瞼を閉じる | 99 | | blinkLeft | 左瞼を閉じる | 100 | | blinkRight | 右瞼を閉じる | 101 | 102 | ### 視線 プロシージャル 103 | 104 | プロシージャル: システムから自動的に生成されうる値です。 105 | 106 | > VRMの LookAt により注視点に対応した値が随時生成されます(LookAt の Expressionタイプを参照してください) 107 | 108 | | 名前 | 備考 | 109 | |:----------|:----------------------------------------------------| 110 | | lookUp | ボーンではなくExpressionで視線が動くモデル向け。視線制御を参照してください。 | 111 | | lookDown | ボーンではなくExpressionで視線が動くモデル向け。視線制御を参照してください。 | 112 | | lookLeft | ボーンではなくExpressionで視線が動くモデル向け。視線制御を参照してください。 | 113 | | lookRight | ボーンではなくExpressionで視線が動くモデル向け。視線制御を参照してください。 | 114 | 115 | ### その他 116 | 117 | | 名前 | 備考 | 118 | |:--------|:---------------------| 119 | | neutral | 後方互換性のために残しています。 | 120 | 121 | ## Custom Expressions 122 | 123 | 上で挙げたPreset Expressionsの他に、ユーザが独自に表情を定義できます。 124 | Custom Expressionsは `expressions.custom` 内に格納されます。 125 | プリセット名と同じ名前の Custom Expressions は許容されません。 126 | 127 | ## プロシージャルのオーバーライド 128 | 129 | リップシンク、瞬き、視線 はプロシージャルと分類します。 130 | プロシージャルは、システムにより自動で生成されることを想定します。 131 | そのため、 これらの Expression が他の Expression と同時に有効になってしまい、 132 | メッシュが破綻してしまう可能性があります。 133 | 134 | 例えば、 135 | 136 | * 口が開く `happy` と同時に `aa` が適用される => 口が開きすぎて変になる 137 | * 目を閉じる `sad` と同時に `blink` が適用される => 目が2回閉じて瞼が頬を貫通してしまう 138 | * `blink` と同時に `lookRight` が適用される => 目が瞼を貫通してしまう 139 | 140 | などです。 141 | これらを防御するために、 プロシージャルではない Expression に対して、同時にプロシージャルな Expression が有効になった場合に、プロシージャルな Expression の値をオーバーライドする機能があります。 142 | 143 | > `happy` 中はリップシンクをしないなど 144 | 145 | リップシンク、瞬き、視線 に対して 146 | overrideMouth, overrideBlink, overrideLookAt を設定できます。 147 | 148 | それぞれの override プロパティは、以下のプロシージャル表情に対して作用します: 149 | 150 | | 対象 | プロパティ | ExpressionPreset | 151 | |:-------|:-----------------|:----------------------------------------------| 152 | | リップシンク | `overrideMouth` | `aa`, `ih`, `ou`, `ee`, `oh` | 153 | | 瞬き | `overrideBlink` | `blink`, `blinkLeft`, `blinkRight` | 154 | | 視線 | `overrideLookAt` | `lookUp`, `lookDown`, `lookLeft`, `lookRight` | 155 | 156 | > カスタム表情に対してこれらの override プロパティが作用するかは、仕様では特に定義しません。 157 | > アプリケーション側の需要に応じて適宜設定を行ってください。 158 | > 例えば、VRMのプリセットに含まれないリップシンクをカスタム表情を用いてアプリケーションごとに利用したい場合に、そのカスタム表情の発現を override プロパティを用いて制御するような使い方が想定されます。 159 | > 160 | > 上記の理由で、VRMの実装は、カスタム表情を override の対象に含むことができるようなインタフェースを提供することが推奨されます。 161 | 162 | blink に対する overrideBlink のように、同種同士に対する設定は無効として扱います。 163 | 164 | 設定内容はすべて同じで、効果は下記のとおりです。 165 | 166 | | 名前 | 備考 | 167 | |:------|:------------------------------------------------------------------------------------------------------------------------------------------------| 168 | | none | 何もしない | 169 | | block | 対象の weight を 0 にする。例えば、 happy に overrideBlink=block が設定されているときに、 happy.weight>0 になると blink,blinkLeft,blinkRight の weight を 0 に override する。 | 170 | | blend | 対象の weight を 減衰させる。例えば、 happy に overrideBlink=blend が設定されているときに、 blink,blinkLeft,blinkRight を happy.weight とブレンドして減衰させる(後述)。 | 171 | 172 | blend 詳細 173 | 174 | 例えば、happy が overrideBlink = blend に設定されている場合、 175 | happy の値が 0 から 1 にフェードするに従い、線形に blink を減衰させます。 176 | 0~1 の間の中間値の挙動が block と異なります。 177 | 178 | ```js 179 | var value = 0; 180 | if (happyWeight > 0 && happy.overrideBlink == "blend") value += happyWeight; 181 | if (angryWeight > 0 && happy.overrideBlink == "blend") value += angryWeight; 182 | if (sadWeight > 0 && happy.overrideBlink == "blend") value += sadWeight; 183 | if (relaxedWeight > 0 && happy.overrideBlink == "blend") value += relaxedWeight; 184 | if (surprisedWeight > 0 && happy.overrideBlink == "blend") value += surprisedWeight; 185 | var factor = 1.0 - saturate(value); 186 | SetBlinkWeight(blinkWeight * factor); 187 | ``` 188 | 189 | ### オーバーライドとisBinaryの相互作用について 190 | 191 | isBinaryが指定されている表情が他の表情にオーバーライドの影響を与える場合、出力値である二値化された値をもって他の表情に影響を与えなければいけません(MUST)。 192 | 193 | > これは、オーバーライドの影響を与える表情がキャラクター上に見た目として発現していないにも関わらず、他の表情がオーバーライドによって抑制されることを防ぐための仕様です。 194 | > 例えば、表情 `happy` の `isBinary` が `true` で、かつ `overrideBlink` に `block` もしくは `blend` が指定されている場合、 `happy` の値が 0.5 以上のとき、 `blink` は完全に抑制されます。逆に、 `happy` の値が 0.5 未満のとき、 `blink` は `happy` の値に関係なく評価されます。 195 | > 196 | > ![上記の例における `happy` の出力値の図解](./figures/override-isbinary-ja.png) 197 | 198 | isBinaryが指定されている表情が他の表情からオーバーライドの影響を受ける場合、受けている影響が0.0より大きければ、完全に抑制されなければいけません(MUST)。 199 | 200 | > これは、オーバーライドの影響を受ける `isBinary` が `true` の表情が0もしくは1以外の値で発現することを防ぐための仕様です。 201 | > 例えば、表情 `happy` の `overrideBlink` が `block` もしくは `blend` で、表情 `blink` の `isBinary` が `true` の場合、 `happy` が少しでもオーバーライドの影響を与えているならば、 `blink` は完全に抑制されます。 202 | 203 | ### MorphTargetBind 204 | 205 | `extensions.VRMC_vrm.expressions[*].morphTargetBinds[*]` 206 | 207 | Expression と MorphTarget を結びつけます。 208 | 209 | | 名前 | 備考 | 210 | |:-------|:------------------------------------------------------| 211 | | node | 対象node(meshを持っている)のindex | 212 | | index | 対象morphのindex(すべてのprimitiveが同じmorphTargetを持つ想定です) | 213 | | weight | 適用したときのmorph値 [0-1]。0.X では [0-100] | 214 | 215 | ### MaterialColorBind 216 | 217 | `extensions.VRMC_vrm.expressions[*].materialColorBinds[*]` 218 | 219 | Expression と Material の色の変化を結びつけます。 220 | 221 | | 名前 | 備考 | 222 | |:------------|:----------------------------------------------| 223 | | material | 対象のmaterialのindex | 224 | | type | materialの変更対象項目(color, uvScale, uvOffset) | 225 | | targetValue | 適用したときのmaterial値(float4) | 226 | 227 | `extensions.VRMC_vrm.expressions[*].materialColorBinds[*].type` 228 | 229 | それぞれ、以下のパラメータに対応します: 230 | 231 | | Name | `pbrMetallicRoughness` | ` KHR_materials_unlit` | `VRMC_materials_mtoon` | 232 | |:--------------|:---------------------------------------|:----------------------------------------|:-----------------------------------------------------------| 233 | | color | `pbrMetallicRoughness.baseColorFactor` | ` pbrMetallicRoughness.baseColorFactor` | `pbrMetallicRoughness.baseColorFactor` | 234 | | emissionColor | `emissiveFactor` | 未使用 | `emissiveFactor` | 235 | | shadeColor | 未使用 | 未使用 | `extensions.VRMC_materials_mtoon.shadeColorFactor` | 236 | | matcapColor | 未使用 | 未使用 | `extensions.VRMC_materials_mtoon.matcapFactor` | 237 | | rimColor | 未使用 | 未使用 | `extensions.VRMC_materials_mtoon.parametricRimColorFactor` | 238 | | outlineColor | 未使用 | 未使用 | `extensions.VRMC_materials_mtoon.outlineColorFactor` | 239 | 240 | `targetValue` はfloat4で格納されますが、宛先のパラメータに4つ目の成分が存在しない場合、4つ目の値は無視されます。 241 | 242 | ### TextureTransformBind 243 | 244 | `extensions.VRMC_vrm.expressions[*].textureTransformBinds[*]` 245 | 246 | Expression と 対象 Material のテクスチャーの scale, offset の変化を結びつけます。 247 | 対象マテリアルで使われるテクスチャのうち、UVアクセスするテクスチャすべてが同じ値を使用することとします。 248 | 249 | UVアクセスしないテクスチャは、MToon の `matcap` です。 250 | 251 | | 名前 | 備考 | 252 | |:---------|:---------------------------------------| 253 | | material | 対象のmaterialのindex | 254 | | scale | 適用したときのscale値(float2, default=[1, 1]) | 255 | | offset | 適用したときのoffset値(float2) | 256 | 257 | ## Expression 更新のアルゴリズム 258 | 259 | ### MorphTarget 260 | 261 | * すべての MorphTarget が0の状態にする 262 | * Expression の値(Weight)を積算する `void AccumulateValue(Expression expression, float value)` 263 | * 積算された値を適用する 264 | 265 | ### MaterialColor 266 | 267 | * すべての MaterialColor を初期状態にする(0ではなく) 268 | * Expression の値(Weight)を積算する `void AccumulateValue(Exoressuib expression, float value)` 269 | * 積算された値を適用する `Base + (A.Target - Base) * A.Weight + (B.Target - Base) * B.Weight` 270 | * MaterialColor は初期値が 0 とは限らないので、初期値との差分を積算します。 271 | 272 | ### TextureTransform 273 | 274 | * すべての MaterialColor を初期状態にする(0ではなく) 275 | * Expression の値(Weight)を積算する `void AccumulateValue(Exoressuib expression, float value)` 276 | * 積算された値を適用する 277 | 278 | > TODO: 適用について、具体的なアルゴリズムを検討中です 279 | -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/figures/override-isbinary-en.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrm-c/vrm-specification/c24d76d99a18738dd2c266be1c83f089064a7b5e/specification/VRMC_vrm-1.0/figures/override-isbinary-en.png -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/figures/override-isbinary-ja.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrm-c/vrm-specification/c24d76d99a18738dd2c266be1c83f089064a7b5e/specification/VRMC_vrm-1.0/figures/override-isbinary-ja.png -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/figures/range_map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrm-c/vrm-specification/c24d76d99a18738dd2c266be1c83f089064a7b5e/specification/VRMC_vrm-1.0/figures/range_map.png -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/firstPerson.ja.md: -------------------------------------------------------------------------------- 1 | # `VRMC_vrm.firstPerson` 2 | 3 | 本文書では、 `VRMC_vrm` 拡張のうち `firstPerson` フィールドについての仕様を示します。 4 | 5 | ## MeshAnnotation 6 | 7 | Mesh単位での描画を制御します。 8 | 9 | `extensions.VRMC_vrm.firstPerson.meshAnnotations[*]` 10 | 11 | | 名前 | 備考 | 12 | |:----------------|:---------------------------| 13 | | node | 対象node(meshを持っている)へのindex | 14 | | firstPersonFlag | 後述 | 15 | 16 | firstPersonFlag。VRアプリでモデルを使用した場合に、自モデルの描画をHMDとそれ以外で切り分けます。 17 | 18 | ## MeshAnnotation(enum) 19 | 20 | `thirdPersonOnly` は、VR描画時に自分の頭部を非表示にすることを意図しています。VR視点カメラは、頭部の中に位置することが想定されます。そのため、顔・頭・髪のポリゴンが視界に見えてしまうのを防ぎます。 21 | 22 | 特に描き分ける必要ないオブジェクトは、 `both` にして、すべてのカメラから描画されるようにします。 23 | 24 | `firstPersonOnly` は、自分だけに見えて他人視点からは見えない設定です。アプリ側で特別な用途が無ければ使いません。 25 | 26 | `auto` はMeshを頭部(`thirdPersonOnly`)とその他(`both`)に分割してください。次の節で詳述します。 27 | 28 | | 名前 | 1人称カメラ(VR視点) | その他のカメラ | 例 | 29 | |:----------------|:-----------------|:---------|---------------------------------------| 30 | | thirdPersonOnly | 描画しない | 描画する | 顔・目・頭・髪、帽子・ヘルメットなどVR視界を遮るもの | 31 | | firstPersonOnly | 描画する | 描画しない | プレイヤーだけに見えてたの視点からは見えないユーザーインタフェース | 32 | | both | 描画する | 描画する | | 33 | | auto | | | 後述 | 34 | 35 | ### MeshAnnotation.Autoのアルゴリズム 36 | 37 | * Meshの頂点をすべて調べて、Headボーンとその子孫のボーンに対するWeightを持つ頂点を集める 38 | * 上記の頂点を含む三角形と含まない三角形に2分したMeshを作成する 39 | * 上記の頂点を含むMeshをThirdPersonOnly、含まないMeshをBothとしたに設定する 40 | 41 | ### MeshAnnotationが指定されていない場合 42 | 43 | MeshAnnotationが指定されていないメッシュが存在する場合において、FirstPersonの機能を利用する場合、 44 | そのメッシュには `auto` が設定されているとみなして処理を行ってください。 45 | 46 | `firstPerson` プロパティそれ自体がVRM拡張に存在しなかった場合においても、 47 | すべてのメッシュに `auto` が設定されているとみなして処理を行ってください。 48 | -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/firstPerson.md: -------------------------------------------------------------------------------- 1 | # `VRMC_vrm.firstPerson` 2 | 3 | This document provides specifications for the `firstPerson` field of the` VRMC_vrm` extension. 4 | 5 | ## MeshAnnotation 6 | 7 | Control renderings in Mesh units. 8 | 9 | `extensions.VRMC_vrm.firstPerson.meshAnnotations[*]` 10 | 11 | | Name | Note | 12 | |:----------------|:--------------------------------------| 13 | | node | Index for target node that has a mesh | 14 | | firstPersonFlag | Described below | 15 | 16 | firstPersonFlag. When using a model in the VR application, the renderings from the HMD and the others are separated. 17 | 18 | ## MeshAnnotation (enum) 19 | 20 | `thirdPersonOnly` is for hiding the rendering of the model's head portion in VR. Since we assumed that the VR camera's viewpoint is at the head position, by setting thirdPersonOnly, the situation where the user may inadvertently see the model's face, head and hair (block the first-person view) can be prevented. 21 | 22 | `firstPersonOnly` is a setting that objects rendered by the first-person camera can only be seen from the first-person view. Normally `firstPersonOnly` will not be used unless the application side needs it for special purposes. 23 | 24 | Set `both` for objects that do not necessarily being rendered separately so that those objects can be rendered by all the cameras. 25 | 26 | `auto` is used to divide the mesh into the head portion (`thirdPersonOnly`) and the others (`both`). See the details in the next section. 27 | 28 | | Name | First Person Camera (VR viewpoint) | Other Cameras | Example | 29 | |:----------------|:-----------------------------------|:------------------|------------------------------------------------------------------------------| 30 | | thirdPersonOnly | Rendering disable | Rendering enable | Objects that block VR view such as face, eyes, head, hair, hat, helmet, etc. | 31 | | firstPersonOnly | Rendering enable | Rendering disable | User interface that is only visible from the user's perspective view | 32 | | both | Rendering enable | Rendering enable | | 33 | | auto | | | Will describe later | 34 | 35 | ### MeshAnnotation.Auto Algorithm 36 | 37 | * For a mesh specified as `auto`, each vertex will be checked whether it contains the weight of Head bone (or the child of the Head bone) 38 | * Split the mesh into two groups: the first group contains triangles with HeadBone-related vertices while the second group contains triangles with the rest of the vertices 39 | * Set the mesh containing the HeadBone-related vertices as `thirdPersonOnly`. And another mesh is set as `both` 40 | 41 | ### When MeshAnnotation does not exist 42 | 43 | When you use the features of FirstPerson while there are meshes that do not have corresponding MeshAnnotation, 44 | You must assume MeshAnnotation for the meshes are `auto`. 45 | 46 | Also, when the `firstPerson` property itself does not exist in the VRM extension, 47 | You must assume all meshes are annotated as `auto`. 48 | -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/humanoid.ja.md: -------------------------------------------------------------------------------- 1 | # `VRMC_vrm.humanoid` 2 | 3 | 本文書では、 `VRMC_vrm` 拡張のうち `humanoid` フィールドについての仕様を示します。 4 | `humanoid bone` の一覧を定義します。 5 | 6 | ```json 7 | extensions.VRMC_vrm.humanoid = { 8 | "humanBones": { 9 | "hips": { 10 | "node": 1 // index of glTF.Node 11 | }, 12 | "spine": { 13 | "node": 2 14 | }, 15 | // 省略 16 | } 17 | } 18 | ``` 19 | 20 | 21 | 22 | **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* 23 | 24 | - [ヒューマノイドボーンの一覧](#%E3%83%92%E3%83%A5%E3%83%BC%E3%83%9E%E3%83%8E%E3%82%A4%E3%83%89%E3%83%9C%E3%83%BC%E3%83%B3%E3%81%AE%E4%B8%80%E8%A6%A7) 25 | - [胴](#%E8%83%B4) 26 | - [頭](#%E9%A0%AD) 27 | - [脚](#%E8%84%9A) 28 | - [腕](#%E8%85%95) 29 | - [指](#%E6%8C%87) 30 | - [ヒューマノイドボーンの親子関係](#%E3%83%92%E3%83%A5%E3%83%BC%E3%83%9E%E3%83%8E%E3%82%A4%E3%83%89%E3%83%9C%E3%83%BC%E3%83%B3%E3%81%AE%E8%A6%AA%E5%AD%90%E9%96%A2%E4%BF%82) 31 | 32 | 33 | 34 | ## ヒューマノイドボーンの一覧 35 | 36 | * ヒューマノイドボーンは VRM 内で同じものが複数存在してはいけません。 37 | * 表中の `-` は親ボーンが必ず存在するため、条件を考慮する必要が無いことを示します。 38 | 39 | ### 胴 40 | 41 | | ボーン名前 | 必須 | 親ボーン | 位置の目安 | 親ボーンの存在が必須 | 備考 | 42 | | :--------- | :--- | :--------- | ---------- | -------------------- | -------------------------------------------------------- | 43 | | hips | 必須 | (root) | 股間 | - | 通常、このボーンだけが移動し、他のボーンは回転だけします | 44 | | spine | 必須 | hips | 骨盤の上端 | - | | 45 | | chest | | spine | 胸郭の下端 | - | 0.X では必須でした | 46 | | upperChest | | chest | | Yes | chest が存在する場合にのみ、このボーンは存在できます | 47 | | neck | | upperChest | 首の付け根 | No | 0.X では必須でした | 48 | 49 | ### 頭 50 | 51 | | ボーン名前 | 必須 | 親ボーン | 位置の目安 | 親ボーンの存在が必須 | 備考 | 52 | | :--------- | :--- | :------- | ---------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | 53 | | head | 必須 | neck | 首の上端 | No | | 54 | | leftEye | | head | | - | [`VRMC_vrm.lookAt` 視線制御(オプション)](#vrmc_vrmlookat-%E8%A6%96%E7%B7%9A%E5%88%B6%E5%BE%A1%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3) | 55 | | rightEye | | head | | - | [`VRMC_vrm.lookAt` 視線制御(オプション)](#vrmc_vrmlookat-%E8%A6%96%E7%B7%9A%E5%88%B6%E5%BE%A1%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3) | 56 | | jaw | | head | | - | | 57 | 58 | ### 脚 59 | 60 | | ボーン名前 | 必須 | 親ボーン | 位置の目安 | 親ボーンの存在が必須 | 備考 | 61 | | :------------ | :--- | :------------ | -------------- | -------------------- | ---- | 62 | | leftUpperLeg | 必須 | hips | 脚の付け根 | - | | 63 | | leftLowerLeg | 必須 | leftUpperLeg | 膝 | - | | 64 | | leftFoot | 必須 | leftLowerLeg | 足首 | - | | 65 | | leftToes | | leftFoot | 足の指の付け根 | - | | 66 | | rightUpperLeg | 必須 | hips | 脚の付け根 | - | | 67 | | rightLowerLeg | 必須 | rightUpperLeg | 膝 | - | | 68 | | rightFoot | 必須 | rightLowerLeg | 足首 | - | | 69 | | rightToes | | rightFoot | 足の指の付け根 | - | | 70 | 71 | ### 腕 72 | 73 | | ボーン名前 | 必須 | 親ボーン | 位置の目安 | 親ボーンの存在が必須 | 備考 | 74 | | :------------ | :--- | :------------ | ------------ | -------------------- | ---- | 75 | | leftShoulder | | upperChest | | No | | 76 | | leftUpperArm | 必須 | leftShoulder | 上腕の付け根 | No | | 77 | | leftLowerArm | 必須 | leftUpperArm | 肘 | - | | 78 | | leftHand | 必須 | leftLowerArm | 手首 | - | | 79 | | rightShoulder | | upperChest | | No | | 80 | | rightUpperArm | 必須 | rightShoulder | 上腕の付け根 | No | | 81 | | rightLowerArm | 必須 | rightUpperArm | 肘 | - | | 82 | | rightHand | 必須 | rightLowerArm | 手首 | - | | 83 | 84 | ### 指 85 | 86 | | ボーン名前 | 必須 | 親ボーン | 位置の目安 | 親ボーンの存在が必須 | 備考 | 87 | | :---------------------- | :--- | :---------------------- | ---------- | -------------------- | ---- | 88 | | leftThumbMetacarpal | | leftHand | | - | | 89 | | leftThumbProximal | | leftThumbMetacarpal | | Yes | | 90 | | leftThumbDistal | | leftThumbProximal | | Yes | | 91 | | leftIndexProximal | | leftHand | | - | | 92 | | leftIndexIntermediate | | leftIndexProximal | | Yes | | 93 | | leftIndexDistal | | leftIndexIntermediate | | Yes | | 94 | | leftMiddleProximal | | leftHand | | - | | 95 | | leftMiddleIntermediate | | leftMiddleProximal | | Yes | | 96 | | leftMiddleDistal | | leftMiddleIntermediate | | Yes | | 97 | | leftRingProximal | | leftHand | | - | | 98 | | leftRingIntermediate | | leftRingProximal | | Yes | | 99 | | leftRingDistal | | leftRingIntermediate | | Yes | | 100 | | leftLittleProximal | | leftHand | | - | | 101 | | leftLittleIntermediate | | leftLittleProximal | | Yes | | 102 | | leftLittleDistal | | leftLittleIntermediate | | Yes | | 103 | | rightThumbMetacarpal | | rightHand | | - | | 104 | | rightThumbProximal | | rightThumbMetacarpal | | Yes | | 105 | | rightThumbDistal | | rightThumbProximal | | Yes | | 106 | | rightIndexProximal | | rightHand | | - | | 107 | | rightIndexIntermediate | | rightIndexProximal | | Yes | | 108 | | rightIndexDistal | | rightIndexIntermediate | | Yes | | 109 | | rightMiddleProximal | | rightHand | | - | | 110 | | rightMiddleIntermediate | | rightMiddleProximal | | Yes | | 111 | | rightMiddleDistal | | rightMiddleIntermediate | | Yes | | 112 | | rightRingProximal | | rightHand | | - | | 113 | | rightRingIntermediate | | rightRingProximal | | Yes | | 114 | | rightRingDistal | | rightRingIntermediate | | Yes | | 115 | | rightLittleProximal | | rightHand | | - | | 116 | | rightLittleIntermediate | | rightLittleProximal | | Yes | | 117 | | rightLittleDistal | | rightLittleIntermediate | | Yes | | 118 | 119 | ## ヒューマノイドボーンの親子関係 120 | 121 | * ヒューマノイドボーンは親ボーンが決まっています。必須でない親ボーンが存在しない場合は、親ボーンの親ボーンを探してください。 122 | * ヒューマノイドボーンの間にヒューマノイドボーンではないノードが入ることは許容されます(UpperLegとLowerLegの間にヒューマノイドボーンでないノードがあるなど) 123 | 124 | hips を root として以下のような親子になります。 125 | 126 | * root(ヒューマノイドボーンではない。原点) 127 | * hips 128 | * spine 129 | * (chest) 130 | * (upperChest) 131 | * (neck) 132 | * head 133 | * (leftEye) 134 | * (rightEye) 135 | * (jaw) 136 | * (leftShoulder) 137 | * leftUpperArm 138 | * leftLowerArm 139 | * leftHand 140 | * (fingers) 省略 141 | * (rightShoulder) 142 | * rightUpperArm 143 | * rightLowerArm 144 | * rightHand 145 | * (fingers) 省略 146 | * leftUpperLeg 147 | * leftLowerLeg 148 | * leftFoot 149 | * (leftToes) 150 | * rightUpperLeg 151 | * rightLowerLeg 152 | * rightFoot 153 | * (leftToes) 154 | -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/humanoid.md: -------------------------------------------------------------------------------- 1 | # `VRMC_vrm.humanoid` 2 | 3 | This document provides specifications for the `humanoid` field of the` VRMC_vrm` extension. 4 | Defines a list of `humanoid bone`. 5 | 6 | ```json 7 | extensions.VRMC_vrm.humanoid = { 8 | "humanBones": { 9 | "hips": { 10 | "node": 1 // index of glTF.Node 11 | }, 12 | "spine": { 13 | "node": 2 14 | }, 15 | // 16 | } 17 | } 18 | ``` 19 | 20 | 21 | 22 | **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* 23 | 24 | - [List of humanoid bones](#list-of-humanoid-bones) 25 | - [Torso](#torso) 26 | - [Head](#head) 27 | - [Leg](#leg) 28 | - [Arm](#arm) 29 | - [Finger](#finger) 30 | - [Humanoid bone parent-child relationship](#humanoid-bone-parent-child-relationship) 31 | 32 | 33 | 34 | ## Forbidden Transforms 35 | 36 | For transforms of humanoid bones, scale components MUST have positive values (zero is not permitted). 37 | 38 | ## List of humanoid bones 39 | 40 | * Humanoid bones must be unique in VRM. 41 | * `-` in the table indicates that the parent bone always exists, so the condition doesn't need to be considered. 42 | 43 | ### Torso 44 | 45 | | Bone Name | Required | Parent Bone | Estimated Position | Needs Parent Bone | Note | 46 | | :--------- | :------- | :---------- | :----------------- | :---------------- | :---------------------------------------------------- | 47 | | hips | Required | | Crotch | - | Usually only this bone moves. Other bones rotate only | 48 | | spine | Required | hips | Top of pelvis | - | | 49 | | chest | | spine | Bottom of rib cage | - | 0.X is required | 50 | | upperChest | | chest | | Yes | upperChest can exist only when chest exists | 51 | | neck | | upperChest | Base of neck | No | 0.X is required | 52 | 53 | * The bone equivalent to pelvis towards `Y-` direction from hips is deprecated (inverted pelvis). 54 | 55 | ### Head 56 | 57 | | Bone Name | Required | Parent Bone | Estimated Position | Needs Parent Bone | Note | 58 | | :-------- | :------- | :---------- | :----------------- | :---------------- | :------------------------------------------- | 59 | | head | Required | neck | Top of neck | No | | 60 | | leftEye | | head | | - | The model's eye movement controlled by bones | 61 | | rightEye | | head | | - | The model's eye movement controlled by bones | 62 | | jaw | | head | | - | | 63 | 64 | ### Leg 65 | 66 | | Bone Name | Required | Parent Bone | Estimated Position | Needs Parent Bone | Note | 67 | | :------------ | :------- | :------------ | :----------------- | :---------------- | :--- | 68 | | leftUpperLeg | Required | hips | groin | - | | 69 | | leftLowerLeg | Required | leftUpperLeg | knee | - | | 70 | | leftFoot | Required | leftLowerLeg | ankle | - | | 71 | | leftToes | | leftFoot | | - | | 72 | | rightUpperLeg | Required | hips | groin | - | | 73 | | rightLowerLeg | Required | rightUpperLeg | knee | - | | 74 | | rightFoot | Required | rightLowerLeg | ankle | - | | 75 | | rightToes | | rightFoot | | - | | 76 | 77 | ### Arm 78 | 79 | | Bone Name | Required | Parent Bone | Estimated Position | Needs Parent Bone | Note | 80 | | :------------ | :------- | :------------ | :----------------- | :---------------- | :--- | 81 | | leftShoulder | | upperChest | | No | | 82 | | leftUpperArm | Required | leftShoulder | Base of upper arm | No | | 83 | | leftLowerArm | Required | leftUpperArm | elbow | - | | 84 | | leftHand | Required | leftLowerArm | wrist | - | | 85 | | rightShoulder | | upperChest | | No | | 86 | | rightUpperArm | Required | rightShoulder | Base of upper arm | No | | 87 | | rightLowerArm | Required | rightUpperArm | elbow | - | | 88 | | rightHand | Required | rightLowerArm | wrist | - | | 89 | 90 | ### Finger 91 | 92 | | Bone Name | Required | Parent Bone | Estimated Position | Needs Parent Bone | Note | 93 | | :---------------------- | :------- | :---------------------- | :----------------- | :---------------- | :--- | 94 | | leftThumbMetacarpal | | leftHand | | - | | 95 | | leftThumbProximal | | leftThumbMetacarpal | | Yes | | 96 | | leftThumbDistal | | leftThumbProximal | | Yes | | 97 | | leftIndexProximal | | leftHand | | - | | 98 | | leftIndexIntermediate | | leftIndexProximal | | Yes | | 99 | | leftIndexDistal | | leftIndexIntermediate | | Yes | | 100 | | leftMiddleProximal | | leftHand | | - | | 101 | | leftMiddleIntermediate | | leftMiddleProximal | | Yes | | 102 | | leftMiddleDistal | | leftMiddleIntermediate | | Yes | | 103 | | leftRingProximal | | leftHand | | - | | 104 | | leftRingIntermediate | | leftRingProximal | | Yes | | 105 | | leftRingDistal | | leftRingIntermediate | | Yes | | 106 | | leftLittleProximal | | leftHand | | - | | 107 | | leftLittleIntermediate | | leftLittleProximal | | Yes | | 108 | | leftLittleDistal | | leftLittleIntermediate | | Yes | | 109 | | rightThumbMetacarpal | | rightHand | | - | | 110 | | rightThumbProximal | | rightThumbMetacarpal | | Yes | | 111 | | rightThumbDistal | | rightThumbProximal | | Yes | | 112 | | rightIndexProximal | | rightHand | | - | | 113 | | rightIndexIntermediate | | rightIndexProximal | | Yes | | 114 | | rightIndexDistal | | rightIndexIntermediate | | Yes | | 115 | | rightMiddleProximal | | rightHand | | - | | 116 | | rightMiddleIntermediate | | rightMiddleProximal | | Yes | | 117 | | rightMiddleDistal | | rightMiddleIntermediate | | Yes | | 118 | | rightRingProximal | | rightHand | | - | | 119 | | rightRingIntermediate | | rightRingProximal | | Yes | | 120 | | rightRingDistal | | rightRingIntermediate | | Yes | | 121 | | rightLittleProximal | | rightHand | | - | | 122 | | rightLittleIntermediate | | rightLittleProximal | | Yes | | 123 | | rightLittleDistal | | rightLittleIntermediate | | Yes | | 124 | 125 | ## Humanoid bone parent-child relationship 126 | 127 | * The parent bone of the humanoid bone is fixed. If no non-essential parent bone exists, look for the parent bone of the parent bone. 128 | * It is permissible to have non-humanoid bone nodes between humanoid bones (for example, there are non-humanoid bone nodes between Upper Leg and Lower Leg). 129 | 130 | With hips as root, the parent and child are as follows. 131 | 132 | * root (not a humanoid bone, origin) 133 | * hips 134 | * spine 135 | * (chest) 136 | * (upperChest) 137 | * (neck) 138 | * head 139 | * (leftEye) 140 | * (rightEye) 141 | * (jaw) 142 | * (leftShoulder) 143 | * leftUpperArm 144 | * leftLowerArm 145 | * leftHand 146 | * (fingers)... 147 | * (rightShoulder) 148 | * rightUpperArm 149 | * rightLowerArm 150 | * rightHand 151 | * (fingers)... 152 | * leftUpperLeg 153 | * leftLowerLeg 154 | * leftFoot 155 | * (leftToes) 156 | * rightUpperLeg 157 | * rightLowerLeg 158 | * rightFoot 159 | * (leftToes) 160 | 161 | -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/lookAt.ja.md: -------------------------------------------------------------------------------- 1 | # `VRMC_vrm.lookAt` 2 | 3 | 本文書では、 `VRMC_vrm` 拡張のうち `lookAt` フィールドについての仕様を示します。 4 | 5 | 6 | 7 | **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* 8 | 9 | - [概要](#%E6%A6%82%E8%A6%81) 10 | - [詳細](#%E8%A9%B3%E7%B4%B0) 11 | - [LookAtType](#lookattype) 12 | - [LookAt 空間(offsetFromHeadBone)](#lookat-%E7%A9%BA%E9%96%93offsetfromheadbone) 13 | - [範囲マップ](#%E7%AF%84%E5%9B%B2%E3%83%9E%E3%83%83%E3%83%97) 14 | - [LookAtのアルゴリズム](#lookat%E3%81%AE%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0) 15 | - [Yaw and Pitch in lookAt space](#yaw-and-pitch-in-lookat-space) 16 | - [Apply Yaw and Pitch to bone](#apply-yaw-and-pitch-to-bone) 17 | - [Apply Yaw and Pitch to expression](#apply-yaw-and-pitch-to-expression) 18 | 19 | 20 | 21 | ## 概要 22 | 23 | LookAtは、VRMモデルに対して視線のアニメーションを行うためのコンポーネントです。 24 | 25 | 初期姿勢時の `Head` ボーンをオフセットして得られる `LookAt空間` で視線を定義します。 26 | 視線値は、`LookAt空間` での 上下左右 の Degree 値です。 27 | 本文章では、右手系の Euler 角に準じた正の回転方向をもつ Yaw と Pitch で説明します。 28 | 29 | > Euler角については、プラットフォーム毎に、右手・左手、 Y-UP・Z-UP などをふまえて一貫性のある実装をしてください。 30 | 31 | 一組の yaw, pitch により両目が同じ方向を見ることを想定しています。 32 | このことより、寄り目等の両目が異なる方向を向く表現はできません。 33 | 34 | ## 詳細 35 | 36 | ```json 37 | extensions.VRMC_vrm.lookAt = { 38 | "offsetFromHeadBone": [ 39 | 0, 40 | 0.06, 41 | 0 42 | ], 43 | "rangeMapHorizontalInner": { 44 | "inputMaxValue": 90, 45 | "outputScale": 10 46 | }, 47 | "rangeMapHorizontalOuter": { 48 | "inputMaxValue": 90, 49 | "outputScale": 10 50 | }, 51 | "rangeMapVerticalDown": { 52 | "inputMaxValue": 90, 53 | "outputScale": 10 54 | }, 55 | "rangeMapVerticalUp": { 56 | "inputMaxValue": 90, 57 | "outputScale": 10 58 | }, 59 | "type": "bone" 60 | } 61 | ``` 62 | 63 | | 名前 | 備考 | 64 | |:------------------------|:---------------------------------------------------------------------| 65 | | type | bone または expression | 66 | | offsetFromHeadBone | lookAtの基準位置(両目の間が目安)へのヘッドボーンからの位置offsetです | 67 | | rangeMapHorizontalInner | 水平内側の目の可動範囲 | 68 | | rangeMapHorizontalOuter | 水平外側の目の可動範囲(ExpressionのLookLeft, LookRightはこれを使用) | 69 | | rangeMapVerticalDown | 下方向の目の可動範囲 | 70 | | rangeMapVerticalUp | 上方向の目の可動範囲 | 71 | 72 | ### LookAtType 73 | 74 | 下記の2種類を定義しています。 75 | 76 | | 名前 | 対象 | 値 | 77 | |:-----------|:--------------------------------------------------------|------------------| 78 | | bone | Humanoid leftEyeボーンとrightEyeボーン の LocalRotation | EulerAngles | 79 | | expression | Expression のLookAt, LookDown, LookLeft, LookRight | ExpressionWeight | 80 | 81 | > expression は、MorphTarget, MaterialColor, TextureTransform が可能です。 82 | > LookAt では、おもに MorphTarget による頂点移動 と TextureTransform による 目のテクスチャーの offset 移動により視線が表現されることが想定されています。 83 | 84 | ### LookAt 空間 (offsetFromHeadBone) 85 | 86 | モデルがある対象物体を見るような場合において、視線方向を決定するのに用いる「LookAt 空間」を定義します。 87 | 88 | LookAt 空間は、ワールド上のあるトランスフォームからの相対的な空間として定義され、このトランスフォームを以下のように定義します。 89 | 90 | * トランスフォームの親はheadであり、headの動きに追従して動く 91 | * トランスフォームのheadからのローカル位置は、プロパティ `offsetFromHeadBone` によって定められる 92 | * トランスフォームのheadからのローカル回転は、headのモデル空間におけるレスト回転の逆である 93 | 94 | > headがモデル空間におけるレスト回転によって、 `offsetFromHeadBone` による視点の位置の移動方向がモデル空間の軸と一致しない場合があります。 95 | > また、headがモデル空間におけるレスト回転を持っている場合も、視線の前方向はモデル座標系における+Z軸と一致します。 96 | 97 | 本文章では、glTF の右手系, Y-Up, Z-Forward 座標系を用いて説明します。 98 | Yaw, Pitch の正の方向は下記のとおりです。 99 | 100 | * Yaw: Z->X方向 => 左 101 | * Pitch: Y->Z方向 => 下 102 | 103 | ``` 104 | Y Forward 105 | ^ Z 106 | | / 107 | |/ 108 | X<----+ 109 | Left Right 110 | ``` 111 | 112 | `offsetFromHeadBone` は、VR向けHMDの位置を想定しています。 113 | モデルの一人称視点の位置の取得・反映に用いることができます。 114 | 115 | > Implementation note: モデルに `offsetFromHeadBone` が存在しない場合は、実装ごとに適切な値にフォールバックを行うことが推奨されます。 116 | 117 | 118 | ### 範囲マップ 119 | 120 | `LookAt空間` で評価された視線値 `Yaw` と `Pitch` を `bone` または `expression` に適用する前に、値を加工できます。 121 | 122 | ![range_map](./figures/range_map.png) 123 | 124 | | name | 機能 | 125 | |---------------|-----------------------------------------------------------------------------------------| 126 | | inputMaxValue | Yaw または Pitch の上限値。この値が小さいほど、同じ視線値に対して視線は大きく動きます。 | 127 | | outputScale | `bone の回転` または `Expression の Weight` の最大値。 | 128 | 129 | #### inputMaxValueが0の場合の挙動 130 | 131 | inputMaxValueが0に設定されている場合、視線値が0の場合は0を・それ以外の場合は `outputScale` を適用することを推奨します(SHOULD)。 132 | 133 | > Implementation note: これは、 `inputMaxValue` が0の場合に、0除算を避けるための仕様です。 134 | > 上記に十分に近い挙動を実現するために、 `inputMaxValue` に対して `max(0.001, inputMaxValue)` などの処理を行うことが想定されます。 135 | 136 | #### type が bone のときの 解釈 137 | 138 | `yaw`, `pitch` の視線値から、`leftEye` ボーンと `rightEye` ボーンに対する `local rotation` を生成します。 139 | `水平内側`, `水平外側`, `垂直上側`, `垂直下側` の4つの区分があります。 140 | 141 | 上下左右の rangeMap の使い分けは下記のようになります。 142 | 143 | ``` 144 | + yaw - + yaw - 145 | ^ ^ 146 | | | 147 | outer|inner inner|outer 148 | left eye right eye 149 | ``` 150 | 151 | | | leftEye rangeMap | rightEye rangeMap | 152 | |-------------|-------------------------|-------------------------| 153 | | Yaw>0(左) | rangeMapHorizontalOuter | rangeMapHorizontalInner | 154 | | Yaw<0(右) | rangeMapHorizontalInner | rangeMapHorizontalOuter | 155 | | Pitch>0(下) | rangeMapVerticalDown | rangeMapVerticalDown | 156 | | Pitch<0(上) | rangeMapVerticalUp | rangeMapVerticalUp | 157 | 158 | 範囲マップは、視線値によって得られたEuler角 (degree) の絶対値に対して行います。 159 | 出力の単位は、目のボーンのEuler角 (degree) となります。 160 | 161 | ``` 162 | const boneLocalEulerAngle = min(fabs(value), inputMaxValue)/inputMaxValue * outputScale; 163 | ``` 164 | 165 | #### type が expression のときの解釈 166 | 167 | `lookUp` Expression, `lookDown` Expression, `lookLeft` Expression, `lookRight` Expression に対する `weight` を生成します。 168 | `水平`, `垂直上側`, `垂直下側` の3つの区分があります。 169 | ひとつの Expression で両目がまとめて変化するため、`水平内側`, `水平外側` の区別が無いことに注意してください。 170 | `rangeMapHorizontalOuter` を使います。 171 | 172 | | | expression | rangeMap | 173 | |-------------|------------|-------------------------| 174 | | Yaw>0(左) | lookLeft | rangeMapHorizontalOuter | 175 | | Yaw<0(右) | lookRight | rangeMapHorizontalOuter | 176 | | Pitch>0(下) | lookDown | rangeMapVerticalDown | 177 | | Pitch<0(上) | lookUp | rangeMapVerticalUp | 178 | 179 | 範囲マップは、視線値によって得られたEuler角 (degree) の絶対値に対して行います。 180 | 出力の単位は、目のexpressionのweight値となります。 181 | 182 | ``` 183 | const expressionWeight = min(fabs(value), inputMaxValue)/inputMaxValue * outputScale; 184 | ``` 185 | 186 | ## LookAtのアルゴリズム 187 | ### Yaw and Pitch in lookAt space 188 | 189 | ```cs 190 | public static (float Yaw, float Pitch) CalcYawPitch(this Matrix4x4 lookAtSpace, Vector3 target) 191 | { 192 | var localTarget = lookAtSpace.inverse.MultiplyPoint(target); 193 | 194 | var z = Vector3.Dot(localPosition, Vector3.forward); 195 | var x = Vector3.Dot(localPosition, Vector3.right); 196 | var yaw = (float)Math.Atan2(x, z) * Mathf.Rad2Deg; 197 | 198 | // x+y z plane 199 | var xz = Mathf.sqrt(x * x + z * z); 200 | var y = Vector3.Dot(localPosition, Vector3.up); 201 | var pitch = (float)Math.Atan2(-y, xz) * Mathf.Rad2Deg; 202 | 203 | return (yaw, pitch); 204 | } 205 | ``` 206 | 207 | ### Apply Yaw and Pitch to bone 208 | 209 | ``` 210 | function applyLeftEyeBone(vrm, yawDegrees, pitchDegrees) 211 | { 212 | var yaw = 0; 213 | if(yawDegrees>0) 214 | { 215 | // left => outer 216 | yaw = min(fabs(yawDegrees), rangeMapHorizontalOuter.inputMaxValue) / rangeMapHorizontalOuter.inputMaxValue * rangeMapHorizontalOuter.outputScale; 217 | } 218 | else{ 219 | // right => inner 220 | yaw = -min(fabs(yawDegrees), rangeMapHorizontalInner.inputMaxValue) / rangeMapHorizontalInner.inputMaxValue * rangeMapHorizontalInner.outputScale; 221 | } 222 | 223 | var pitch = 0; 224 | if(pitchDegrees>0) 225 | { 226 | // down 227 | pitch = min(fabs(pitchDegrees), rangeMapVerticalDown.inputMaxValue) / rangeMapVerticalDown.inputMaxValue * rangeMapVerticalDown.outScale; 228 | } 229 | else{ 230 | // up 231 | pitch = -min(fabs(pitchDegrees), rangeMapVerticalUp.inputMaxValue) / rangeMapVerticalUp.inputmaxValue * rangeMapVerticalUp.outScale; 232 | } 233 | 234 | vrm.humanoid.leftEye.localRotation = Quaternion.from_YXZEuler(yaw, pitch, 0); 235 | } 236 | 237 | function applyRightEyeBone(vrm, yawDegrees, pitchDegrees) 238 | { 239 | var yaw = 0; 240 | if(yawDegrees>0) 241 | { 242 | // left => inner 243 | yaw = min(fabs(yawDegrees), rangeMapHorizontalInner.inputMaxValue) / rangeMapHorizontalInner.inputMaxValue * rangeMapHorizontalInner.outputScale; 244 | } 245 | else{ 246 | // right => outer 247 | yaw = -min(fabs(yawDegrees), rangeMapHorizontalOuter.inputMaxValue) / rangeMapHorizontalOuter.inputMaxValue * rangeMapHorizontalOuter.outputScale; 248 | } 249 | 250 | var pitch = 0; 251 | if(pitchDegrees>0) 252 | { 253 | // down 254 | pitch = min(fabs(pitchDegrees), rangeMapVerticalDown.inputMaxValue) / rangeMapVerticalDown.inputMaxValue * rangeMapVerticalDown.outScale; 255 | } 256 | else{ 257 | // up 258 | pitch = -min(fabs(pitchDegrees), rangeMapVerticalUp.inputMaxValue) / rangeMapVerticalUp.inputmaxValue * rangeMapVerticalUp.outScale; 259 | } 260 | 261 | vrm.humanoid.rightEye.localRotation = Quaternion.from_YXZEuler(yaw, pitch, 0); 262 | } 263 | ``` 264 | 265 | ### Apply Yaw and Pitch to expression 266 | 267 | ``` 268 | function applyExpression(vrm, yawDegrees, pitchDegrees) 269 | { 270 | // horizontal 271 | if(yawDegrees>0) 272 | { 273 | // left 274 | const yawWeight = min(fabs(yawDegrees), rangeMapHorizontalOuter.inputMaxValue)/rangeMapHorizontalOuter.inputMaxValue * rangeMapHorizontalOuter.outputScale; 275 | vrm.expression.setWeight(LOOK_LEFT, yawWeight); 276 | vrm.expression.setWeight(LOOK_RIGHT, 0); 277 | } 278 | else{ 279 | // right 280 | const yawWeight = min(fabs(yawDegrees), rangeMapHorizontalOuter.inputMaxValue)/rangeMapHorizontalOuter.inputMaxValue * rangeMapHorizontalOuter.outputScale; 281 | vrm.expression.setWeight(LOOK_LEFT, 0); 282 | vrm.expression.setWeight(LOOK_RIGHT, yawWeight); 283 | } 284 | 285 | // vertical 286 | if(pitchDegrees>0) 287 | { 288 | // down 289 | const pitchWeight = min(fabs(pitchDegrees), rangeMapVerticalDown.inputMaxValue)/rangeMapVerticalDown.inputMaxValue * rangeMapVerticalDown.outputScale; 290 | vrm.expression.setWeight(LOOK_DOWN, pitchWeight); 291 | vrm.expression.setWeight(LOOK_UP, 0); 292 | } 293 | else{ 294 | // up 295 | const pitchWeight = min(fabs(pitchDegrees), rangeMapVerticalUp.inputMaxValue)/rangeMapVerticalUp.inputMaxValue * rangeMapVerticalUp.outputScale; 296 | vrm.expression.setWeight(LOOK_DOWN, 0); 297 | vrm.expression.setWeight(LOOK_UP, pitchWeight); 298 | } 299 | } 300 | ``` 301 | -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/meta.ja.md: -------------------------------------------------------------------------------- 1 | # `VRMC_vrm.meta` 2 | 3 | 本文書では、 `VRMC_vrm` 拡張のうち `meta` フィールドについての仕様を示します。 4 | 5 | 6 | 7 | **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* 8 | 9 | - [Meta](#meta) 10 | - [ライセンス](#%E3%83%A9%E3%82%A4%E3%82%BB%E3%83%B3%E3%82%B9) 11 | - [glTF Schema Updates](#gltf-schema-updates) 12 | - [プロパティ](#%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3) 13 | - [meta.name ✅](#metaname-) 14 | - [meta.version](#metaversion) 15 | - [meta.authors ✅](#metaauthors-) 16 | - [meta.copyrightInformation](#metacopyrightinformation) 17 | - [meta.contactInformation](#metacontactinformation) 18 | - [meta.references](#metareferences) 19 | - [meta.thirdPartyLicenses](#metathirdpartylicenses) 20 | - [meta.thumbnailImage](#metathumbnailimage) 21 | - [meta.licenseUrl ✅](#metalicenseurl-) 22 | - [meta.avatarPermission](#metaavatarpermission) 23 | - [meta.allowExcessivelyViolentUsage](#metaallowexcessivelyviolentusage) 24 | - [meta.allowExcessivelySexualUsage](#metaallowexcessivelysexualusage) 25 | - [meta.commercialUsage](#metacommercialusage) 26 | - [meta.allowPoliticalOrReligiousUsage](#metaallowpoliticalorreligioususage) 27 | - [meta.allowAntisocialOrHateUsage](#metaallowantisocialorhateusage) 28 | - [meta.creditNotation](#metacreditnotation) 29 | - [meta.allowRedistribution](#metaallowredistribution) 30 | - [meta.modification](#metamodification) 31 | - [meta.otherLicenseUrl](#metaotherlicenseurl) 32 | 33 | 34 | 35 | ## Meta 36 | 37 | VRMの `meta` フィールドでは、モデルに関するメタ情報を記述することができます。 38 | メタ情報には、モデルの名前や作者などの基本的な情報に加え、モデルの利用条件に関わる情報を記述することができます。 39 | 40 | ## ライセンス 41 | 42 | VRM拡張では、モデルのライセンス情報を `meta` フィールドに記述することができます。 43 | 44 | `meta` フィールドに格納されるライセンス情報は、ライセンス文書へのURLとライセンス設定によって構成されます。 45 | ライセンス文書は、VRMコンソーシアムによって制定されたVRMパブリック・ライセンス文書を指し、 `meta.licenseUrl` に文書へのユニークなURLが格納されている必要があります。 46 | ライセンス設定は、ライセンス文書から参照される個別の設定であり、モデルのライセンサーが自由に指定することができます。 47 | 48 | ### licenseUrl 49 | 50 | `licenseUrl` プロパティは、VRM1.0においては `https://vrm.dev/licenses/1.0/` を許容します。 51 | 52 | ## glTF Schema Updates 53 | 54 | ### プロパティ 55 | 56 | | 名前 | 値 | 説明 | 必須 | 57 | |:-------------------------------|:-----------|:-----------------------------------------------|:--------------------------------| 58 | | name | `string` | モデルの名前 | ✅ Yes | 59 | | version | `string` | モデルのバージョン | No | 60 | | authors | `string[]` | モデルの作者名 | ✅ Yes | 61 | | copyrightInformation | `string` | モデルの著作権者 | No | 62 | | contactInformation | `string` | モデルの作者(代表者)への連絡先 | No | 63 | | references | `string[]` | モデルの「親作品」となるようなものがあれば、その情報 | No | 64 | | thirdPartyLicenses | `string` | モデルのサードパーティライセンス表記 | No | 65 | | thumbnailImage | `integer` | モデルのサムネイルとなる画像へのインデックス | No | 66 | | licenseUrl | `string` | このモデルが参照するVRMライセンス文書へのURL | ✅ Yes | 67 | | avatarPermission | `string` | このモデルに人格を与えることの許諾範囲 | No, 初期値: `OnlyAuthor` | 68 | | allowExcessivelyViolentUsage | `boolean` | このモデルの過剰な暴力表現を含むコンテンツでの利用を許可するか | No, 初期値: `false` | 69 | | allowExcessivelySexualUsage | `boolean` | このモデルの過剰な性的表現を含むコンテンツでの利用を許可するか | No, 初期値: `false` | 70 | | commercialUsage | `string` | このモデルを利用した商用利用の許可範囲 | No, 初期値: `personalNonProfit` | 71 | | allowPoliticalOrReligiousUsage | `boolean` | このモデルの政治・宗教用途での利用を許可するか | No, 初期値: `false` | 72 | | allowAntisocialOrHateUsage | `boolean` | このモデルの反社会的・憎悪表現を含むコンテンツでの利用を許可するか | No, 初期値: `false` | 73 | | creditNotation | `string` | このモデルのクレジット表記の強制および放棄の指定 | No, 初期値: `required` | 74 | | allowRedistribution | `boolean` | このモデルの再配布を許可するか | No, 初期値: `false` | 75 | | modification | `string` | このモデルの改変の許可範囲 | No, 初期値: `prohibited` | 76 | | otherLicenseUrl | `string` | その他のライセンス条件があれば、そのURL | No | 77 | 78 | ### meta.name ✅ 79 | 80 | モデルの名前です。 81 | 82 | - 型: `string` 83 | - 必須: Yes 84 | 85 | ### meta.version 86 | 87 | モデルのバージョンです。 88 | 89 | - 型: `string` 90 | - 必須: No 91 | 92 | ### meta.authors ✅ 93 | 94 | モデルの作者名です。 95 | 96 | 必ず、一つ以上の空文字でない項目が必要です。 97 | アバターの造形者・代表者名を最初に書くことを推奨します。 98 | 99 | - 型: `string[]` 100 | - 必須: Yes 101 | 102 | ### meta.copyrightInformation 103 | 104 | モデルの著作権者です。 105 | 106 | このモデルの著作権を表示するために使われることを想定しており、直前の `authors` とは明確に区別して扱います。 107 | 108 | - 型: `string` 109 | - 必須: No 110 | 111 | ### meta.contactInformation 112 | 113 | モデルの作者(代表者)への連絡先です。 114 | 115 | > このプロパティは、ユーザーがなんらかの理由で作者に連絡を取りたい場合に備えて、ソーシャルアカウントの情報やWebサイトなど、モデルの作者の連絡先情報を表示するために使用されることを意図しています。 116 | > 電話番号や住所など、公衆に公開されることを意図しない個人情報を含めないようにしてください。 117 | 118 | - 型: `string` 119 | - 必須: No 120 | 121 | ### meta.references 122 | 123 | モデルの「親作品」となるようなものがあれば、その情報を記述します。 124 | 125 | - 型: `string[]` 126 | - 必須: No 127 | 128 | ### meta.thirdPartyLicenses 129 | 130 | モデルのサードパーティライセンス表記が必要であれば、ここに記述します。 131 | 132 | 改行を用いて、複数行に渡る文書を記述可能です。 133 | 134 | - 型: `string` 135 | - 必須: No 136 | 137 | ### meta.thumbnailImage 138 | 139 | モデルのサムネイルを、 `gltf.images` に定義されたインデックスを用いて指定します。 140 | 141 | 画像は正方形である必要があります。解像度は 1024x1024 を推奨します。 142 | 利便性のため、画像は glTF が標準でサポートする jpg もしくは png である必要があります。 143 | 拡張を用いて他形式を用いることは許可されません。 144 | 145 | VRMを利用するアプリケーションが、モデルのアイコンとして表示することを想定しています。 146 | 147 | - 型: `integer` 148 | - 必須: No 149 | - 最小値: `>= 0` 150 | 151 | ### meta.licenseUrl ✅ 152 | 153 | このモデルが参照する、ライセンス文書へのURLを指定します。 154 | VRMパブリック・ライセンス文書へのユニークなURLが格納されている必要があります。 155 | 156 | - 型: `string` 157 | - 必須: Yes 158 | 159 | ### meta.avatarPermission 160 | 161 | このモデルをアバターとして操作し演じることを許可するユーザを指定します。 162 | 163 | `onlyAuthor` は、モデルの作者のみにアバターとしての操作が許可されることを示します。 164 | `onlySeparatelyLicensedPerson` は、別の文書でライセンス許諾されたユーザにアバターとしての操作が許可されることを示します。例えば、有料で販売されるモデルに対して用いられることを想定しています。 165 | `everyone` は、誰にでもこのモデルをアバターとして操作することが許可されることを示します。 166 | 167 | - 型: `string` 168 | - 必須: No, 初期値: `onlyAuthor` 169 | - 許可された値: 170 | - `onlyAuthor` 171 | - `onlySeparatelyLicensedPerson` 172 | - `everyone` 173 | 174 | ### meta.allowExcessivelyViolentUsage 175 | 176 | このモデルを、過度の暴力表現を含むコンテンツに利用することを許可するか否かを指定します。 177 | 178 | - 型: `boolean` 179 | - 必須: No, 初期値: `false` 180 | 181 | ### meta.allowExcessivelySexualUsage 182 | 183 | このモデルを、過度の性的表現を含むコンテンツに利用することを許可するか否かを指定します。 184 | 185 | - 型: `boolean` 186 | - 必須: No, 初期値: `false` 187 | 188 | ### meta.commercialUsage 189 | 190 | このモデルを商用利用することを許可するかを指定します。 191 | 192 | `personalNonProfit` は、個人のユーザが非商用目的に限り利用することを許可することを示します。 193 | `personalProfit` は、個人のユーザが商用・非商用のどちらの目的に関わらず利用することを許可することを示します。 194 | 法人のユーザは、このプロパティが `corporation` でない限り、該当するモデルの利用が許可されません。 195 | 196 | - 型: `string` 197 | - 必須: No, 初期値: `personalNonProfit` 198 | - 許可された値: 199 | - `personalNonProfit` 200 | - `personalProfit` 201 | - `corporation` 202 | 203 | ### meta.allowPoliticalOrReligiousUsage 204 | 205 | このモデルを、政治的・宗教的なコンテンツに対して利用することを許可するか否かを指定します。 206 | 207 | - 型: `boolean` 208 | - 必須: No, 初期値: `false` 209 | 210 | ### meta.allowAntisocialOrHateUsage 211 | 212 | このモデルを、反社会的・憎悪表現を含むコンテンツに対して利用することを許可するか否かを指定します。 213 | 214 | - 型: `boolean` 215 | - 必須: No, 初期値: `false` 216 | 217 | ### meta.creditNotation 218 | 219 | このモデルのクレジット表記を要求することを指定します。 220 | 221 | このプロパティが `required` の場合、ユーザはモデルのクレジット表記を必ずしなければなりません。 222 | このプロパティが `unnecessary` の場合、ユーザはモデルのクレジット表記を必ずする必要はありません。 223 | 224 | - 型: `string` 225 | - 必須: No, 初期値: `required` 226 | - 許可された値: 227 | - `required` 228 | - `unnecessary` 229 | 230 | ### meta.allowRedistribution 231 | 232 | このモデルを再配布することを許可するか否かを指定します。 233 | 234 | - 型: `boolean` 235 | - 必須: No, 初期値: `false` 236 | 237 | ### meta.modification 238 | 239 | このモデルを改変することを許可するか否か、および改変したモデルの再配布を許可するか否かを指定します。 240 | 241 | このプロパティが `prohibited` の場合、モデルの改変を許可しないことを示します。 242 | このプロパティが `allowModification` もしくは `allowModificationRedistribution` の場合、モデルの改変を許可することを示します。 243 | このプロパティが `allowModificationRedistribution` の場合、改変したモデルの再配布を許可することを示します。 244 | 245 | - 型: `string` 246 | - 必須: No, 初期値: `prohibited` 247 | - 許可された値: 248 | - `prohibited` 249 | - `allowModification` 250 | - `allowModificationRedistribution` 251 | 252 | ### meta.otherLicenseUrl 253 | 254 | その他のライセンス条件があれば、そのURLを指定します。 255 | 256 | - 型: `string` 257 | - 必須: No 258 | -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/meta.md: -------------------------------------------------------------------------------- 1 | # `VRMC_vrm.meta` 2 | 3 | In this document, the `meta` field of `VRMC_vrm` extension will be explained. 4 | 5 | ## Meta 6 | 7 | In the `meta` field of VRM, you can describe meta information about the model. 8 | `meta` contains not only basic model information like the name and authors of the model but also information about the use conditions of the model. 9 | 10 | ## License 11 | 12 | In the VRM extension, license information will be specified in the `meta` field. 13 | 14 | The license information of `meta` consists of a URL of a license document and license settings. 15 | The license document is a document of VRM Public License established by VRM Consortium. `meta.licenseUrl` field must have a unique URL towards the document. 16 | License settings are settings that are referred from the license document and a licenser of the model can specify. 17 | 18 | ### licenseUrl 19 | 20 | The property `licenseUrl` accepts `https://vrm.dev/licenses/1.0/` in VRM1.0. 21 | 22 | ## glTF Schema Updates 23 | 24 | ### Properties 25 | 26 | | Name | Value | Description | Required | 27 | |:-------------------------------|:-----------|:---------------------------------------------------------------------------|:---------------------------------| 28 | | name | `string` | The name of the model | ✅ Yes | 29 | | version | `string` | The version of the model | No | 30 | | authors | `string[]` | Authors of the model | ✅ Yes | 31 | | copyrightInformation | `string` | Information that describes the copyright of the model | No | 32 | | contactInformation | `string` | The contact information of the author | No | 33 | | references | `string[]` | References / original works of the model | No | 34 | | thirdPartyLicenses | `string` | Third party licenses of the model | No | 35 | | thumbnailImage | `integer` | The index to access the thumbnail image of the model | No | 36 | | licenseUrl | `string` | A URL towards the license document this model refers | ✅ Yes | 37 | | avatarPermission | `string` | The person who can act as an avatar with this model | No, default: `onlyAuthor` | 38 | | allowExcessivelyViolentUsage | `boolean` | Perform violent acts with this model | No, default: `false` | 39 | | allowExcessivelySexualUsage | `boolean` | Perform sexual acts with this model | No, default: `false` | 40 | | commercialUsage | `string` | Commercial use | No, default: `personalNonProfit` | 41 | | allowPoliticalOrReligiousUsage | `boolean` | Permission for political or religious purposes | No, default: `false` | 42 | | allowAntisocialOrHateUsage | `boolean` | Permission for content that contains anti-social activities or hate speech | No, default: `false` | 43 | | creditNotation | `string` | An option that forces or omits displaying the credit of this model. | No, default: `required` | 44 | | allowRedistribution | `boolean` | A flag that permits redistribution of this model | No, default: `false` | 45 | | modification | `string` | An option that controls the condition for modifying this mode | No, default: `prohibited` | 46 | | otherLicenseUrl | `string` | Describe the URL links of other license | No | 47 | 48 | ### meta.name ✅ 49 | 50 | The name of the model. 51 | 52 | - Type: `string` 53 | - Required: Yes 54 | 55 | ### meta.version 56 | 57 | The version of the model. 58 | 59 | - Type: `string` 60 | - Required: No 61 | 62 | ### meta.authors ✅ 63 | 64 | Authors of the model. 65 | 66 | Must have at least one entry that is not an empty string. 67 | Putting model creator/first author name at the beginning is recommended. 68 | 69 | - Type: `string[]` 70 | - Required: Yes 71 | 72 | ### meta.copyrightInformation 73 | 74 | Information that describes the copyright of the model. 75 | 76 | Since this property is intended to be used to display the copyright holder of the model, it must be distinguished from the previous property `authors`. 77 | 78 | - Type: `string` 79 | - Required: No 80 | 81 | ### meta.contactInformation 82 | 83 | Information that describes the contact information of the author. 84 | 85 | > This property is intended to be used to display the contact information of the author of the model such as social account information or website, in case the user wants to contact the author for some reason. 86 | > Make sure not to include personal information that is not intended to be disclosed to the public, such as phone numbers or addresses. 87 | 88 | - Type: `string` 89 | - Required: No 90 | 91 | ### meta.references 92 | 93 | References / original works of the model. 94 | 95 | - Type: `string[]` 96 | - Required: No 97 | 98 | ### meta.thirdPartyLicenses 99 | 100 | Third party licenses of the model, if required. 101 | 102 | You can use line breaks in this property. 103 | 104 | - Type: `string` 105 | - Required: No 106 | 107 | ### meta.thumbnailImage 108 | 109 | The index to access the thumbnail image of the model in `gltf.images` . 110 | 111 | The thumbnail image must be square. Preferable resolution is 1024 x 1024. 112 | For convenience, the image must be either jpg or png that is supported in glTF by its core specification. 113 | Use of other formats using extensions is not allowed. 114 | 115 | Intended to be used in applications that uses VRMs, as an icon of the model. 116 | 117 | - Type: `integer` 118 | - Required: No 119 | - Minimum: `>= 0` 120 | 121 | ### meta.licenseUrl ✅ 122 | 123 | A URL towards the license document this model refers to. 124 | It must be a unique URL to VRM Public License. 125 | 126 | - Type: `string` 127 | - Required: Yes 128 | 129 | ### meta.avatarPermission 130 | 131 | The person who can perform as an avatar with this model. 132 | 133 | `onlyAuthor` indicates people cannot use this model as an avatar unless they are the author. 134 | `onlySeparatelyLicensedPerson` indicates that people who are licensed in separated documents can use this model as an avatar. Intended to be used when the model is a paid model, for example. 135 | `everyone` indicates anyone can use this model as an avatar. 136 | 137 | - Type: `string` 138 | - Required: No, default: `onlyAuthor` 139 | - Allowed values: 140 | - `onlyAuthor` 141 | - `onlySeparatelyLicensedPerson` 142 | - `everyone` 143 | 144 | ### meta.allowExcessivelyViolentUsage 145 | 146 | A flag that permits use of this model in excessively violent content. 147 | 148 | - Type: `boolean` 149 | - Required: No, default: `false` 150 | 151 | ### meta.allowExcessivelySexualUsage 152 | 153 | A flag that permits use of this model in excessively sexual content. 154 | 155 | - Type: `boolean` 156 | - Required: No, default: `false` 157 | 158 | ### meta.commercialUsage 159 | 160 | An option that permits use of this model in commercial products. 161 | 162 | `personalNonProfit` indicates personal users can use this model only if they are not going to make a profit from its use. 163 | `personalProfit` indicates personal users can use this model whether they are going to make a profit from its use or not. 164 | Corporate organization users cannot use this model unless the property is `corporation`. 165 | 166 | - Type: `string` 167 | - Required: No, default: `personalNonProfit` 168 | - Allowed values: 169 | - `personalNonProfit` 170 | - `personalProfit` 171 | - `corporation` 172 | 173 | ### meta.allowPoliticalOrReligiousUsage 174 | 175 | A flag that permits use of the model in political or religious content. 176 | 177 | - Type: `boolean` 178 | - Required: No, default: `false` 179 | 180 | ### meta.allowAntisocialOrHateUsage 181 | 182 | A flag that permits use of this model in content that contains anti-social activities or hate speech. 183 | 184 | - Type: `boolean` 185 | - Required: No, default: `false` 186 | 187 | ### meta.creditNotation 188 | 189 | An option that requires displaying the credit of this model. 190 | 191 | When the property is `required`, users of the model must show the credit of the model. 192 | When the property is `unnecessary`, users of the model do not have to show the credit of the model. 193 | 194 | - Type: `string` 195 | - Required: No, default: `required` 196 | - Allowed values: 197 | - `required` 198 | - `unnecessary` 199 | 200 | ### meta.allowRedistribution 201 | 202 | A flag that permits redistribution of this model. 203 | 204 | - Type: `boolean` 205 | - Required: No, default: `false` 206 | 207 | ### meta.modification 208 | 209 | An option that gives permission to modify the model, or redistribute the modified model. 210 | 211 | When the property is `prohibited`, users cannot modify the model. 212 | When the property is either `allowModification` or `allowModificationRedistribution`, users can modify the model. 213 | When the property is `allowModificationRedistribution`, users can redistribute the modified model. 214 | 215 | - Type: `string` 216 | - Required: No, default: `prohibited` 217 | - Allowed values: 218 | - `prohibited` 219 | - `allowModification` 220 | - `allowModificationRedistribution` 221 | 222 | ### meta.otherLicenseUrl 223 | 224 | Describe the URL links of other license. 225 | 226 | - Type: `string` 227 | - Required: No 228 | -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/schema/VRMC_vrm.expressions.expression.materialColorBind.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "MaterialColorBind", 3 | "type": "object", 4 | "description": "Material color value associated with a expression", 5 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 6 | "properties": { 7 | "material": { 8 | "allOf": [ { "$ref": "glTFid.schema.json" } ], 9 | "description": "target material" 10 | }, 11 | "type": { 12 | "title": "MaterialColorType", 13 | "type": "string", 14 | "enum": [ 15 | "color", 16 | "emissionColor", 17 | "shadeColor", 18 | "matcapColor", 19 | "rimColor", 20 | "outlineColor" 21 | ] 22 | }, 23 | "targetValue": { 24 | "type": "array", 25 | "description": "target color", 26 | "items": { 27 | "type": "number" 28 | }, 29 | "minItems": 4, 30 | "maxItems": 4 31 | }, 32 | "extensions": { }, 33 | "extras": { } 34 | }, 35 | "required": [ 36 | "material", 37 | "type", 38 | "targetValue" 39 | ] 40 | } -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/schema/VRMC_vrm.expressions.expression.morphTargetBind.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "MorphTargetBind", 3 | "type": "object", 4 | "description": "Morph target value associated with a expression", 5 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 6 | "properties": { 7 | "node": { 8 | "allOf": [{ "$ref": "glTFid.schema.json" }], 9 | "description": "The index of the node that attached to target mesh." 10 | }, 11 | "index": { 12 | "allOf": [{ "$ref": "glTFid.schema.json" }], 13 | "description": "The index of the morph target in the mesh." 14 | }, 15 | "weight": { 16 | "type": "number", 17 | "description": "The weight value of target morph target." 18 | }, 19 | "extensions": { }, 20 | "extras": { } 21 | }, 22 | "required": [ 23 | "node", 24 | "index", 25 | "weight" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/schema/VRMC_vrm.expressions.expression.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Expression", 3 | "type": "object", 4 | "description": "Definition of expression by weighted animation", 5 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 6 | "properties": { 7 | "morphTargetBinds": { 8 | "type": "array", 9 | "description": "Specify a morph target", 10 | "items": { 11 | "$ref": "VRMC_vrm.expressions.expression.morphTargetBind.schema.json" 12 | }, 13 | "minItems": 1 14 | }, 15 | "materialColorBinds": { 16 | "type": "array", 17 | "description": "Material color animation references", 18 | "items": { 19 | "$ref": "VRMC_vrm.expressions.expression.materialColorBind.schema.json" 20 | }, 21 | "minItems": 1 22 | }, 23 | "textureTransformBinds": { 24 | "type": "array", 25 | "description": "Texture transform animation references", 26 | "items": { 27 | "$ref": "VRMC_vrm.expressions.expression.textureTransformBind.schema.json" 28 | }, 29 | "minItems": 1 30 | }, 31 | "isBinary": { 32 | "type": "boolean", 33 | "default": false, 34 | "description": "A value greater than 0.5 is 1.0, otherwise 0.0" 35 | }, 36 | "overrideBlink": { 37 | "title": "ExpressionOverrideType", 38 | "type": "string", 39 | "enum": [ 40 | "none", 41 | "block", 42 | "blend" 43 | ], 44 | "default": "none", 45 | "description": "Override values of Blink expressions when this Expression is enabled" 46 | }, 47 | "overrideLookAt": { 48 | "title": "ExpressionOverrideType", 49 | "type": "string", 50 | "enum": [ 51 | "none", 52 | "block", 53 | "blend" 54 | ], 55 | "default": "none", 56 | "description": "Override values of LookAt expressions when this Expression is enabled" 57 | }, 58 | "overrideMouth": { 59 | "title": "ExpressionOverrideType", 60 | "type": "string", 61 | "enum": [ 62 | "none", 63 | "block", 64 | "blend" 65 | ], 66 | "default": "none", 67 | "description": "Override values of Mouth expressions when this Expression is enabled" 68 | }, 69 | "extensions": { }, 70 | "extras": { } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/schema/VRMC_vrm.expressions.expression.textureTransformBind.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "TextureTransformBind", 3 | "type": "object", 4 | "description": "Texture transform value associated with a expression", 5 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 6 | "properties": { 7 | "material": { 8 | "allOf": [ { "$ref": "glTFid.schema.json" } ], 9 | "description": "target material" 10 | }, 11 | "scale": { 12 | "type": "array", 13 | "description": "uv scaling for TEXCOORD_0", 14 | "items": { 15 | "type": "number" 16 | }, 17 | "minItems": 2, 18 | "maxItems": 2, 19 | "default": [ 20 | 1, 21 | 1 22 | ] 23 | }, 24 | "offset": { 25 | "type": "array", 26 | "description": "uv offset for TEXCOORD_0", 27 | "items": { 28 | "type": "number" 29 | }, 30 | "minItems": 2, 31 | "maxItems": 2, 32 | "default": [ 33 | 0, 34 | 0 35 | ] 36 | }, 37 | "extensions": { }, 38 | "extras": { } 39 | }, 40 | "required": [ 41 | "material" 42 | ] 43 | } -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/schema/VRMC_vrm.expressions.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Expressions", 3 | "type": "object", 4 | "description": "Definition of expressions", 5 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 6 | "properties": { 7 | "preset": { 8 | "type": "object", 9 | "description": "Preset expressions", 10 | "properties": { 11 | "happy": { 12 | "$ref": "VRMC_vrm.expressions.expression.schema.json" 13 | }, 14 | "angry": { 15 | "$ref": "VRMC_vrm.expressions.expression.schema.json" 16 | }, 17 | "sad": { 18 | "$ref": "VRMC_vrm.expressions.expression.schema.json" 19 | }, 20 | "relaxed": { 21 | "$ref": "VRMC_vrm.expressions.expression.schema.json" 22 | }, 23 | "surprised": { 24 | "$ref": "VRMC_vrm.expressions.expression.schema.json" 25 | }, 26 | "aa": { 27 | "$ref": "VRMC_vrm.expressions.expression.schema.json" 28 | }, 29 | "ih": { 30 | "$ref": "VRMC_vrm.expressions.expression.schema.json" 31 | }, 32 | "ou": { 33 | "$ref": "VRMC_vrm.expressions.expression.schema.json" 34 | }, 35 | "ee": { 36 | "$ref": "VRMC_vrm.expressions.expression.schema.json" 37 | }, 38 | "oh": { 39 | "$ref": "VRMC_vrm.expressions.expression.schema.json" 40 | }, 41 | "blink": { 42 | "$ref": "VRMC_vrm.expressions.expression.schema.json" 43 | }, 44 | "blinkLeft": { 45 | "$ref": "VRMC_vrm.expressions.expression.schema.json" 46 | }, 47 | "blinkRight": { 48 | "$ref": "VRMC_vrm.expressions.expression.schema.json" 49 | }, 50 | "lookUp": { 51 | "$ref": "VRMC_vrm.expressions.expression.schema.json" 52 | }, 53 | "lookDown": { 54 | "$ref": "VRMC_vrm.expressions.expression.schema.json" 55 | }, 56 | "lookLeft": { 57 | "$ref": "VRMC_vrm.expressions.expression.schema.json" 58 | }, 59 | "lookRight": { 60 | "$ref": "VRMC_vrm.expressions.expression.schema.json" 61 | }, 62 | "neutral": { 63 | "$ref": "VRMC_vrm.expressions.expression.schema.json" 64 | } 65 | } 66 | }, 67 | "custom": { 68 | "type": "object", 69 | "description": "Custom expressions", 70 | "additionalProperties": { 71 | "$ref": "VRMC_vrm.expressions.expression.schema.json" 72 | } 73 | }, 74 | "extensions": { }, 75 | "extras": { } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/schema/VRMC_vrm.firstPerson.meshAnnotation.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "MeshAnnotation", 3 | "type": "object", 4 | "description": "Specify how the mesh should be interpreted by the camera", 5 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 6 | "properties": { 7 | "node": { 8 | "allOf": [{ "$ref": "glTFid.schema.json" }], 9 | "description": "The index of the node that attached to target mesh." 10 | }, 11 | "type": { 12 | "title": "FirstPersonType", 13 | "type": "string", 14 | "enum": ["auto", "both", "thirdPersonOnly", "firstPersonOnly"], 15 | "description": "How the camera interprets the mesh." 16 | }, 17 | "extensions": { }, 18 | "extras": { } 19 | }, 20 | "required": [ 21 | "node", 22 | "type" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/schema/VRMC_vrm.firstPerson.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "FirstPerson", 3 | "type": "object", 4 | "description": "First-person perspective settings", 5 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 6 | "properties": { 7 | "meshAnnotations": { 8 | "type": "array", 9 | "description": "Mesh rendering annotation for cameras.", 10 | "items": { 11 | "$ref": "VRMC_vrm.firstPerson.meshAnnotation.schema.json" 12 | }, 13 | "minItems": 1 14 | }, 15 | "extensions": { }, 16 | "extras": { } 17 | } 18 | } -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/schema/VRMC_vrm.humanoid.humanBones.humanBone.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "HumanBone", 3 | "type": "object", 4 | "description": "Represents a single bone of a Humanoid.", 5 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 6 | "properties": { 7 | "node": { 8 | "allOf": [{ "$ref": "glTFid.schema.json" }], 9 | "description": "Represents a single glTF node tied to this humanBone." 10 | }, 11 | "extensions": { }, 12 | "extras": { } 13 | }, 14 | "required": [ "node" ] 15 | } 16 | -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/schema/VRMC_vrm.humanoid.humanBones.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "HumanBones", 3 | "type": "object", 4 | "description": "Represents a set of humanBones of a humanoid.", 5 | "properties": { 6 | "hips": { 7 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 8 | }, 9 | "spine": { 10 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 11 | }, 12 | "chest": { 13 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 14 | }, 15 | "upperChest": { 16 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 17 | }, 18 | "neck": { 19 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 20 | }, 21 | "head": { 22 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 23 | }, 24 | "leftEye": { 25 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 26 | }, 27 | "rightEye": { 28 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 29 | }, 30 | "jaw": { 31 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 32 | }, 33 | "leftUpperLeg": { 34 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 35 | }, 36 | "leftLowerLeg": { 37 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 38 | }, 39 | "leftFoot": { 40 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 41 | }, 42 | "leftToes": { 43 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 44 | }, 45 | "rightUpperLeg": { 46 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 47 | }, 48 | "rightLowerLeg": { 49 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 50 | }, 51 | "rightFoot": { 52 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 53 | }, 54 | "rightToes": { 55 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 56 | }, 57 | "leftShoulder": { 58 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 59 | }, 60 | "leftUpperArm": { 61 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 62 | }, 63 | "leftLowerArm": { 64 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 65 | }, 66 | "leftHand": { 67 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 68 | }, 69 | "rightShoulder": { 70 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 71 | }, 72 | "rightUpperArm": { 73 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 74 | }, 75 | "rightLowerArm": { 76 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 77 | }, 78 | "rightHand": { 79 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 80 | }, 81 | "leftThumbMetacarpal": { 82 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 83 | }, 84 | "leftThumbProximal": { 85 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 86 | }, 87 | "leftThumbDistal": { 88 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 89 | }, 90 | "leftIndexProximal": { 91 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 92 | }, 93 | "leftIndexIntermediate": { 94 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 95 | }, 96 | "leftIndexDistal": { 97 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 98 | }, 99 | "leftMiddleProximal": { 100 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 101 | }, 102 | "leftMiddleIntermediate": { 103 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 104 | }, 105 | "leftMiddleDistal": { 106 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 107 | }, 108 | "leftRingProximal": { 109 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 110 | }, 111 | "leftRingIntermediate": { 112 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 113 | }, 114 | "leftRingDistal": { 115 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 116 | }, 117 | "leftLittleProximal": { 118 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 119 | }, 120 | "leftLittleIntermediate": { 121 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 122 | }, 123 | "leftLittleDistal": { 124 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 125 | }, 126 | "rightThumbMetacarpal": { 127 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 128 | }, 129 | "rightThumbProximal": { 130 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 131 | }, 132 | "rightThumbDistal": { 133 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 134 | }, 135 | "rightIndexProximal": { 136 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 137 | }, 138 | "rightIndexIntermediate": { 139 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 140 | }, 141 | "rightIndexDistal": { 142 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 143 | }, 144 | "rightMiddleProximal": { 145 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 146 | }, 147 | "rightMiddleIntermediate": { 148 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 149 | }, 150 | "rightMiddleDistal": { 151 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 152 | }, 153 | "rightRingProximal": { 154 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 155 | }, 156 | "rightRingIntermediate": { 157 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 158 | }, 159 | "rightRingDistal": { 160 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 161 | }, 162 | "rightLittleProximal": { 163 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 164 | }, 165 | "rightLittleIntermediate": { 166 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 167 | }, 168 | "rightLittleDistal": { 169 | "$ref": "VRMC_vrm.humanoid.humanBones.humanBone.schema.json" 170 | } 171 | }, 172 | "required": [ "hips", "spine", "head", "leftUpperLeg", "leftLowerLeg", "leftFoot", "rightUpperLeg", "rightLowerLeg", "rightFoot", "leftUpperArm", "leftLowerArm", "leftHand", "rightUpperArm", "rightLowerArm", "rightHand" ] 173 | } 174 | -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/schema/VRMC_vrm.humanoid.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Humanoid", 3 | "type": "object", 4 | "description": "Correspondence between nodes and human bones", 5 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 6 | "properties": { 7 | "humanBones": { 8 | "$ref": "VRMC_vrm.humanoid.humanBones.schema.json" 9 | }, 10 | "extensions": { }, 11 | "extras": { } 12 | }, 13 | "required": [ "humanBones" ] 14 | } 15 | -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/schema/VRMC_vrm.lookAt.rangeMap.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "LookAtRangeMap", 3 | "type": "object", 4 | "description": "Horizontal inward movement. The left eye moves right. The right eye moves left.", 5 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 6 | "properties": { 7 | "inputMaxValue": { 8 | "type": "number", 9 | "minimum": 0.0, 10 | "maximum": 180.0, 11 | "description": "Yaw and pitch angles ( degrees ) between the head bone forward vector and the eye gaze LookAt vector" 12 | }, 13 | "outputScale": { 14 | "type": "number", 15 | "description": "Degree for type.bone, Weight for type.expressions" 16 | }, 17 | "extensions": { }, 18 | "extras": { } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/schema/VRMC_vrm.lookAt.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "LookAt", 3 | "type": "object", 4 | "description": "Eye gaze control", 5 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 6 | "properties": { 7 | "offsetFromHeadBone": { 8 | "type": "array", 9 | "description": "The origin of LookAt. Position offset from the head bone", 10 | "items": { 11 | "type": "number" 12 | }, 13 | "minItems": 3, 14 | "maxItems": 3 15 | }, 16 | "type": { 17 | "title": "LookAtType", 18 | "type": "string", 19 | "enum": [ 20 | "bone", 21 | "expression" 22 | ] 23 | }, 24 | "rangeMapHorizontalInner": { 25 | "description": "Horizontal inward movement. The left eye moves right. The right eye moves left.", 26 | "$ref": "VRMC_vrm.lookAt.rangeMap.schema.json" 27 | }, 28 | "rangeMapHorizontalOuter": { 29 | "description": "Horizontal outward movement. The left eye moves left. The right eye moves right.", 30 | "$ref": "VRMC_vrm.lookAt.rangeMap.schema.json" 31 | }, 32 | "rangeMapVerticalDown": { 33 | "description": "Vertical downward movement. Both eyes move upwards", 34 | "$ref": "VRMC_vrm.lookAt.rangeMap.schema.json" 35 | }, 36 | "rangeMapVerticalUp": { 37 | "description": "Vertical upward movement. Both eyes move downwards", 38 | "$ref": "VRMC_vrm.lookAt.rangeMap.schema.json" 39 | }, 40 | "extensions": { }, 41 | "extras": { } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/schema/VRMC_vrm.meta.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Meta", 3 | "type": "object", 4 | "description": "", 5 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 6 | "properties": { 7 | "name": { 8 | "type": "string", 9 | "description": "The name of the model", 10 | "minLength": 1 11 | }, 12 | "version": { 13 | "type": "string", 14 | "description": "The version of the model" 15 | }, 16 | "authors": { 17 | "type": "array", 18 | "description": "Authors of the model", 19 | "items": { 20 | "type": "string", 21 | "minLength": 1 22 | }, 23 | "minItems": 1 24 | }, 25 | "copyrightInformation": { 26 | "type": "string", 27 | "description": "An information that describes the copyright of the model" 28 | }, 29 | "contactInformation": { 30 | "type": "string", 31 | "description": "An information that describes the contact information of the author" 32 | }, 33 | "references": { 34 | "type": "array", 35 | "description": "References / original works of the model", 36 | "items": { 37 | "type": "string" 38 | }, 39 | "minItems": 1 40 | }, 41 | "thirdPartyLicenses": { 42 | "type": "string", 43 | "description": "Third party licenses of the model, if required. You can use line breaks" 44 | }, 45 | "thumbnailImage": { 46 | "allOf": [{ "$ref": "glTFid.schema.json" }], 47 | "description": "The index to the thumbnail image of the model in gltf.images" 48 | }, 49 | "licenseUrl": { 50 | "type": "string", 51 | "description": "A URL towards the license document this model refers to" 52 | }, 53 | "avatarPermission": { 54 | "title": "AvatarPermissionType", 55 | "type": "string", 56 | "enum": [ 57 | "onlyAuthor", 58 | "onlySeparatelyLicensedPerson", 59 | "everyone" 60 | ], 61 | "default": "onlyAuthor", 62 | "description": "A person who can perform as an avatar with this model" 63 | }, 64 | "allowExcessivelyViolentUsage": { 65 | "type": "boolean", 66 | "default": false, 67 | "description": "A flag that permits to use this model in excessively violent contents" 68 | }, 69 | "allowExcessivelySexualUsage": { 70 | "type": "boolean", 71 | "default": false, 72 | "description": "A flag that permits to use this model in excessively sexual contents" 73 | }, 74 | "commercialUsage": { 75 | "title": "CommercialUsageType", 76 | "type": "string", 77 | "enum": [ 78 | "personalNonProfit", 79 | "personalProfit", 80 | "corporation" 81 | ], 82 | "default": "personalNonProfit", 83 | "description": "An option that permits to use this model in commercial products" 84 | }, 85 | "allowPoliticalOrReligiousUsage": { 86 | "type": "boolean", 87 | "default": false, 88 | "description": "A flag that permits to use this model in political or religious contents" 89 | }, 90 | "allowAntisocialOrHateUsage": { 91 | "type": "boolean", 92 | "default": false, 93 | "description": "A flag that permits to use this model in contents contain anti-social activities or hate speeches" 94 | }, 95 | "creditNotation": { 96 | "title": "CreditNotationType", 97 | "type": "string", 98 | "enum": [ 99 | "required", 100 | "unnecessary" 101 | ], 102 | "default": "required", 103 | "description": "An option that forces or abandons to display the credit of this model" 104 | }, 105 | "allowRedistribution": { 106 | "type": "boolean", 107 | "default": false, 108 | "description": "A flag that permits to redistribute this model" 109 | }, 110 | "modification": { 111 | "title": "ModificationType", 112 | "type": "string", 113 | "enum": [ 114 | "prohibited", 115 | "allowModification", 116 | "allowModificationRedistribution" 117 | ], 118 | "default": "prohibited", 119 | "description": "An option that controls the condition to modify this model" 120 | }, 121 | "otherLicenseUrl": { 122 | "type": "string", 123 | "description": "Describe the URL links of other license" 124 | }, 125 | "extensions": { }, 126 | "extras": { } 127 | }, 128 | "required": [ 129 | "name", 130 | "authors", 131 | "licenseUrl" 132 | ] 133 | } -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/schema/VRMC_vrm.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "VRMCVrm", 3 | "type": "object", 4 | "description": "", 5 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 6 | "properties": { 7 | "specVersion": { 8 | "type": "string", 9 | "description": "Specification version of VRMC_vrm" 10 | }, 11 | "meta": { 12 | "title": "Meta", 13 | "type": "object", 14 | "description": "Meta informations of the VRM model", 15 | "$ref": "VRMC_vrm.meta.schema.json" 16 | }, 17 | "humanoid": { 18 | "$ref": "VRMC_vrm.humanoid.schema.json" 19 | }, 20 | "firstPerson": { 21 | "title": "FirstPerson", 22 | "type": "object", 23 | "description": "First-person perspective settings", 24 | "$ref": "VRMC_vrm.firstPerson.schema.json" 25 | }, 26 | "lookAt": { 27 | "title": "LookAt", 28 | "type": "object", 29 | "description": "Eye gaze control", 30 | "$ref": "VRMC_vrm.lookAt.schema.json" 31 | }, 32 | "expressions": { 33 | "$ref": "VRMC_vrm.expressions.schema.json" 34 | }, 35 | "extensions": { }, 36 | "extras": { } 37 | }, 38 | "required": [ 39 | "specVersion", 40 | "meta", 41 | "humanoid" 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/tpose.ja.md: -------------------------------------------------------------------------------- 1 | # VRM T-pose: VRM が定義する姿勢の仕様 2 | 3 | ## 概要 4 | VRM モデルは VRM が定義する姿勢の仕様を満たす必要があります。 5 | この文書ではその VRM が定義する姿勢の仕様を述べ、また「VRM T-pose」と呼称します。 6 | 7 | ## 定義 8 | VRM T-pose は大きく分けて 2 つの基準による定義が存在し、すべて満たす必要があります。 9 | 第一にスキニングされたメッシュに関する見た目を基準として定義します。 10 | 第二にノードのトランスフォームに関する数値を基準として定義します。 11 | 12 | 大まかには、真っすぐに立った気を付けの姿勢から、上腕の骨だけを真横に上げて T の字になった姿勢になります。 13 | 14 | ### スキニングされたメッシュに関する見た目を基準とした定義 15 | VRM モデルの見た目を基準に定義します。 16 | 17 | たとえば VRM モデルに対して、靴底の面の高さ情報を計算できることは重要です。 18 | 靴底の面の高さ情報が計算できれば、VRM モデルはバーチャル空間の地面に対して適切に接地できます。 19 | ここで一般的に、ヒューマノイドボーンのひとつ足ボーンはくるぶしの高さに存在します。 20 | また靴の高さはメッシュの見た目によって変わるものです。 21 | したがって足ボーンから靴底の面の高さ情報を計算することはできません。 22 | 靴底の面の高さ情報は、メッシュの見た目を基準に定義し、計算できるようにする必要があります。 23 | 24 | 定義の中で言及される軸は、指定のない限りすべて、グローバル空間の軸です。 25 | 26 | #### 定義 1.1. 見た目上 +Z 軸方向を向いて、X 軸で左右対称に真っすぐに立っている 27 | VRM モデルの足・胴体・頭・目の見た目は +Z 軸の方向を向いて、X 軸で左右対称に、真っすぐに立つ姿勢であると定義します。 28 | 29 | 真っすぐに立つ姿勢とは、その VRM モデルにとってリラックスしたニュートラルな姿勢です。 30 | X: 0.0 の位置で左右対称で、視線を真正面に向けます。 31 | また横から見て、Z: 0.0 の付近で足元から頭までなるべくまっすぐ並ぶようにします。 32 | 33 | #### 定義 1.2. 見た目上、足は Z 軸と平行に向ける 34 | VRM モデルの足はまっすぐ Z 軸と平行に向け、+Z 軸の方向に足先があると定義します。 35 | 36 | たとえば足がハの字になっていたりしてはいけません。 37 | 38 | #### 定義 1.3. 見た目上、足が接地する高さは Y: 0.0 である 39 | 靴底の面など、VRM モデルが見た目上接地する高さは Y: 0.0 と定義します。 40 | 41 | VRM モデル制作者はモデルの見た目上の接地面を Y: 0.0 に合わせる必要があります。 42 | たとえば hips ボーンの位置を上下に移動して調整することができます。 43 | 44 | VRM モデル利用者はモデルの Y: 0.0 を接地面と見なすことができます。 45 | たとえば foot ボーンからの相対位置を事前に計算し、リアルタイムに接地面を計算することができます。 46 | 47 | #### 定義 1.4. 見た目上、腕は X 軸に沿って伸びていて、地面と平行である 48 | 見た目上、腕は X 軸に沿って伸びていて、地面と平行であると定義します。 49 | 50 | 腕を伸ばすため、真正面から見て T の字となり T-pose と呼ばれることとなります。 51 | 52 | #### 定義 1.5. 見た目上、肩はリラックスして一番下がっている 53 | 肩ボーンが存在する場合、肩の見た目はリラックスして一番下がった状態であると定義します。 54 | 55 | これは肩ボーンが存在しないモデルと存在するモデルで差異のない定義をするためです。 56 | またこの定義により、腕を下げた状態で肩がどういう状態になるべきかを計算しやすくなります。 57 | 58 | 定義 1.4. と合わせると、肩は下がったまま腕は上がるという現実の人間にはできないポーズになりますが、それが定義になります。 59 | 60 | #### 定義 1.6. 見た目上、手は X 軸に沿って伸びていて、地面と平行である 61 | 見た目上、手は X 軸に沿って伸びていて、地面と平行であると定義します。 62 | 63 | また手のひらの面は -Y 軸の方向を向きます。 64 | 65 | #### 定義 1.7. 見た目上、4 本の指は X 軸に沿って伸びていて、地面と平行である 66 | 見た目上、人差し指・中指・薬指・小指の 4 本の指は X 軸に沿って伸びていて、地面と平行であると定義します。 67 | 68 | また爪の面は +Y 軸の方向を向きます。 69 | 70 | #### 定義 1.8. 見た目上、親指は X 軸と +Z 軸の中間の方向に伸びていて、地面と平行であると定義します。 71 | 見た目上、親指は地面と平行に、X 軸と +Z 軸の中間 45 度の方向に真っすぐ伸びていると定義します。 72 | 73 | また爪の面は他の 4 本の指とは違い 90 度外側にロールした方向を向きます。 74 | 75 | 左手の親指は +X 軸と +Z 軸の中間の方向に伸びていて、爪の面は -X 軸と +Z 軸の中間を向いています。 76 | 右手の親指は -X 軸と +Z 軸の中間の方向に伸びていて、爪の面は +X 軸と +Z 軸の中間を向いています。 77 | 78 | ### ノードのトランスフォームに関する数値を基準とした定義 79 | スキニングされたメッシュに関する見た目を基準とした定義だけでは、ボーンの取りうる姿勢の自由度が高すぎます。 80 | 不必要に自由度が高いと、実装の複雑性が上がってしまいます。 81 | したがってノードのトランスフォームに関する数値を基準とした定義を加えます。 82 | 83 | #### 定義 2.1. すべてのノードのトランスフォームは、正のユニフォームスケールである 84 | すべてのノードのトランスフォームは、正のユニフォームスケールであると定義します。 85 | 正のユニフォームスケールとは、スケールの各値が 0 ではない正の値の同じ値であると定義します。 86 | -------------------------------------------------------------------------------- /specification/VRMC_vrm-1.0/tpose.md: -------------------------------------------------------------------------------- 1 | # VRM T-pose: The specification of the rest pose in VRM 2 | 3 | ## Overview 4 | VRM models must follow the specification of the rest pose in VRM. 5 | This document describes the spec of the pose, and we call it "VRM T-pose". 6 | 7 | ## Definition 8 | The VRM T-pose has two main criteria, all of which must be met. 9 | First, it defines the criteria for the appearance of skinned meshes. 10 | Second, it defines the criteria of the numerical values of node transforms. 11 | 12 | Basically, the pose goes from a straight standing posture to a T-shaped pose which raises only the upper arm bones directly to the side. 13 | 14 | ### Definition based on the appearance of skinned meshes 15 | This section defines the VRM T-pose by the appearance of the VRM model. 16 | 17 | For example, it is important to be able to calculate the height of the sole surface for a VRM model. 18 | If it can be correctly calculated, the VRM model can be properly grounded in virtual space. 19 | Typically, the Foot bone of a humanoid model is located at the ankle. 20 | Or, the height of the sole depends on the appearance of the mesh. 21 | Therefore, it is impossible to calculate the height of the sole surface by simply seeing the bone transform. 22 | The height information of the sole surface must be defined based on the appearance of the mesh. 23 | 24 | All axes mentioned in the following definitions are in global space unless specified otherwise. 25 | 26 | #### Definition 1.1. Standing straight toward the +Z axis, symmetrical on the X axis in appearance 27 | The legs, torso, head, and eyes of a VRM model must be oriented along the +Z axis, symmetrical on the X axis, and standing straight. 28 | 29 | "Standing straight" means a relaxed, and neutral posture for the VRM model. 30 | It is symmetrical at X: 0.0, gazing straight ahead. 31 | Seeing from the side, It should be as straight as possible from feet to head near Z: 0.0. 32 | 33 | #### Definition 1.2. Feet parallel to the Z axis in appearance 34 | The feet of a VRM model must be pointing straight and parallel to the Z axis. 35 | The toes must be directed along the +Z axis. 36 | 37 | For example, the feet must not be V-shaped. 38 | 39 | #### Definition 1.3. The foot is grounded at Y: 0.0 in appearance 40 | The height at which the VRM model is grounded, such as sole surfaces, is defined as Y: 0.0. 41 | 42 | VRM models must be grounded on the plane at Y: 0.0 in appearance. 43 | For example, it can be achieved by adjusting the transform of the Hips bone up and down. 44 | 45 | Users of a VRM model can consider the model's Y: 0.0 as the ground plane. 46 | For example, the relative position of the ground plane from the foot bone can be pre-calculated to calculate the ground plane in realtime. 47 | 48 | #### Definition 1.4. The arms are extended along the X axis and are parallel to the ground in appearance 49 | The arms must be extended in parallel to the X axis, which is also parallel to the ground. 50 | 51 | Because the arms are extended horizontally, it forms the T letter by seeing from the front, and is referred to as a T-pose. 52 | 53 | #### Definition 1.5. Shoulders are relaxed and lowest in appearance 54 | If shoulder bones are present, the shoulders must be relaxed and lowermost in appearance. 55 | 56 | This is to ensure that there is no difference between models without shoulder bones and with shoulder bones. 57 | This also makes it easier to calculate how the shoulders look when the arms are down. 58 | 59 | Combining with the Definition 1.4, this would result in a pose where the shoulders are lowered and the arms are raised, which is not possible for a real person, but it is the definition. 60 | 61 | #### Definition 1.6. The hands are extended along the X axis and are parallel to the ground in appearance 62 | The hands must be extended in parallel to the X axis, which is also parallel to the ground. 63 | 64 | The palm plane must toward the -Y axis. 65 | 66 | #### Definition 1.7. The four fingers are extended along the X axis and are parallel to the ground in appearance 67 | The four fingers, index, middle, ring, and little, of each hand must be in parallel to the X axis, which is also parallel to the ground. 68 | 69 | The nail surface must toward the +Y axis. 70 | 71 | #### Definition 1.8. The thumb of each hand is extended between the X axis and +Z axis and is parallel to the ground in appearance 72 | The thumb of each hand must be in parallel to the sum of X axis and +Z axis, which is 45 degrees from each axes, and it is also parallel to the ground. 73 | 74 | The nail surface of the thumb is oriented with a 90 degrees outward roll, unlike the other four fingers. 75 | 76 | The thumb of the left hand is directed between the +X axis and +Z axis, and the nail faces between the -X axis and the +Z axis. 77 | The thumb of the right hand is directed between the -X axis and +Z axis, and the nail faces between the +X axis and the +Z axis. 78 | 79 | ### Definition based on numerical values of node transforms 80 | A definition based solely on the appearance of the skinned mesh provides too many degrees of freedom in the possible postures of the bones. 81 | Unnecessarily high degrees of freedom of models increase the complexity of implementation. 82 | Therefore, we add a numerical-based definition for node transforms. 83 | 84 | #### Definition 2.1. All node transforms are on a positive uniform scale 85 | All node transforms must be in a positive uniform scale. 86 | A positive uniform scale means that each value of the scale is the same non-zero positive value. 87 | -------------------------------------------------------------------------------- /specification/VRMC_vrm_animation-1.0/how_to_transform_human_pose.ja.md: -------------------------------------------------------------------------------- 1 | # ポーズデータの互換性について 2 | 3 | > 本ドキュメントは Non-normative です。 4 | 5 | `VRMC_vrm_animation` では、人型モデル (Humanoid) のポーズデータを扱います。 6 | このときに、異なる T-pose を持ったモデル間でのポーズデータの互換性の問題が発生する場合があります。 7 | 本ドキュメントでは、異なる T-pose を持ったモデル間でのポーズデータの互換性を解決する方法を説明します。 8 | 9 | ## 用語の導入 10 | 11 | ### Humanoid 12 | 本ドキュメントで扱う *Humanoid* は、VRM の Humanoid 定義に依存します。 13 | [VRM 仕様内の Humanoid の定義](https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_vrm-1.0/humanoid.ja.md)を参照してください。 14 | 15 | ### T-pose 16 | 本ドキュメントで扱う *T-pose* は、VRM の T-pose に依存します。 17 | [VRM T-pose: VRM が定義する姿勢の仕様](https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_vrm-1.0/tpose.ja.md)を参照してください。 18 | 19 | ### レスト回転 20 | VRM-1.0の定義する T-pose 状態での node の回転状態を **レスト回転** と呼称します。 21 | 22 | VRM-0.X では、レスト回転が無回転であることを仕様化することでポーズデータの互換性の問題が発生しないようにしていました。 23 | VRM-1.0 ではこのレスト回転の制約を撤廃しています。 24 | 25 | ### 非必須ボーン 26 | VRM で定義された Humanoid ボーンのうち、必須でない **非必須ボーン** は、モデル間で存在の有無が異なる場合があります。 27 | 28 | 例えば、 `hips` や `head` などのボーンは必須ボーンであるのに対して、 `upperChest` や `leftShoulder` などは非必須ボーンです。 29 | このため、`upperChest` ボーンがあるモデルとないモデルの両方が存在します。 30 | 31 | ### 同じ姿勢 32 | 各 `HumanBone` が見た目に同じ向きであるときに **同じ姿勢** であるとします。 33 | T-pose 時に少し斜めになっているなどの微妙な差異は含まれるため、完全に同じ姿勢にはなりません。 34 | 35 | ### ポーズデータ 36 | **ポーズデータ** は、`hips` ボーンの平行移動値とすべての Humanoid ボーンのローカル回転で表現されます。 37 | 38 | レスト回転の影響を受けて、同じ姿勢に対する数値が変化します。 39 | また、非必須ボーンの有無の影響を受けて、同じ姿勢に対する数値が変化します。 40 | 41 | **T-poseのレスト回転もしくは非必須ボーンの有無が違う場合、同じ姿勢に対するポーズデータは互換性がありません。** 42 | 43 | ## ポーズデータの互換性を持たせる変換処理 44 | 45 | 異なる T-pose を持ったモデル間でポーズデータの互換性を持たせるため、以下いずれかの変換処理が必要です。 46 | 47 | ### モデルを変換する 48 | モデルのレスト回転を無回転に変換します。 49 | 50 | VRM-0.X の UniVRM においては、モデルのエクスポート時にモデルのレスト回転を無回転にして出力していました。 51 | 52 | ### ポーズデータを変換する 53 | ポーズデータを、任意のレスト回転を持ったモデルに対して適用できるように変換します。 54 | 55 | VRM-1.0 においては、モデルが任意のレスト回転を持っているため、こちらの方法が想定されます。 56 | 57 | VRM-1.0 の UniVRM においては、ランタイムでポーズデータの変換が行えるよう、 ControlRig という機能が提供されています。 58 | 59 | ## 変換処理の詳細 60 | 61 | - `TPoseA`: モデルAのレスト回転 62 | - `PoseForA`: モデルAに適用したときに意図した見た目となるポーズデータ 63 | - `TPoseB`: モデルBのレスト回転 64 | 65 | があるときに、`PoseForB`: モデルBに適用したときに `PoseForA` と同じ姿勢となるポーズデータ を得る方法を説明します。 66 | 67 | ### 中間形式 NormalizedLocalRotation 68 | 69 | ここで処理を単純化するために、中間形式 `NormalizedLocalRotation` を導入します。 70 | 71 | `PoseForA` => `NormalizedLocalRotation` => `PoseForB` 72 | 73 | `NormalizedLocalRotation` は、レスト回転が無回転のモデルに対して適用したとき、 `PoseForA` と同じ姿勢となるポーズデータとします。 74 | 75 | > VRM-0.X の正規化状態とほぼ同じです。 VRM-1.0 で T-pose の定義を明確化したので、同一とは言い切れません。 76 | > 77 | > `TPoseA` が無回転の場合は `PoseForA` と`NormalizedLocalRotation` が等しくなり簡単になります。 78 | > 同様に、 `TPoseB` が無回転の場合は `NormalizedLocalRotation` と `PoseForB` が等しくなり簡単になります。 79 | 80 | ### `PoseForA` => `NormalizedLocalRotation` 81 | 82 | - W: TPoseA の World レスト回転 83 | - L: TPoseA の Local レスト回転 84 | 85 | $NormalizedLocalRotation = W \cdot L^{-1} \cdot A.LocalRotation \cdot W^{-1}$ 86 | 87 | ```cs 88 | // C# 89 | InitialGlobalRotation * Quaternion.Inverse(InitialLocalRotation) * Transform.localRotation * Quaternion.Inverse(InitialGlobalRotation); 90 | ``` 91 | 92 | ### `NormalizedLocalRotation` => `PoseForB` 93 | 94 | - W: TPoseB の World レスト回転 95 | - L: TPoseB の Local レスト回転 96 | 97 | $B.LocalRotation = L \cdot W^{-1} \cdot NormalizedLocalRotation \cdot W$ 98 | 99 | ```cs 100 | // C# 101 | ControlTarget.localRotation = _initialTargetLocalRotation * (Quaternion.Inverse(_initialTargetGlobalRotation) * ControlBone.localRotation * _initialTargetGlobalRotation); 102 | ``` 103 | 104 | ### 非必須ボーンの有無が異なる場合 105 | 変換元のモデル・変換先のモデルの間で、非必須ボーンの有無が異なる場合の変換処理について説明します。 106 | 107 | #### 変換元のモデルのボーンが少ない場合 108 | 変換元のモデルのボーンが少ない場合、単純に変換元のモデルに含まれるボーンのみを適用することが推奨されます。 109 | 110 | #### 変換先のモデルのボーンが少ない場合 111 | 変換先のモデルのボーンが少ない場合、本来対象ボーンの回転によって影響を与えるはずだった子ボーンすべてに対して、対象ボーンの回転を適用することが推奨されます。 112 | 例えば、upperChestが変換元のモデルに存在し変換先のモデルに存在しない場合、変換先のモデルのneck・leftShoulder・rightShoulderには、upperChestの回転とそのボーン自体の回転の両方を乗算して適用することが望ましいです。 113 | すなわち、変換元のアニメーションにおけるボーンごとの見た目の姿勢と、変換先のモデルにおける対応するボーンの見た目の姿勢が同じ向きになることを期待します。 114 | -------------------------------------------------------------------------------- /specification/VRMC_vrm_animation-1.0/how_to_transform_human_pose.md: -------------------------------------------------------------------------------- 1 | # About pose data compatibility 2 | 3 | > This document is non-normative. 4 | 5 | `VRMC_vrm_animation` handles pose data of humanoid models. 6 | There is a pose data compatibility issue between models with different T-poses. 7 | This document explains how to resolve pose data compatibility between models with different T-poses. 8 | 9 | ## Terms 10 | 11 | ### Humanoid 12 | *Humanoid* referred to in this document depends on the VRM Humanoid definition. 13 | 14 | [Humanoid definition within the VRM specification](https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_vrm-1.0/humanoid.ja.md) 15 | 16 | ### T-pose 17 | *T-pose* referred to in this document depends on T-pose of VRM. 18 | [VRM T-pose: Specification of posture defined by VRM](https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_vrm-1.0/tpose.ja.md) 19 | 20 | ### rest rotation 21 | The rotation state of node in T-pose state defined by VRM-1.0 is **Rest rotation**. 22 | 23 | VRM-0.X made pose data compatible by forcing rest rotations to be no rotations. 24 | VRM-1.0 eliminates this no-rotation restriction on rest rotation. 25 | 26 | ### Non-required bone 27 | **Non-required bones** in VRM may have different presence or absence between models. 28 | 29 | For example, bones such as `hips` and `head` are required bones, whereas bones such as `upperChest` and `leftShoulder` are non-required bones. 30 | Therefore, there are models with and without the `upperChest` bone. 31 | 32 | ### same posture 33 | Suppose each `HumanBone` has the **same pose** when it is visually oriented the same way. 34 | Subtle differences, such as being slightly slanted during T-pose, are considered as the same posture so that it won't be in exactly the same posture. 35 | 36 | ### pose data 37 | **Pose data** is represented by translation values of the `hips` bone and local rotations of all Humanoid bones. 38 | 39 | The values for the same posture will change under the influence of rest rotation. 40 | Also, the values for the same posture will change depending on the presence or absence of non-required bones. 41 | 42 | **If the rest rotation of T-pose or the presence or absence of non-essential bones are different, pose data for the same pose cannot be used as-is.** 43 | 44 | ## Conversion processing to make pose data compatible 45 | 46 | In order to make pose data compatible between models with different T-poses, one of the following conversion processes is required. 47 | 48 | ### Convert the model 49 | Converts the rest rotation of the model to no rotation. 50 | 51 | In VRM-0.X (UniVRM), the rest rotation of the model was converted to no rotation when exporting the model. 52 | 53 | ### Convert pose data 54 | Convert pose data to fit a model with arbitrary rest rotation. 55 | 56 | In VRM-1.0, this method is assumed because the model has arbitrary rest rotation. 57 | 58 | VRM-1.0 (UniVRM) provides a function called **ControlRig** that allows pose data conversion at runtime. 59 | 60 | ## Conversion process details 61 | 62 | - `TPoseA`: Model A rest rotation 63 | - `PoseForA`: Pose data that gives the intended look when applied to model A 64 | - `TPoseB`: Model B rest rotation 65 | 66 | Given the above, we will explain how to obtain pose data `PoseForB` that looks the same as `PoseForA` when applied to Model B. 67 | 68 | ### intermediate format: NormalizedLocalRotation 69 | 70 | To simplify processing here, we introduce an intermediate format: `NormalizedLocalRotation`. 71 | 72 | `PoseForA` => `NormalizedLocalRotation` => `PoseForB` 73 | 74 | `NormalizedLocalRotation` is pose data that looks the same as `PoseForA` when applied to a model with no rest rotation. 75 | 76 | > The intermediate format is almost the same as the normalized state of VRM-0.X. The definition of T-pose was clarified in VRM-1.0, so it cannot be said that they are completely the same. 77 | > 78 | > If `TPoseA` has no rotation, `PoseForA` and `NormalizedLocalRotation` will be equal, making it easier. 79 | > Similarly, if `TPoseB` has no rotation, `NormalizedLocalRotation` and `PoseForB` will be equal, making it easier. 80 | 81 | ### `PoseForA` => `NormalizedLocalRotation` 82 | 83 | - W: World rest rotation of TPoseA 84 | - L: Local rest rotation of TPoseA 85 | 86 | $NormalizedLocalRotation = W \cdot L^{-1} \cdot A.LocalRotation \cdot W^{-1}$ 87 | 88 | ```cs 89 | // C# 90 | InitialGlobalRotation * Quaternion.Inverse(InitialLocalRotation) * Transform.localRotation * Quaternion.Inverse(InitialGlobalRotation); 91 | ``` 92 | 93 | ### `NormalizedLocalRotation` => `PoseForB` 94 | 95 | - W: World rest rotation of TPoseB 96 | - L: Local rest rotation of TPoseB 97 | 98 | $B.LocalRotation = L \cdot W^{-1} \cdot NormalizedLocalRotation \cdot W$ 99 | 100 | ```cs 101 | // C# 102 | ControlTarget.localRotation = _initialTargetLocalRotation * (Quaternion.Inverse(_initialTargetGlobalRotation) * ControlBone.localRotation * _initialTargetGlobalRotation); 103 | ``` 104 | 105 | ### When the presence or absence of non-required bones differs 106 | This section explains the conversion process when the presence or absence of non-required bones differs between the conversion source model and conversion destination model. 107 | 108 | #### When the source model has few bones 109 | If the source model has few bones, it is recommended to simply apply only the bones contained in the source model. 110 | 111 | #### When the target model has few bones 112 | If the destination model has few bones, it is recommended to apply the rotation of the target bone to all child bones that would otherwise be affected by the rotation of the target bone. 113 | For example, if upperChest exists in the source model but not in the destination model, the neck, leftShoulder, and rightShoulder of the destination model should be transformed by both the rotation of upperChest and the rotation of the bone itself by multiplying the two. 114 | In other words, we expect the visual posture of each bone in the source animation to be in the same orientation as the corresponding bone in the destination model. 115 | 116 | -------------------------------------------------------------------------------- /specification/VRMC_vrm_animation-1.0/schema/VRMC_vrm_animation.expressions.expression.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema", 3 | "title": "Expression", 4 | "type": "object", 5 | "description": "Represents a single expression.", 6 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 7 | "properties": { 8 | "node": { 9 | "allOf": [{ "$ref": "glTFid.schema.json" }], 10 | "description": "Represents a single glTF node mapped to this expression." 11 | }, 12 | "extensions": { }, 13 | "extras": { } 14 | }, 15 | "required": [ "node" ] 16 | } 17 | -------------------------------------------------------------------------------- /specification/VRMC_vrm_animation-1.0/schema/VRMC_vrm_animation.expressions.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema", 3 | "title": "Expressions", 4 | "type": "object", 5 | "description": "An object which maps expressions to nodes.", 6 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 7 | "properties": { 8 | "preset": { 9 | "type": "object", 10 | "description": "An object that contains definitions of preset expressions.", 11 | "properties": { 12 | "happy": { 13 | "$ref": "VRMC_vrm_animation.expressions.expression.schema.json" 14 | }, 15 | "angry": { 16 | "$ref": "VRMC_vrm_animation.expressions.expression.schema.json" 17 | }, 18 | "sad": { 19 | "$ref": "VRMC_vrm_animation.expressions.expression.schema.json" 20 | }, 21 | "relaxed": { 22 | "$ref": "VRMC_vrm_animation.expressions.expression.schema.json" 23 | }, 24 | "surprised": { 25 | "$ref": "VRMC_vrm_animation.expressions.expression.schema.json" 26 | }, 27 | "aa": { 28 | "$ref": "VRMC_vrm_animation.expressions.expression.schema.json" 29 | }, 30 | "ih": { 31 | "$ref": "VRMC_vrm_animation.expressions.expression.schema.json" 32 | }, 33 | "ou": { 34 | "$ref": "VRMC_vrm_animation.expressions.expression.schema.json" 35 | }, 36 | "ee": { 37 | "$ref": "VRMC_vrm_animation.expressions.expression.schema.json" 38 | }, 39 | "oh": { 40 | "$ref": "VRMC_vrm_animation.expressions.expression.schema.json" 41 | }, 42 | "blink": { 43 | "$ref": "VRMC_vrm_animation.expressions.expression.schema.json" 44 | }, 45 | "blinkLeft": { 46 | "$ref": "VRMC_vrm_animation.expressions.expression.schema.json" 47 | }, 48 | "blinkRight": { 49 | "$ref": "VRMC_vrm_animation.expressions.expression.schema.json" 50 | }, 51 | "neutral": { 52 | "$ref": "VRMC_vrm_animation.expressions.expression.schema.json" 53 | } 54 | } 55 | }, 56 | "custom": { 57 | "type": "object", 58 | "description": "An object that contains definitions of custom expressions.", 59 | "additionalProperties": { 60 | "$ref": "VRMC_vrm_animation.expressions.expression.schema.json" 61 | } 62 | }, 63 | "extensions": { }, 64 | "extras": { } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /specification/VRMC_vrm_animation-1.0/schema/VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema", 3 | "title": "HumanBone", 4 | "type": "object", 5 | "description": "Represents a single bone of a Humanoid.", 6 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 7 | "properties": { 8 | "node": { 9 | "allOf": [{ "$ref": "glTFid.schema.json" }], 10 | "description": "Represents a single glTF node mapped to this humanBone." 11 | }, 12 | "extensions": { }, 13 | "extras": { } 14 | }, 15 | "required": [ "node" ] 16 | } 17 | -------------------------------------------------------------------------------- /specification/VRMC_vrm_animation-1.0/schema/VRMC_vrm_animation.humanoid.humanBones.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema", 3 | "title": "HumanBones", 4 | "type": "object", 5 | "description": "An object which maps humanoid bones to nodes.", 6 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 7 | "properties": { 8 | "hips": { 9 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 10 | }, 11 | "spine": { 12 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 13 | }, 14 | "chest": { 15 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 16 | }, 17 | "upperChest": { 18 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 19 | }, 20 | "neck": { 21 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 22 | }, 23 | "head": { 24 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 25 | }, 26 | "jaw": { 27 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 28 | }, 29 | "leftUpperLeg": { 30 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 31 | }, 32 | "leftLowerLeg": { 33 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 34 | }, 35 | "leftFoot": { 36 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 37 | }, 38 | "leftToes": { 39 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 40 | }, 41 | "rightUpperLeg": { 42 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 43 | }, 44 | "rightLowerLeg": { 45 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 46 | }, 47 | "rightFoot": { 48 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 49 | }, 50 | "rightToes": { 51 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 52 | }, 53 | "leftShoulder": { 54 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 55 | }, 56 | "leftUpperArm": { 57 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 58 | }, 59 | "leftLowerArm": { 60 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 61 | }, 62 | "leftHand": { 63 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 64 | }, 65 | "rightShoulder": { 66 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 67 | }, 68 | "rightUpperArm": { 69 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 70 | }, 71 | "rightLowerArm": { 72 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 73 | }, 74 | "rightHand": { 75 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 76 | }, 77 | "leftThumbMetacarpal": { 78 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 79 | }, 80 | "leftThumbProximal": { 81 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 82 | }, 83 | "leftThumbDistal": { 84 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 85 | }, 86 | "leftIndexProximal": { 87 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 88 | }, 89 | "leftIndexIntermediate": { 90 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 91 | }, 92 | "leftIndexDistal": { 93 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 94 | }, 95 | "leftMiddleProximal": { 96 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 97 | }, 98 | "leftMiddleIntermediate": { 99 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 100 | }, 101 | "leftMiddleDistal": { 102 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 103 | }, 104 | "leftRingProximal": { 105 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 106 | }, 107 | "leftRingIntermediate": { 108 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 109 | }, 110 | "leftRingDistal": { 111 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 112 | }, 113 | "leftLittleProximal": { 114 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 115 | }, 116 | "leftLittleIntermediate": { 117 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 118 | }, 119 | "leftLittleDistal": { 120 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 121 | }, 122 | "rightThumbMetacarpal": { 123 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 124 | }, 125 | "rightThumbProximal": { 126 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 127 | }, 128 | "rightThumbDistal": { 129 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 130 | }, 131 | "rightIndexProximal": { 132 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 133 | }, 134 | "rightIndexIntermediate": { 135 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 136 | }, 137 | "rightIndexDistal": { 138 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 139 | }, 140 | "rightMiddleProximal": { 141 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 142 | }, 143 | "rightMiddleIntermediate": { 144 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 145 | }, 146 | "rightMiddleDistal": { 147 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 148 | }, 149 | "rightRingProximal": { 150 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 151 | }, 152 | "rightRingIntermediate": { 153 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 154 | }, 155 | "rightRingDistal": { 156 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 157 | }, 158 | "rightLittleProximal": { 159 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 160 | }, 161 | "rightLittleIntermediate": { 162 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 163 | }, 164 | "rightLittleDistal": { 165 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.humanBone.schema.json" 166 | } 167 | }, 168 | "required": [ "hips", "spine", "head", "leftUpperLeg", "leftLowerLeg", "leftFoot", "rightUpperLeg", "rightLowerLeg", "rightFoot", "leftUpperArm", "leftLowerArm", "leftHand", "rightUpperArm", "rightLowerArm", "rightHand" ] 169 | } 170 | -------------------------------------------------------------------------------- /specification/VRMC_vrm_animation-1.0/schema/VRMC_vrm_animation.humanoid.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema", 3 | "title": "Humanoid", 4 | "type": "object", 5 | "description": "An object which describes about humanoid bones.", 6 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 7 | "properties": { 8 | "humanBones": { 9 | "$ref": "VRMC_vrm_animation.humanoid.humanBones.schema.json" 10 | } 11 | }, 12 | "required": [ "humanBones" ] 13 | } 14 | -------------------------------------------------------------------------------- /specification/VRMC_vrm_animation-1.0/schema/VRMC_vrm_animation.lookAt.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema", 3 | "title": "LookAt", 4 | "type": "object", 5 | "description": "An object which maps a eye gaze point to a node.", 6 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 7 | "properties": { 8 | "node": { 9 | "allOf": [{ "$ref": "glTFid.schema.json" }], 10 | "description": "Represents a single glTF node represents the eye gaze point." 11 | }, 12 | "offsetFromHeadBone": { 13 | "type": "array", 14 | "description": "The position offset of the origin of the LookAt from the humanoid head bone", 15 | "items": { 16 | "type": "number" 17 | }, 18 | "minItems": 3, 19 | "maxItems": 3 20 | }, 21 | "extensions": { }, 22 | "extras": { } 23 | }, 24 | "required": [ "node" ] 25 | } 26 | -------------------------------------------------------------------------------- /specification/VRMC_vrm_animation-1.0/schema/VRMC_vrm_animation.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema", 3 | "title": "VRMC_vrm_animation extension", 4 | "type": "object", 5 | "description": "glTF extension that defines humanoid animations.", 6 | "allOf": [ { "$ref": "glTFProperty.schema.json" } ], 7 | "properties": { 8 | "specVersion": { 9 | "type": "string", 10 | "description": "Specification version of VRMC_vrm_animation" 11 | }, 12 | "humanoid": { 13 | "$ref": "VRMC_vrm_animation.humanoid.schema.json" 14 | }, 15 | "expressions": { 16 | "$ref": "VRMC_vrm_animation.expressions.schema.json" 17 | }, 18 | "lookAt": { 19 | "$ref": "VRMC_vrm_animation.lookAt.schema.json" 20 | }, 21 | "extensions": { }, 22 | "extras": { } 23 | }, 24 | "required": [ "specVersion" ] 25 | } 26 | --------------------------------------------------------------------------------