@zephyr3d/scene 0.9.24 → 0.9.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/dist/animation/hair/gpu_hair_simulation.js +1090 -0
  2. package/dist/animation/hair/gpu_hair_simulation.js.map +1 -0
  3. package/dist/animation/joint_dynamics/controller.js +7 -5
  4. package/dist/animation/joint_dynamics/controller.js.map +1 -1
  5. package/dist/animation/joint_dynamics/joint_dynamics_system.js +81 -5
  6. package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
  7. package/dist/animation/morphtrack.js +3 -4
  8. package/dist/animation/morphtrack.js.map +1 -1
  9. package/dist/animation/skeleton.js +58 -24
  10. package/dist/animation/skeleton.js.map +1 -1
  11. package/dist/animation/spring/multi_chain_spring_system.js +577 -179
  12. package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
  13. package/dist/animation/spring/spring_collider.js +4 -3
  14. package/dist/animation/spring/spring_collider.js.map +1 -1
  15. package/dist/animation/spring/spring_node_pose_tracker.js +40 -0
  16. package/dist/animation/spring/spring_node_pose_tracker.js.map +1 -0
  17. package/dist/animation/spring/spring_particle.js +2 -0
  18. package/dist/animation/spring/spring_particle.js.map +1 -1
  19. package/dist/animation/spring/spring_system.js +11 -3
  20. package/dist/animation/spring/spring_system.js.map +1 -1
  21. package/dist/animation/spring_modifier.js +10 -0
  22. package/dist/animation/spring_modifier.js.map +1 -1
  23. package/dist/app/engine.js +53 -43
  24. package/dist/app/engine.js.map +1 -1
  25. package/dist/app/scriptingsystem.js +119 -6
  26. package/dist/app/scriptingsystem.js.map +1 -1
  27. package/dist/app/scriptregistry.js +3 -2
  28. package/dist/app/scriptregistry.js.map +1 -1
  29. package/dist/asset/assetmanager.js +284 -67
  30. package/dist/asset/assetmanager.js.map +1 -1
  31. package/dist/asset/loaders/zhair/zhair_format.js +288 -0
  32. package/dist/asset/loaders/zhair/zhair_format.js.map +1 -0
  33. package/dist/asset/loaders/zhair/zhair_loader.js +221 -0
  34. package/dist/asset/loaders/zhair/zhair_loader.js.map +1 -0
  35. package/dist/asset/model.js +178 -67
  36. package/dist/asset/model.js.map +1 -1
  37. package/dist/camera/camera.js +193 -21
  38. package/dist/camera/camera.js.map +1 -1
  39. package/dist/camera/perspectivecamera.js +3 -1
  40. package/dist/camera/perspectivecamera.js.map +1 -1
  41. package/dist/index.d.ts +4040 -1290
  42. package/dist/index.js +16 -6
  43. package/dist/index.js.map +1 -1
  44. package/dist/material/eye.js +932 -0
  45. package/dist/material/eye.js.map +1 -0
  46. package/dist/material/hair.js +917 -0
  47. package/dist/material/hair.js.map +1 -0
  48. package/dist/material/hairstrand.js +842 -0
  49. package/dist/material/hairstrand.js.map +1 -0
  50. package/dist/material/hairstrand_data.js +162 -0
  51. package/dist/material/hairstrand_data.js.map +1 -0
  52. package/dist/material/lambert.js +5 -2
  53. package/dist/material/lambert.js.map +1 -1
  54. package/dist/material/material.js +338 -300
  55. package/dist/material/material.js.map +1 -1
  56. package/dist/material/meshmaterial.js +120 -19
  57. package/dist/material/meshmaterial.js.map +1 -1
  58. package/dist/material/mixins/albedocolor.js +1 -1
  59. package/dist/material/mixins/albedocolor.js.map +1 -1
  60. package/dist/material/mixins/lightmodel/blinnphong.js +5 -3
  61. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  62. package/dist/material/mixins/lightmodel/lambert.js +5 -4
  63. package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
  64. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +3 -3
  65. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
  66. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +5 -5
  67. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  68. package/dist/material/mixins/lightmodel/pbrspecularglossness.js +3 -3
  69. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  70. package/dist/material/mixins/lit.js +73 -18
  71. package/dist/material/mixins/lit.js.map +1 -1
  72. package/dist/material/mixins/pbr/common.js +4 -4
  73. package/dist/material/mixins/pbr/common.js.map +1 -1
  74. package/dist/material/mixins/texture.js +48 -11
  75. package/dist/material/mixins/texture.js.map +1 -1
  76. package/dist/material/mtoon.js +6 -5
  77. package/dist/material/mtoon.js.map +1 -1
  78. package/dist/material/pbrblueprint.js +146 -28
  79. package/dist/material/pbrblueprint.js.map +1 -1
  80. package/dist/material/pbrblueprint_instance.js +501 -0
  81. package/dist/material/pbrblueprint_instance.js.map +1 -0
  82. package/dist/material/pbrmr.js +15 -16
  83. package/dist/material/pbrmr.js.map +1 -1
  84. package/dist/material/shader/helper.js +766 -456
  85. package/dist/material/shader/helper.js.map +1 -1
  86. package/dist/material/shader/terrain_blend.js +55 -0
  87. package/dist/material/shader/terrain_blend.js.map +1 -0
  88. package/dist/material/skin.js +192 -32
  89. package/dist/material/skin.js.map +1 -1
  90. package/dist/material/spriteblueprint.js +16 -1
  91. package/dist/material/spriteblueprint.js.map +1 -1
  92. package/dist/material/subsurfaceprofile.js +86 -23
  93. package/dist/material/subsurfaceprofile.js.map +1 -1
  94. package/dist/material/water.js +3 -1
  95. package/dist/material/water.js.map +1 -1
  96. package/dist/posteffect/bloom.js +167 -7
  97. package/dist/posteffect/bloom.js.map +1 -1
  98. package/dist/posteffect/coloradjust.js +2 -1
  99. package/dist/posteffect/coloradjust.js.map +1 -1
  100. package/dist/posteffect/compositor.js.map +1 -1
  101. package/dist/posteffect/fxaa.js +2 -1
  102. package/dist/posteffect/fxaa.js.map +1 -1
  103. package/dist/posteffect/grayscale.js +3 -1
  104. package/dist/posteffect/grayscale.js.map +1 -1
  105. package/dist/posteffect/motionblur.js +4 -1
  106. package/dist/posteffect/motionblur.js.map +1 -1
  107. package/dist/posteffect/posteffect.js.map +1 -1
  108. package/dist/posteffect/skinsss.js +368 -69
  109. package/dist/posteffect/skinsss.js.map +1 -1
  110. package/dist/posteffect/ssgi.js +16 -9
  111. package/dist/posteffect/ssgi.js.map +1 -1
  112. package/dist/posteffect/ssr.js +3 -0
  113. package/dist/posteffect/ssr.js.map +1 -1
  114. package/dist/posteffect/sss.js +91 -34
  115. package/dist/posteffect/sss.js.map +1 -1
  116. package/dist/posteffect/taa.js.map +1 -1
  117. package/dist/posteffect/tonemap.js +44 -1
  118. package/dist/posteffect/tonemap.js.map +1 -1
  119. package/dist/render/abuffer_oit.js +45 -39
  120. package/dist/render/abuffer_oit.js.map +1 -1
  121. package/dist/render/cluster_light.js +4 -4
  122. package/dist/render/cluster_light.js.map +1 -1
  123. package/dist/render/cull_visitor.js +19 -0
  124. package/dist/render/cull_visitor.js.map +1 -1
  125. package/dist/render/depthpass.js +36 -2
  126. package/dist/render/depthpass.js.map +1 -1
  127. package/dist/render/drawable_mixin.js +26 -1
  128. package/dist/render/drawable_mixin.js.map +1 -1
  129. package/dist/render/dualdepthpeeling_oit.js +52 -51
  130. package/dist/render/dualdepthpeeling_oit.js.map +1 -1
  131. package/dist/render/envlight.js +1 -1
  132. package/dist/render/envlight.js.map +1 -1
  133. package/dist/render/fbm_wavegenerator.js +3 -0
  134. package/dist/render/fbm_wavegenerator.js.map +1 -1
  135. package/dist/render/gerstner_wavegenerator.js +3 -0
  136. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  137. package/dist/render/globalbindgroup_allocator.js +3 -0
  138. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  139. package/dist/render/oit.js +29 -0
  140. package/dist/render/oit.js.map +1 -0
  141. package/dist/render/render_queue.js +3 -0
  142. package/dist/render/render_queue.js.map +1 -1
  143. package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
  144. package/dist/render/rendergraph/executor.js +2 -0
  145. package/dist/render/rendergraph/executor.js.map +1 -1
  146. package/dist/render/rendergraph/forward_plus_builder.js +61 -1
  147. package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
  148. package/dist/render/rendergraph/rendergraph.js.map +1 -1
  149. package/dist/render/rendergraph/texture_affinity_cache.js +1 -1
  150. package/dist/render/rendergraph/texture_affinity_cache.js.map +1 -1
  151. package/dist/render/rendergraph/types.js.map +1 -1
  152. package/dist/render/shadow_mask_pass.js +73 -8
  153. package/dist/render/shadow_mask_pass.js.map +1 -1
  154. package/dist/render/sky.js +166 -126
  155. package/dist/render/sky.js.map +1 -1
  156. package/dist/render/weightedblended_oit.js +36 -35
  157. package/dist/render/weightedblended_oit.js.map +1 -1
  158. package/dist/scene/basesprite.js +8 -0
  159. package/dist/scene/basesprite.js.map +1 -1
  160. package/dist/scene/batchgroup.js +3 -0
  161. package/dist/scene/batchgroup.js.map +1 -1
  162. package/dist/scene/environment.js +4 -1
  163. package/dist/scene/environment.js.map +1 -1
  164. package/dist/scene/hair.js +963 -0
  165. package/dist/scene/hair.js.map +1 -0
  166. package/dist/scene/light.js +5 -1
  167. package/dist/scene/light.js.map +1 -1
  168. package/dist/scene/mesh.js +481 -47
  169. package/dist/scene/mesh.js.map +1 -1
  170. package/dist/scene/meshdrawable.js +6 -0
  171. package/dist/scene/meshdrawable.js.map +1 -1
  172. package/dist/scene/msdftext.js +3 -0
  173. package/dist/scene/msdftext.js.map +1 -1
  174. package/dist/scene/msdftextsprite.js +3 -0
  175. package/dist/scene/msdftextsprite.js.map +1 -1
  176. package/dist/scene/particlesys.js +6 -0
  177. package/dist/scene/particlesys.js.map +1 -1
  178. package/dist/scene/scene.js +3 -0
  179. package/dist/scene/scene.js.map +1 -1
  180. package/dist/scene/scene_node.js +6 -1
  181. package/dist/scene/scene_node.js.map +1 -1
  182. package/dist/scene/terrain-cm/grass.js +273 -249
  183. package/dist/scene/terrain-cm/grass.js.map +1 -1
  184. package/dist/scene/terrain-cm/grassmaterial.js +3 -0
  185. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  186. package/dist/scene/terrain-cm/terrain-cm.js +6 -0
  187. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  188. package/dist/scene/terrain-cm/texture_cache.js +309 -0
  189. package/dist/scene/terrain-cm/texture_cache.js.map +1 -0
  190. package/dist/scene/water.js +6 -0
  191. package/dist/scene/water.js.map +1 -1
  192. package/dist/shaders/atmosphere.js.map +1 -1
  193. package/dist/shaders/diffusion.js +54 -0
  194. package/dist/shaders/diffusion.js.map +1 -0
  195. package/dist/shaders/shadow.js +33 -21
  196. package/dist/shaders/shadow.js.map +1 -1
  197. package/dist/shaders/temporal.js +71 -33
  198. package/dist/shaders/temporal.js.map +1 -1
  199. package/dist/shadow/dom.js +546 -0
  200. package/dist/shadow/dom.js.map +1 -0
  201. package/dist/shadow/pcf_opt.js +3 -5
  202. package/dist/shadow/pcf_opt.js.map +1 -1
  203. package/dist/shadow/pcf_pd.js +1 -1
  204. package/dist/shadow/pcf_pd.js.map +1 -1
  205. package/dist/shadow/receiver_bias.js +41 -0
  206. package/dist/shadow/receiver_bias.js.map +1 -0
  207. package/dist/shadow/shader.js +20 -60
  208. package/dist/shadow/shader.js.map +1 -1
  209. package/dist/shadow/shadow_impl.js +89 -0
  210. package/dist/shadow/shadow_impl.js.map +1 -1
  211. package/dist/shadow/shadow_region.js +50 -50
  212. package/dist/shadow/shadow_region.js.map +1 -1
  213. package/dist/shadow/shadowmapper.js +150 -37
  214. package/dist/shadow/shadowmapper.js.map +1 -1
  215. package/dist/shapes/shape.js +11 -2
  216. package/dist/shapes/shape.js.map +1 -1
  217. package/dist/shapes/sphere.js +50 -9
  218. package/dist/shapes/sphere.js.map +1 -1
  219. package/dist/utility/blueprint/common/constants.js +112 -2
  220. package/dist/utility/blueprint/common/constants.js.map +1 -1
  221. package/dist/utility/blueprint/material/func.js +142 -49
  222. package/dist/utility/blueprint/material/func.js.map +1 -1
  223. package/dist/utility/blueprint/material/ir.js +490 -25
  224. package/dist/utility/blueprint/material/ir.js.map +1 -1
  225. package/dist/utility/blueprint/material/texture.js +898 -4
  226. package/dist/utility/blueprint/material/texture.js.map +1 -1
  227. package/dist/utility/serialization/manager.js +431 -100
  228. package/dist/utility/serialization/manager.js.map +1 -1
  229. package/dist/utility/serialization/scene/animation.js +370 -3
  230. package/dist/utility/serialization/scene/animation.js.map +1 -1
  231. package/dist/utility/serialization/scene/batch.js +4 -0
  232. package/dist/utility/serialization/scene/batch.js.map +1 -1
  233. package/dist/utility/serialization/scene/camera.js +133 -1
  234. package/dist/utility/serialization/scene/camera.js.map +1 -1
  235. package/dist/utility/serialization/scene/common.js +26 -5
  236. package/dist/utility/serialization/scene/common.js.map +1 -1
  237. package/dist/utility/serialization/scene/hair.js +1141 -0
  238. package/dist/utility/serialization/scene/hair.js.map +1 -0
  239. package/dist/utility/serialization/scene/light.js +84 -4
  240. package/dist/utility/serialization/scene/light.js.map +1 -1
  241. package/dist/utility/serialization/scene/material.js +1867 -166
  242. package/dist/utility/serialization/scene/material.js.map +1 -1
  243. package/dist/utility/serialization/scene/mesh.js +231 -14
  244. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  245. package/dist/utility/serialization/scene/node.js +141 -7
  246. package/dist/utility/serialization/scene/node.js.map +1 -1
  247. package/dist/utility/serialization/scene/particle.js +4 -0
  248. package/dist/utility/serialization/scene/particle.js.map +1 -1
  249. package/dist/utility/serialization/scene/primitive.js +18 -0
  250. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  251. package/dist/utility/serialization/scene/sprite.js +4 -0
  252. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  253. package/dist/utility/serialization/scene/terrain.js +92 -69
  254. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  255. package/dist/utility/serialization/scene/text.js +4 -0
  256. package/dist/utility/serialization/scene/text.js.map +1 -1
  257. package/dist/utility/serialization/scene/water.js +4 -0
  258. package/dist/utility/serialization/scene/water.js.map +1 -1
  259. package/dist/utility/serialization/types.js.map +1 -1
  260. package/dist/utility/shprojector.js +96 -95
  261. package/dist/utility/shprojector.js.map +1 -1
  262. package/dist/values.js +105 -58
  263. package/dist/values.js.map +1 -1
  264. package/package.json +3 -3
