1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
|
# Resource formats
## Common types
- `Matrix3`: 3x3 matrix of `Float` in columns
- `Vec3`: 3 component `Float` vector
- `Affine3`: `Matrix3` and `Vec3` translation
- `Res`: 256-bit resource id
- `[T; N]`: Type `T` repeated `N`-times.
- `[T]`: Type `T` repeated until end of data.
## Dictionary format
```
[kkkk vvvv KK... VV...]...
^ ^ ^ ^
| | | | value
| | | key
| | 16-bit kalue length
| 16-bit key length
```
## PrefabIndex
| Key | Value Type |
| -------- | ---------- |
| \<Name\> | `Res` |
## Prefab
| Key | Value Type | |
| ------------- | ------------------------------ | --------- |
| `mesh` | `Affine3`, `Res<MeshPart>` | Multi key |
| `collision` | `Affine3`, `Res<ColliderPart>` | Multi key |
| `light` | `Vec3`, `Res<LightPart>` | Multi key |
| `armature` | `Res<ArmaturePart>` | Multi key |
| `particles` | `Res<ParticlesPart>` | Multi key |
| `animation` | `Res<AnimationPart>` | Multi key |
| `avatar` | `Res<AvatarInfoPart>` | |
| `environment` | `Res<EnvironmentPart>` | |
## MeshPart
Vertex attribute arrays (va_\*) are resources that contain a packed float32
array. ombinations of g_\*, va_\* and tex_\* are multiplied except normal which
is added. Defaults should be the identity for that operation, so default is 1 /
white except normals are zero.
| Key | Value Type | |
| ------------------------ | ------------------- | ------------------ |
| `name` | `String` | |
| `index` | `Res<[u32; 3]>` | |
| `armature` | `u32` | |
| `billboard` | | |
| `g_metallic` | `Float` | |
| `g_roughness` | `Float` | |
| `g_albedo` | `Vec3` | |
| `g_alpha` | `Float` | |
| `g_transmission` | `Float` | |
| `g_emission` | `Vec3` | |
| `g_refractive_index` | `Float` | |
| `g_attenuation` | `Vec3` | |
| `g_dispersion` | `Float` | |
| `g_thickness` | `Float` | |
| `g_unlit` | | |
| `g_double_sided` | | |
| `va_position` | `Res<[Vec3]>` | |
| `va_normal` | `Res<[Vec3]>` | |
| `va_tangent` | `Res<[Vec4]>` | Tangent+Handedness |
| `va_texcoord` | `Res<[Vec2]>` | |
| `va_roughness` | `Res<[Float]>` | |
| `va_metallic` | `Res<[Float]>` | |
| `va_albedo` | `Res<[Vec3]>` | |
| `va_alpha` | `Res<[Float]>` | |
| `va_transmission` | `Res<[Float]>` | |
| `va_emission` | `Res<[Vec3]>` | |
| `va_joint_weight` | `Res<[[Float; 4]]>` | |
| `va_joint_index` | `Res<[[u32; 4]]>` | |
| `tex_normal` | `Res<Texture>` | Use color channels |
| `tex_roughness` | `Res<Texture>` | Use green channel |
| `tex_metallic` | `Res<Texture>` | Use blue channel |
| `tex_albedo` | `Res<Texture>` | Use color channels |
| `tex_alpha` | `Res<Texture>` | Use alpha channel |
| `tex_transmission` | `Res<Texture>` | Use red channel |
| `tex_emission` | `Res<Texture>` | Use color channels |
| `tex_thickness` | `Res<Texture>` | Use green channel |
| `tex_occlusion` | `Res<Texture>` | Use red channel |
| `hint_mirror` | | |
| `hint_hide_first_person` | | |
| `hint_static` | | |
| `hint_volume` | | |
- **Attenuation**: Attenuation coefficient for each color channel due to
scattering within the material volume expressed as e-folding distance (m^-1).
See [KHR_materials_volume].
- **Transmission**: Equivalent to `transmissionFactor` and `transmissionTexture`
of [KHR_materials_transmission].
- **Refractive Index**: Equivalent to `ior` of [KHR_materials_ior]
- **Thickness**: Equivalent to `thicknessFactor` and `thicknessTexture` of
[KHR_materials_volume].
- **Dispersion**: 20 / Abbe Number. Equivalent to `dispersion` of
[KHR_materials_dispersion].
- **Unlit**: Directly transfers \*_albedo to the screen if set. No lighting
shaders are applied. See [KHR_materials_unlit]
- **Double Sided**: Disable backface culling for this mesh. Equivalent to
`material.doubleSided` of glTF 2.0.
- **Mirror Hint**: Suggest a client to render reflections of this surface
properly e.g. show use a texture that shows output of another render pass from
the mirrors perspective. It can be assumed that the mesh is on a single plane.
- **Static Hint**: Object will not move often. This allows implementations to
choose instanced rending when MeshPart are added more than once.
- **Volume Hint**: The material's attenuation is important for the scene and
should be rendered as a volume and not approximated when rendering the
surface.
- **Hide First-Person Hint**: Object should not be rendered if the prefab is the
own avatar and first person view is used. This is set for the head and hair
that should not be visible to yourself. See `thirdPersonOnly` variant of
[VRMC_vrm] `firstPerson.meshAnnotations.firstPersonFlag`.
- **Billboard**: Always draw the mesh rotated to match camera space, i.e.
looking at the mesh from -Z with X pointing sideways right.
## ArmaturePart
Armature is used for humanoid avatar rigging and generally follows VRM
specification. Joints are arranged in a hierarchy where transforms are
inherited. Attribute values are zipped similar to vertex attributes.
| Key | Value Type | |
| ------------------------ | ----------- | -------------------------------------- |
| `parent` | `[u16]` | Parent indecies, Root points to itself |
| `transform` | `[Affine3]` | |
| `inverse_bind_transform` | `[Affine3]` | |
| `name` | `[String]` | Each string prefixed with u16 length |
- **Names**: Indirectly controlled joints have an empty name. All other bones
are named like in [VRMC_vrm].
## LightPart
| Key | Value Type |
| ---------- | ------------------------ |
| `name` | `String` |
| `radius` | `Float` |
| `emission` | `Vec3` |
| `spot` | `Vec3`, `Float`, `Float` |
- **Emission**: Luminous intensity in candela per channel. Equivalent of `color`
multiplied with `intensity` of [KHR_lights_punctual].
- **Radius**: Radius for soft shadow calculation. If set, the light source can
be modelled to be a light emitting sphere of that radius. Not suported by
glTF.
- **Spot**: Normalized direction vector, inner and outer cone radius like
`innerConeAngle` and `outerConeAngle` in [KHR_lights_punctual].
## EnvironmentPart
| Key | Value Type | |
| -------- | -------------- | ------------------------ |
| `skybox` | `Res<Texture>` | OpenEXR support required |
| `sun` | `Vec3`, `Vec3` | Direction, Color |
- **Skybox**: Equirectangular projection is used. TODO: Unit for Luminous
intensity? lm/sr?
- **Sun**: Direction is a normal vector, color is illuminance of each channel in
lux. TODO: sun disk size?
## ParticlesPart
| Key | Value Type | |
| ----------------- | ---------- | -------------------- |
| `sprite` | `MeshPart` | |
| `density` | `Float` | in avr. particles/m³ |
| `lifetime` | `Float` | |
| `lifetime_spread` | `Float` | |
| `velocity` | `Vec3` | |
| `velocity_spread` | `Vec3` | |
- **Spread**: Expressed as the standard deviation from the center/bias value.
## AnimationPart
| Key | Value Type | |
| ---------- | ------------------ | --------- |
| `name` | `String` | |
| `channel` | `AnimationChannel` | Multi key |
| `duration` | `f32` | |
## AnimationChannel
| Key | Value Type | Indexes | `value` components |
| --------------------- | ------------ | ----------- | ------------------ |
| `t_mesh_translation` | `u32` | mesh | 3 |
| `t_mesh_rotation` | `u32` | mesh | 4 |
| `t_mesh_scale` | `u32` | mesh | 3 |
| `t_mesh_morph_weight` | `u32`, `u32` | mesh, morph | 1 |
| `t_joint_translation` | `u32`, `u32` | arma, joint | 3 |
| `t_joint_rotation` | `u32`, `u32` | arma, joint | 4 |
| `t_joint_scale` | `u32`, `u32` | arma, joint | 3 |
| `t_light_translation` | `u32` | mesh | 3 |
| `time` | `Res<[f32]>` | | |
| `value` | `Res<[f32]>` | | |
- **Time & Values**: Time and value arrays contain corresponding elements. Every
point is a keyframe and lineraly interpolated by default.
## AvatarInfoPart
| Key | Value Type | |
| --------------------- | ---------- | -------------- |
| `armature` | `u32` | Armature index |
| `camera_mount` | `u32` | Bone index |
| `camera_mount_offset` | `Vec3` | |
| `a_walk` | `u32` | |
| `a_run` | `u32` | |
| `a_sit` | `u32` | |
## Texture
Currently supporting PNG, JPEG, AVIF, WebP and OpenEXR.
## CollisionPart
Only one key for shape should be set.
| Key | Value Type | |
| ------------------- | ------------------------- | -------------------------- |
| `restitution_coeff` | `Float` | |
| `friction_kinetic` | `Float` | Coeffient |
| `friction_static` | `Float` | Coeffient |
| `sh_box` | `Vec3` | Side lengths |
| `sh_sphere` | `Float` | Radius |
| `sh_cylinder` | `Float`, `Float`, `Float` | Bottom/Top Radius, Height |
| `sh_capsule` | `Float`, `Float`, `Float` | Bottom/Top Radius, Height |
| `sh_convex_hull` | `Res<[Vec3]>` | Convex hull points |
| `sh_mesh` | `Res<u32>`, `Res<[Vec3]>` | Mesh index + vertex buffer |
[KHR_materials_transmission]: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_transmission
[KHR_materials_ior]: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_ior
[KHR_materials_volume]: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_volume
[KHR_materials_dispersion]: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_dispersion
[KHR_lights_punctual]: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_lights_punctual
[KHR_lights_unlit]: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_lights_unlit
[VRMC_vrm]: https://github.com/vrm-c/vrm-specification/tree/master/specification/VRMC_vrm-1.0
[VRMC_springBone]: https://github.com/vrm-c/vrm-specification/tree/master/specification/VRMC_springBone-1.0
|