@@ -0,0 +1,1141 @@
1
+ import { mimeTypeOf, Vector4, Vector3 } from '@zephyr3d/base';
2
+ import '../../../scene/scene.js';
3
+ import '../../../values.js';
4
+ import '../../../render/render_queue.js';
5
+ import '../../../render/primitive.js';
6
+ import '@zephyr3d/device';
7
+ import '../../../material/shader/helper.js';
8
+ import '../../../material/lambert.js';
9
+ import '../../../material/blinn.js';
10
+ import '../../../material/unlit.js';
11
+ import '../../../material/particle.js';
12
+ import '../../../material/subsurfaceprofile.js';
13
+ import '../../../material/skin.js';
14
+ import '../../../material/eye.js';
15
+ import '../../../material/meshmaterial.js';
16
+ import '../../../material/hair.js';
17
+ import '../../../material/hairstrand.js';
18
+ import '../../../material/grassmaterial.js';
19
+ import '../../../material/terrain-cm.js';
20
+ import '../../../material/pbrmr.js';
21
+ import '../../../material/pbrsg.js';
22
+ import '../../../material/mtoon.js';
23
+ import '../../../material/pbrblueprint.js';
24
+ import '../../../material/sprite.js';
25
+ import '../../../material/sprite_std.js';
26
+ import { defineProps } from '../types.js';
27
+ import '../../blueprint/material/texture.js';
28
+ import '../../../render/rendergraph/forward_plus_builder.js';
29
+ import '../../../render/lightpass.js';
30
+ import '../../../render/sky.js';
31
+ import '../../../render/clipmap.js';
32
+ import '../../../render/envlight.js';
33
+ import '../../../render/dualdepthpeeling_oit.js';
34
+ import '../../../shaders/atmosphere.js';
35
+ import '../../../render/rendergraph/scene_render_context.js';
36
+ import { GraphNode } from '../../../scene/graph_node.js';
37
+ import '../../../shadow/shadowmapper.js';
38
+ import '../../../scene/mesh.js';
39
+ import '../../../scene/meshdrawable.js';
40
+ import '../../../scene/basesprite.js';
41
+ import '../../../material/msdf_text.js';
42
+ import '../../../scene/water.js';
43
+ import { HairNode } from '../../../scene/hair.js';
44
+ import '../../../scene/scene_node.js';
45
+ import '../../../scene/particlesys.js';
46
+ import '../../../scene/batchgroup.js';
47
+ import '../../../scene/terrain-cm/terrain-cm.js';
48
+ import '../../../scene/terrain-cm/grass.js';
49
+ import '../../../scene/raycast_visitor.js';
50
+
51
+ /**
52
+ * Serialization for {@link HairNode}.
53
+ *
54
+ * @remarks
55
+ * Ordinary in every respect: the node holds all of its own state, so these are
56
+ * plain accessors onto it and the node saves and loads like any other.
57
+ *
58
+ * Two things are deliberately absent. The strand geometry is not here - it lives
59
+ * in the `.zhair` asset the node references by path, and that file holds nothing
60
+ * but strands, so the same groom can be shared by characters that style it
61
+ * differently. Nor is the material: it is an implementation detail of the node
62
+ * (see the {@link HairNode} class remarks), and its controls appear below as
63
+ * properties of the node itself.
64
+ * @internal
65
+ */ function getHairNodeClass() {
66
+ return {
67
+ ctor: HairNode,
68
+ name: 'HairNode',
69
+ parent: GraphNode,
70
+ createFunc (ctx) {
71
+ const node = new HairNode(ctx.scene);
72
+ node.parent = ctx;
73
+ return {
74
+ obj: node
75
+ };
76
+ },
77
+ getProps () {
78
+ return defineProps([
79
+ {
80
+ name: 'HairAsset',
81
+ description: 'Strand geometry asset drawn by this node',
82
+ type: 'string',
83
+ default: '',
84
+ options: {
85
+ group: 'Geometry',
86
+ label: 'Hair Asset',
87
+ mimeTypes: [
88
+ mimeTypeOf('.zhair')
89
+ ]
90
+ },
91
+ get (value) {
92
+ value.str[0] = this.hairAsset;
93
+ },
94
+ async set (value) {
95
+ await this.setHairAsset(value?.str?.[0] ?? '');
96
+ }
97
+ },
98
+ {
99
+ name: 'StrandStride',
100
+ description: 'Draw one strand in every N. Thins the groom evenly across the scalp rather than cropping it',
101
+ type: 'int',
102
+ default: 1,
103
+ options: {
104
+ group: 'Geometry',
105
+ minValue: 1,
106
+ maxValue: 64
107
+ },
108
+ get (value) {
109
+ value.num[0] = this.strandStride;
110
+ },
111
+ set (value) {
112
+ this.strandStride = value.num[0];
113
+ }
114
+ },
115
+ {
116
+ name: 'MaxStrands',
117
+ description: 'Upper bound on drawn strands, widening the stride further when needed. 0 disables',
118
+ type: 'int',
119
+ default: 0,
120
+ options: {
121
+ group: 'Geometry',
122
+ minValue: 0,
123
+ maxValue: 1000000
124
+ },
125
+ get (value) {
126
+ value.num[0] = this.maxStrands;
127
+ },
128
+ set (value) {
129
+ this.maxStrands = value.num[0];
130
+ }
131
+ },
132
+ {
133
+ name: 'SegmentsPerStrand',
134
+ description: 'Ribbon segments generated per strand. Independent of the control point count, so the same strands can be drawn coarser at a distance',
135
+ type: 'int',
136
+ default: 8,
137
+ options: {
138
+ group: 'Geometry',
139
+ minValue: 1,
140
+ maxValue: 64
141
+ },
142
+ get (value) {
143
+ value.num[0] = this.segmentsPerStrand;
144
+ },
145
+ set (value) {
146
+ this.segmentsPerStrand = value.num[0];
147
+ }
148
+ },
149
+ {
150
+ name: 'StrandWidthScale',
151
+ description: 'Multiplier on the width stored in the strand data',
152
+ type: 'float',
153
+ default: 1,
154
+ options: {
155
+ group: 'Geometry',
156
+ animatable: true,
157
+ minValue: 0,
158
+ maxValue: 100
159
+ },
160
+ get (value) {
161
+ value.num[0] = this.strandWidthScale;
162
+ },
163
+ set (value) {
164
+ this.strandWidthScale = value.num[0];
165
+ }
166
+ },
167
+ {
168
+ name: 'MinStrandWidth',
169
+ description: 'Lower bound on ribbon width, in world units',
170
+ type: 'float',
171
+ default: 0,
172
+ options: {
173
+ group: 'Geometry',
174
+ minValue: 0,
175
+ maxValue: 1
176
+ },
177
+ get (value) {
178
+ value.num[0] = this.minStrandWidth;
179
+ },
180
+ set (value) {
181
+ this.minStrandWidth = value.num[0];
182
+ }
183
+ },
184
+ {
185
+ name: 'MinPixelWidth',
186
+ description: 'Lower bound on ribbon width in pixels. Real hair is thinner than a pixel; widening it and paying the coverage back in alpha keeps distant hair from breaking into a flickering dotted line',
187
+ type: 'float',
188
+ default: 1.4,
189
+ options: {
190
+ group: 'Geometry',
191
+ minValue: 0,
192
+ maxValue: 8
193
+ },
194
+ get (value) {
195
+ value.num[0] = this.minPixelWidth;
196
+ },
197
+ set (value) {
198
+ this.minPixelWidth = value.num[0];
199
+ }
200
+ },
201
+ {
202
+ name: 'RootOcclusion',
203
+ description: 'Darkens ambient light on strands near the root, standing in for the occlusion of being buried in the groom. Environment light is not shadowed, so without this a dense hairstyle is as bright inside as out. Direct light is left to the shadow map',
204
+ type: 'float',
205
+ default: 0.5,
206
+ options: {
207
+ group: 'Shading',
208
+ animatable: true,
209
+ minValue: 0,
210
+ maxValue: 1
211
+ },
212
+ get (value) {
213
+ value.num[0] = this.rootOcclusion;
214
+ },
215
+ set (value) {
216
+ this.rootOcclusion = value.num[0];
217
+ }
218
+ },
219
+ {
220
+ name: 'RootOcclusionRange',
221
+ description: 'Fraction of a strand length over which the root occlusion fades out',
222
+ type: 'float',
223
+ default: 0.6,
224
+ options: {
225
+ group: 'Shading',
226
+ minValue: 0.001,
227
+ maxValue: 1
228
+ },
229
+ isHidden () {
230
+ return this.rootOcclusion <= 0;
231
+ },
232
+ get (value) {
233
+ value.num[0] = this.rootOcclusionRange;
234
+ },
235
+ set (value) {
236
+ this.rootOcclusionRange = value.num[0];
237
+ }
238
+ },
239
+ {
240
+ name: 'StrandLOD',
241
+ description: 'Drop strands with distance, redistributing their coverage to the survivors',
242
+ type: 'bool',
243
+ default: false,
244
+ options: {
245
+ group: 'Geometry'
246
+ },
247
+ get (value) {
248
+ value.bool[0] = this.strandLOD;
249
+ },
250
+ set (value) {
251
+ this.strandLOD = value.bool[0];
252
+ }
253
+ },
254
+ {
255
+ name: 'MinStrandLODRatio',
256
+ description: 'Floor on the fraction of strands distance decimation keeps',
257
+ type: 'float',
258
+ default: 0.05,
259
+ options: {
260
+ group: 'Geometry',
261
+ minValue: 0,
262
+ maxValue: 1
263
+ },
264
+ isHidden () {
265
+ return !this.strandLOD;
266
+ },
267
+ get (value) {
268
+ value.num[0] = this.minStrandLODRatio;
269
+ },
270
+ set (value) {
271
+ this.minStrandLODRatio = value.num[0];
272
+ }
273
+ },
274
+ {
275
+ name: 'AlbedoColor',
276
+ description: 'Base color of the strands',
277
+ type: 'rgba',
278
+ default: [
279
+ 1,
280
+ 1,
281
+ 1,
282
+ 1
283
+ ],
284
+ options: {
285
+ group: 'Shading',
286
+ animatable: true,
287
+ minValue: 0,
288
+ maxValue: 1
289
+ },
290
+ get (value) {
291
+ value.num[0] = this.albedoColor.x;
292
+ value.num[1] = this.albedoColor.y;
293
+ value.num[2] = this.albedoColor.z;
294
+ value.num[3] = this.albedoColor.w;
295
+ },
296
+ set (value) {
297
+ this.albedoColor = new Vector4(value.num[0], value.num[1], value.num[2], value.num[3]);
298
+ }
299
+ },
300
+ {
301
+ name: 'ShadingModel',
302
+ description: 'Which scattering model shades the hair. Marschner derives the lobes from the fibre; Kajiya-Kay is the art-directed double lobe',
303
+ type: 'string',
304
+ default: 'kajiya-kay',
305
+ options: {
306
+ group: 'Shading',
307
+ enum: {
308
+ labels: [
309
+ 'Kajiya-Kay (double lobe)',
310
+ 'Marschner (fibre)'
311
+ ],
312
+ values: [
313
+ 'kajiya-kay',
314
+ 'marschner'
315
+ ]
316
+ }
317
+ },
318
+ get (value) {
319
+ value.str[0] = this.shadingModel;
320
+ },
321
+ set (value) {
322
+ this.shadingModel = value.str[0];
323
+ }
324
+ },
325
+ {
326
+ name: 'Specular1Color',
327
+ description: 'Color of the primary (sharp, near-white) specular lobe',
328
+ type: 'rgb',
329
+ default: [
330
+ 0.35,
331
+ 0.35,
332
+ 0.35
333
+ ],
334
+ options: {
335
+ group: 'Shading',
336
+ animatable: true,
337
+ minValue: 0,
338
+ maxValue: 1
339
+ },
340
+ isHidden () {
341
+ return this.shadingModel !== 'kajiya-kay';
342
+ },
343
+ get (value) {
344
+ value.num[0] = this.specular1Color.x;
345
+ value.num[1] = this.specular1Color.y;
346
+ value.num[2] = this.specular1Color.z;
347
+ },
348
+ set (value) {
349
+ this.specular1Color = new Vector3(value.num[0], value.num[1], value.num[2]);
350
+ }
351
+ },
352
+ {
353
+ name: 'Specular1Power',
354
+ description: 'Exponent of the primary specular lobe',
355
+ type: 'float',
356
+ default: 160,
357
+ options: {
358
+ group: 'Shading',
359
+ animatable: true,
360
+ minValue: 1,
361
+ maxValue: 1024
362
+ },
363
+ isHidden () {
364
+ return this.shadingModel !== 'kajiya-kay';
365
+ },
366
+ get (value) {
367
+ value.num[0] = this.specular1Power;
368
+ },
369
+ set (value) {
370
+ this.specular1Power = value.num[0];
371
+ }
372
+ },
373
+ {
374
+ name: 'Specular1Shift',
375
+ description: 'Shift of the primary specular lobe along the strand',
376
+ type: 'float',
377
+ default: 0.05,
378
+ options: {
379
+ group: 'Shading',
380
+ animatable: true,
381
+ minValue: -1,
382
+ maxValue: 1
383
+ },
384
+ isHidden () {
385
+ return this.shadingModel !== 'kajiya-kay';
386
+ },
387
+ get (value) {
388
+ value.num[0] = this.specular1Shift;
389
+ },
390
+ set (value) {
391
+ this.specular1Shift = value.num[0];
392
+ }
393
+ },
394
+ {
395
+ name: 'Specular2Color',
396
+ description: 'Color of the secondary (broad, tinted) specular lobe',
397
+ type: 'rgb',
398
+ default: [
399
+ 0.5,
400
+ 0.35,
401
+ 0.25
402
+ ],
403
+ options: {
404
+ group: 'Shading',
405
+ animatable: true,
406
+ minValue: 0,
407
+ maxValue: 1
408
+ },
409
+ isHidden () {
410
+ return this.shadingModel !== 'kajiya-kay';
411
+ },
412
+ get (value) {
413
+ value.num[0] = this.specular2Color.x;
414
+ value.num[1] = this.specular2Color.y;
415
+ value.num[2] = this.specular2Color.z;
416
+ },
417
+ set (value) {
418
+ this.specular2Color = new Vector3(value.num[0], value.num[1], value.num[2]);
419
+ }
420
+ },
421
+ {
422
+ name: 'Specular2Power',
423
+ description: 'Exponent of the secondary specular lobe',
424
+ type: 'float',
425
+ default: 20,
426
+ options: {
427
+ group: 'Shading',
428
+ animatable: true,
429
+ minValue: 1,
430
+ maxValue: 1024
431
+ },
432
+ isHidden () {
433
+ return this.shadingModel !== 'kajiya-kay';
434
+ },
435
+ get (value) {
436
+ value.num[0] = this.specular2Power;
437
+ },
438
+ set (value) {
439
+ this.specular2Power = value.num[0];
440
+ }
441
+ },
442
+ {
443
+ name: 'Specular2Shift',
444
+ description: 'Shift of the secondary specular lobe along the strand',
445
+ type: 'float',
446
+ default: -0.08,
447
+ options: {
448
+ group: 'Shading',
449
+ animatable: true,
450
+ minValue: -1,
451
+ maxValue: 1
452
+ },
453
+ isHidden () {
454
+ return this.shadingModel !== 'kajiya-kay';
455
+ },
456
+ get (value) {
457
+ value.num[0] = this.specular2Shift;
458
+ },
459
+ set (value) {
460
+ this.specular2Shift = value.num[0];
461
+ }
462
+ },
463
+ {
464
+ name: 'MarschnerShift',
465
+ description: 'Longitudinal shift of the Marschner lobes',
466
+ type: 'float',
467
+ default: 0.035,
468
+ options: {
469
+ group: 'Shading',
470
+ animatable: true,
471
+ minValue: 0,
472
+ maxValue: 0.5
473
+ },
474
+ isHidden () {
475
+ return this.shadingModel !== 'marschner';
476
+ },
477
+ get (value) {
478
+ value.num[0] = this.marschnerShift;
479
+ },
480
+ set (value) {
481
+ this.marschnerShift = value.num[0];
482
+ }
483
+ },
484
+ {
485
+ name: 'MarschnerRoughness',
486
+ description: 'Longitudinal roughness of the Marschner lobes',
487
+ type: 'float',
488
+ default: 0.25,
489
+ options: {
490
+ group: 'Shading',
491
+ animatable: true,
492
+ minValue: 0.01,
493
+ maxValue: 1
494
+ },
495
+ isHidden () {
496
+ return this.shadingModel !== 'marschner';
497
+ },
498
+ get (value) {
499
+ value.num[0] = this.marschnerRoughness;
500
+ },
501
+ set (value) {
502
+ this.marschnerRoughness = value.num[0];
503
+ }
504
+ },
505
+ {
506
+ name: 'MarschnerIOR',
507
+ description: 'Index of refraction of the fibre',
508
+ type: 'float',
509
+ default: 1.55,
510
+ options: {
511
+ group: 'Shading',
512
+ animatable: true,
513
+ minValue: 1,
514
+ maxValue: 3
515
+ },
516
+ isHidden () {
517
+ return this.shadingModel !== 'marschner';
518
+ },
519
+ get (value) {
520
+ value.num[0] = this.marschnerIOR;
521
+ },
522
+ set (value) {
523
+ this.marschnerIOR = value.num[0];
524
+ }
525
+ },
526
+ {
527
+ name: 'MarschnerAbsorption',
528
+ description: 'How strongly pigmented the fibre is. Deepens the transmitted paths without touching the white surface reflection',
529
+ type: 'float',
530
+ default: 1,
531
+ options: {
532
+ group: 'Shading',
533
+ animatable: true,
534
+ minValue: 0,
535
+ maxValue: 8
536
+ },
537
+ isHidden () {
538
+ return this.shadingModel !== 'marschner';
539
+ },
540
+ get (value) {
541
+ value.num[0] = this.marschnerAbsorption;
542
+ },
543
+ set (value) {
544
+ this.marschnerAbsorption = value.num[0];
545
+ }
546
+ },
547
+ {
548
+ name: 'MarschnerLobes',
549
+ description: 'Relative weight of the R, TT and TRT lobes',
550
+ type: 'vec3',
551
+ default: [
552
+ 1,
553
+ 1,
554
+ 1
555
+ ],
556
+ options: {
557
+ group: 'Shading',
558
+ animatable: true,
559
+ minValue: 0,
560
+ maxValue: 4
561
+ },
562
+ isHidden () {
563
+ return this.shadingModel !== 'marschner';
564
+ },
565
+ get (value) {
566
+ value.num[0] = this.marschnerLobes.x;
567
+ value.num[1] = this.marschnerLobes.y;
568
+ value.num[2] = this.marschnerLobes.z;
569
+ },
570
+ set (value) {
571
+ this.marschnerLobes = new Vector3(value.num[0], value.num[1], value.num[2]);
572
+ }
573
+ },
574
+ {
575
+ name: 'StrandRoundness',
576
+ description: 'How far the shading normal bends across the ribbon. At 0 a strand shades as a flat tape, at 1 as a cylinder',
577
+ type: 'float',
578
+ default: 1,
579
+ options: {
580
+ group: 'Shading',
581
+ animatable: true,
582
+ minValue: 0,
583
+ maxValue: 1
584
+ },
585
+ get (value) {
586
+ value.num[0] = this.strandRoundness;
587
+ },
588
+ set (value) {
589
+ this.strandRoundness = value.num[0];
590
+ }
591
+ },
592
+ {
593
+ name: 'DiffuseWrap',
594
+ description: 'How far diffuse lighting wraps around the fibre',
595
+ type: 'float',
596
+ default: 0.5,
597
+ options: {
598
+ group: 'Shading',
599
+ animatable: true,
600
+ minValue: 0,
601
+ maxValue: 1
602
+ },
603
+ get (value) {
604
+ value.num[0] = this.diffuseWrap;
605
+ },
606
+ set (value) {
607
+ this.diffuseWrap = value.num[0];
608
+ }
609
+ },
610
+ {
611
+ name: 'TransmissionColor',
612
+ description: 'Color of light transmitted through the fibre',
613
+ type: 'rgb',
614
+ default: [
615
+ 0.6,
616
+ 0.35,
617
+ 0.2
618
+ ],
619
+ options: {
620
+ group: 'Shading',
621
+ animatable: true,
622
+ minValue: 0,
623
+ maxValue: 1
624
+ },
625
+ get (value) {
626
+ value.num[0] = this.transmissionColor.x;
627
+ value.num[1] = this.transmissionColor.y;
628
+ value.num[2] = this.transmissionColor.z;
629
+ },
630
+ set (value) {
631
+ this.transmissionColor = new Vector3(value.num[0], value.num[1], value.num[2]);
632
+ }
633
+ },
634
+ {
635
+ name: 'TransmissionIntensity',
636
+ description: 'Strength of back-lit transmission',
637
+ type: 'float',
638
+ default: 0.35,
639
+ options: {
640
+ group: 'Shading',
641
+ animatable: true,
642
+ minValue: 0,
643
+ maxValue: 4
644
+ },
645
+ get (value) {
646
+ value.num[0] = this.transmissionIntensity;
647
+ },
648
+ set (value) {
649
+ this.transmissionIntensity = value.num[0];
650
+ }
651
+ },
652
+ {
653
+ name: 'TransmissionPower',
654
+ description: 'Falloff exponent of back-lit transmission',
655
+ type: 'float',
656
+ default: 4,
657
+ options: {
658
+ group: 'Shading',
659
+ animatable: true,
660
+ minValue: 1,
661
+ maxValue: 64
662
+ },
663
+ get (value) {
664
+ value.num[0] = this.transmissionPower;
665
+ },
666
+ set (value) {
667
+ this.transmissionPower = value.num[0];
668
+ }
669
+ },
670
+ {
671
+ name: 'ScatterColor',
672
+ description: 'Color of multiple scattering within the groom',
673
+ type: 'rgb',
674
+ default: [
675
+ 0.55,
676
+ 0.32,
677
+ 0.18
678
+ ],
679
+ options: {
680
+ group: 'Shading',
681
+ animatable: true,
682
+ minValue: 0,
683
+ maxValue: 1
684
+ },
685
+ get (value) {
686
+ value.num[0] = this.scatterColor.x;
687
+ value.num[1] = this.scatterColor.y;
688
+ value.num[2] = this.scatterColor.z;
689
+ },
690
+ set (value) {
691
+ this.scatterColor = new Vector3(value.num[0], value.num[1], value.num[2]);
692
+ }
693
+ },
694
+ {
695
+ name: 'ScatterIntensity',
696
+ description: 'Strength of multiple scattering',
697
+ type: 'float',
698
+ default: 0,
699
+ options: {
700
+ group: 'Shading',
701
+ animatable: true,
702
+ minValue: 0,
703
+ maxValue: 4
704
+ },
705
+ get (value) {
706
+ value.num[0] = this.scatterIntensity;
707
+ },
708
+ set (value) {
709
+ this.scatterIntensity = value.num[0];
710
+ }
711
+ },
712
+ {
713
+ name: 'ScatterLocal',
714
+ description: 'Share of scattering taken as local rather than global',
715
+ type: 'float',
716
+ default: 0.5,
717
+ options: {
718
+ group: 'Shading',
719
+ animatable: true,
720
+ minValue: 0,
721
+ maxValue: 1
722
+ },
723
+ isHidden () {
724
+ return this.scatterIntensity <= 0;
725
+ },
726
+ get (value) {
727
+ value.num[0] = this.scatterLocal;
728
+ },
729
+ set (value) {
730
+ this.scatterLocal = value.num[0];
731
+ }
732
+ },
733
+ {
734
+ name: 'ScatterWrap',
735
+ description: 'How far scattered light wraps around the fibre',
736
+ type: 'float',
737
+ default: 0.8,
738
+ options: {
739
+ group: 'Shading',
740
+ animatable: true,
741
+ minValue: 0,
742
+ maxValue: 1
743
+ },
744
+ isHidden () {
745
+ return this.scatterIntensity <= 0;
746
+ },
747
+ get (value) {
748
+ value.num[0] = this.scatterWrap;
749
+ },
750
+ set (value) {
751
+ this.scatterWrap = value.num[0];
752
+ }
753
+ },
754
+ {
755
+ name: 'BlendMode',
756
+ description: 'How the strands blend with what is behind them. The pixel-width floor pays its widening back in alpha, which only means anything once blending is on',
757
+ type: 'string',
758
+ default: 'none',
759
+ options: {
760
+ group: 'Transparency',
761
+ enum: {
762
+ labels: [
763
+ 'None',
764
+ 'Blend',
765
+ 'Additive',
766
+ 'Max',
767
+ 'Min'
768
+ ],
769
+ values: [
770
+ 'none',
771
+ 'blend',
772
+ 'additive',
773
+ 'max',
774
+ 'min'
775
+ ]
776
+ }
777
+ },
778
+ get (value) {
779
+ value.str[0] = this.blendMode;
780
+ },
781
+ set (value) {
782
+ this.blendMode = value.str[0];
783
+ }
784
+ },
785
+ {
786
+ name: 'AlphaCutoff',
787
+ description: 'Alpha below which a fragment is discarded',
788
+ type: 'float',
789
+ default: 0,
790
+ options: {
791
+ group: 'Transparency',
792
+ animatable: true,
793
+ minValue: 0,
794
+ maxValue: 1
795
+ },
796
+ get (value) {
797
+ value.num[0] = this.alphaCutoff;
798
+ },
799
+ set (value) {
800
+ this.alphaCutoff = value.num[0];
801
+ }
802
+ },
803
+ {
804
+ name: 'AlphaDither',
805
+ description: 'Dither the alpha test, so a temporal filter resolves the soft edge',
806
+ type: 'bool',
807
+ default: false,
808
+ options: {
809
+ group: 'Transparency'
810
+ },
811
+ get (value) {
812
+ value.bool[0] = this.alphaDither;
813
+ },
814
+ set (value) {
815
+ this.alphaDither = value.bool[0];
816
+ }
817
+ },
818
+ {
819
+ name: 'CastShadow',
820
+ description: 'If true, the groom is drawn into shadow maps',
821
+ type: 'bool',
822
+ default: true,
823
+ options: {
824
+ group: 'Shadow'
825
+ },
826
+ get (value) {
827
+ value.bool[0] = this.castShadow;
828
+ },
829
+ set (value) {
830
+ this.castShadow = value.bool[0];
831
+ }
832
+ },
833
+ {
834
+ name: 'TransparentShadowCaster',
835
+ description: 'Let the shadow caster pass respect strand alpha, for softer self-shadowing',
836
+ type: 'bool',
837
+ default: false,
838
+ options: {
839
+ group: 'Shadow'
840
+ },
841
+ isHidden () {
842
+ return !this.castShadow;
843
+ },
844
+ get (value) {
845
+ value.bool[0] = this.transparentShadowCaster;
846
+ },
847
+ set (value) {
848
+ this.transparentShadowCaster = value.bool[0];
849
+ }
850
+ },
851
+ {
852
+ name: 'ShadowAlphaCutoff',
853
+ description: 'Alpha below which a fragment casts no shadow',
854
+ type: 'float',
855
+ default: 0,
856
+ options: {
857
+ group: 'Shadow',
858
+ minValue: 0,
859
+ maxValue: 1
860
+ },
861
+ isHidden () {
862
+ return !this.castShadow || !this.transparentShadowCaster;
863
+ },
864
+ get (value) {
865
+ value.num[0] = this.shadowAlphaCutoff;
866
+ },
867
+ set (value) {
868
+ this.shadowAlphaCutoff = value.num[0];
869
+ }
870
+ },
871
+ {
872
+ name: 'Simulation',
873
+ description: 'Run strand dynamics on this groom. WebGPU only; the strands stay in their authored pose elsewhere',
874
+ type: 'bool',
875
+ default: false,
876
+ options: {
877
+ group: 'Simulation'
878
+ },
879
+ get (value) {
880
+ value.bool[0] = this.simulationEnabled;
881
+ },
882
+ set (value) {
883
+ this.simulationEnabled = value.bool[0];
884
+ }
885
+ },
886
+ {
887
+ name: 'Gravity',
888
+ description: 'World-space gravity acting on the strands',
889
+ type: 'vec3',
890
+ default: [
891
+ 0,
892
+ -9.8,
893
+ 0
894
+ ],
895
+ options: {
896
+ group: 'Simulation',
897
+ animatable: true
898
+ },
899
+ isHidden () {
900
+ return !this.simulationEnabled;
901
+ },
902
+ get (value) {
903
+ value.num[0] = this.gravity.x;
904
+ value.num[1] = this.gravity.y;
905
+ value.num[2] = this.gravity.z;
906
+ },
907
+ set (value) {
908
+ this.gravity = new Vector3(value.num[0], value.num[1], value.num[2]);
909
+ }
910
+ },
911
+ {
912
+ name: 'Local Stiffness',
913
+ description: 'How strongly a strand keeps its authored shape. Holds the curl, and damps the groom',
914
+ type: 'float',
915
+ default: 0.9,
916
+ options: {
917
+ group: 'Simulation',
918
+ animatable: true,
919
+ minValue: 0,
920
+ maxValue: 1
921
+ },
922
+ isHidden () {
923
+ return !this.simulationEnabled;
924
+ },
925
+ get (value) {
926
+ value.num[0] = this.localStiffness;
927
+ },
928
+ set (value) {
929
+ this.localStiffness = value.num[0];
930
+ }
931
+ },
932
+ {
933
+ name: 'Local Iterations',
934
+ description: 'Local shape constraint passes per substep. More converges closer',
935
+ type: 'int',
936
+ default: 2,
937
+ options: {
938
+ group: 'Simulation',
939
+ minValue: 1,
940
+ maxValue: 8
941
+ },
942
+ isHidden () {
943
+ return !this.simulationEnabled;
944
+ },
945
+ get (value) {
946
+ value.num[0] = this.localIterations;
947
+ },
948
+ set (value) {
949
+ this.localIterations = value.num[0];
950
+ }
951
+ },
952
+ {
953
+ name: 'Global Stiffness',
954
+ description: 'Pull back to the authored pose. Off by default: it anchors points in place, which reads as a spring',
955
+ type: 'float',
956
+ default: 0,
957
+ options: {
958
+ group: 'Simulation',
959
+ animatable: true,
960
+ minValue: 0,
961
+ maxValue: 1
962
+ },
963
+ isHidden () {
964
+ return !this.simulationEnabled;
965
+ },
966
+ get (value) {
967
+ value.num[0] = this.globalStiffness;
968
+ },
969
+ set (value) {
970
+ this.globalStiffness = value.num[0];
971
+ }
972
+ },
973
+ {
974
+ name: 'Global Range',
975
+ description: 'Fraction of a strand, from the root, the pose pull acts on',
976
+ type: 'float',
977
+ default: 0,
978
+ options: {
979
+ group: 'Simulation',
980
+ minValue: 0,
981
+ maxValue: 1
982
+ },
983
+ isHidden () {
984
+ return !this.simulationEnabled;
985
+ },
986
+ get (value) {
987
+ value.num[0] = this.globalRange;
988
+ },
989
+ set (value) {
990
+ this.globalRange = value.num[0];
991
+ }
992
+ },
993
+ {
994
+ name: 'FTL Damping',
995
+ description: 'Length correction handed back to the parent point as reverse momentum. Lower whips more',
996
+ type: 'float',
997
+ default: 0.7,
998
+ options: {
999
+ group: 'Simulation',
1000
+ minValue: 0,
1001
+ maxValue: 1
1002
+ },
1003
+ isHidden () {
1004
+ return !this.simulationEnabled;
1005
+ },
1006
+ get (value) {
1007
+ value.num[0] = this.ftlDamping;
1008
+ },
1009
+ set (value) {
1010
+ this.ftlDamping = value.num[0];
1011
+ }
1012
+ },
1013
+ {
1014
+ name: 'Shock Propagation',
1015
+ description: 'How much of the node motion strands are carried along by. 0 lags fully, 1 follows rigidly',
1016
+ type: 'float',
1017
+ default: 0.8,
1018
+ options: {
1019
+ group: 'Simulation',
1020
+ animatable: true,
1021
+ minValue: 0,
1022
+ maxValue: 1
1023
+ },
1024
+ isHidden () {
1025
+ return !this.simulationEnabled;
1026
+ },
1027
+ get (value) {
1028
+ value.num[0] = this.vspCoeff;
1029
+ },
1030
+ set (value) {
1031
+ this.vspCoeff = value.num[0];
1032
+ }
1033
+ },
1034
+ {
1035
+ name: 'Shock Threshold',
1036
+ description: 'Node acceleration above which strands stop lagging, in units per second squared',
1037
+ type: 'float',
1038
+ default: 50,
1039
+ options: {
1040
+ group: 'Simulation',
1041
+ minValue: 0,
1042
+ maxValue: 500
1043
+ },
1044
+ isHidden () {
1045
+ return !this.simulationEnabled;
1046
+ },
1047
+ get (value) {
1048
+ value.num[0] = this.vspAccelThreshold;
1049
+ },
1050
+ set (value) {
1051
+ this.vspAccelThreshold = value.num[0];
1052
+ }
1053
+ },
1054
+ {
1055
+ name: 'Damping',
1056
+ description: 'Velocity lost each step. 0 keeps full inertia',
1057
+ type: 'float',
1058
+ default: 0.08,
1059
+ options: {
1060
+ group: 'Simulation',
1061
+ animatable: true,
1062
+ minValue: 0,
1063
+ maxValue: 1
1064
+ },
1065
+ isHidden () {
1066
+ return !this.simulationEnabled;
1067
+ },
1068
+ get (value) {
1069
+ value.num[0] = this.damping;
1070
+ },
1071
+ set (value) {
1072
+ this.damping = value.num[0];
1073
+ }
1074
+ },
1075
+ {
1076
+ name: 'Friction',
1077
+ description: 'Tangential motion removed at a contact',
1078
+ type: 'float',
1079
+ default: 0.2,
1080
+ options: {
1081
+ group: 'Simulation',
1082
+ minValue: 0,
1083
+ maxValue: 1
1084
+ },
1085
+ isHidden () {
1086
+ return !this.simulationEnabled;
1087
+ },
1088
+ get (value) {
1089
+ value.num[0] = this.friction;
1090
+ },
1091
+ set (value) {
1092
+ this.friction = value.num[0];
1093
+ }
1094
+ },
1095
+ {
1096
+ name: 'Substeps',
1097
+ description: 'Integration substeps per fixed step. More is stabler and slower',
1098
+ type: 'int',
1099
+ default: 1,
1100
+ options: {
1101
+ group: 'Simulation',
1102
+ minValue: 1,
1103
+ maxValue: 8
1104
+ },
1105
+ isHidden () {
1106
+ return !this.simulationEnabled;
1107
+ },
1108
+ get (value) {
1109
+ value.num[0] = this.substeps;
1110
+ },
1111
+ set (value) {
1112
+ this.substeps = value.num[0];
1113
+ }
1114
+ },
1115
+ {
1116
+ name: 'Max Speed Factor',
1117
+ description: 'Per-substep ceiling on point travel, in segment lengths',
1118
+ type: 'float',
1119
+ default: 4,
1120
+ options: {
1121
+ group: 'Simulation',
1122
+ minValue: 0,
1123
+ maxValue: 32
1124
+ },
1125
+ isHidden () {
1126
+ return !this.simulationEnabled;
1127
+ },
1128
+ get (value) {
1129
+ value.num[0] = this.maxSpeedFactor;
1130
+ },
1131
+ set (value) {
1132
+ this.maxSpeedFactor = value.num[0];
1133
+ }
1134
+ }
1135
+ ]);
1136
+ }
1137
+ };
1138
+ }
1139
+
1140
+ export { getHairNodeClass };
1141
+ //# sourceMappingURL=hair.js.map