@zephyr3d/scene 0.9.6 → 0.9.7
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.
- package/dist/animation/joint_dynamics/controller.js +92 -32
- package/dist/animation/joint_dynamics/controller.js.map +1 -1
- package/dist/animation/joint_dynamics/convex_collider.js +320 -0
- package/dist/animation/joint_dynamics/convex_collider.js.map +1 -0
- package/dist/animation/joint_dynamics/joint_dynamics_system.js +57 -19
- package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
- package/dist/animation/joint_dynamics/solver.js +71 -27
- package/dist/animation/joint_dynamics/solver.js.map +1 -1
- package/dist/animation/joint_dynamics_modifier.js +21 -20
- package/dist/animation/joint_dynamics_modifier.js.map +1 -1
- package/dist/animation/skeleton.js +7 -10
- package/dist/animation/skeleton.js.map +1 -1
- package/dist/app/engine.js +134 -140
- package/dist/app/engine.js.map +1 -1
- package/dist/app/scriptregistry.js +47 -16
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/assetmanager.js +3 -1
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/model.js +346 -7
- package/dist/asset/model.js.map +1 -1
- package/dist/avatar/wardrobe.js +20 -16
- package/dist/avatar/wardrobe.js.map +1 -1
- package/dist/camera/camera.js +416 -210
- package/dist/camera/camera.js.map +1 -1
- package/dist/index.d.ts +1349 -621
- package/dist/index.js +6 -11
- package/dist/index.js.map +1 -1
- package/dist/material/blinn.js +1 -1
- package/dist/material/blinn.js.map +1 -1
- package/dist/material/lambert.js +1 -1
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/material.js +23 -1
- package/dist/material/material.js.map +1 -1
- package/dist/material/meshmaterial.js +178 -23
- package/dist/material/meshmaterial.js.map +1 -1
- package/dist/material/mixins/albedocolor.js +4 -4
- package/dist/material/mixins/albedocolor.js.map +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js +2 -1
- package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
- package/dist/material/mixins/lightmodel/lambert.js +2 -1
- package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +63 -16
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +105 -32
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js +16 -6
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
- package/dist/material/mixins/lit.js +1 -1
- package/dist/material/mixins/lit.js.map +1 -1
- package/dist/material/mixins/pbr/common.js +276 -65
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/material/mixins/texture.js +3 -3
- package/dist/material/mixins/texture.js.map +1 -1
- package/dist/material/mixins/vertexcolor.js +2 -2
- package/dist/material/mixins/vertexcolor.js.map +1 -1
- package/dist/material/mtoon.js +574 -0
- package/dist/material/mtoon.js.map +1 -0
- package/dist/material/pbrblueprint.js +499 -336
- package/dist/material/pbrblueprint.js.map +1 -1
- package/dist/material/pbrmr.js +118 -100
- package/dist/material/pbrmr.js.map +1 -1
- package/dist/material/pbrsg.js +1 -1
- package/dist/material/pbrsg.js.map +1 -1
- package/dist/material/shader/helper.js +324 -294
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/subsurfaceprofile.js +812 -0
- package/dist/material/subsurfaceprofile.js.map +1 -0
- package/dist/material/unlit.js +1 -1
- package/dist/material/unlit.js.map +1 -1
- package/dist/posteffect/compositor.js +46 -11
- package/dist/posteffect/compositor.js.map +1 -1
- package/dist/posteffect/ssr.js +422 -96
- package/dist/posteffect/ssr.js.map +1 -1
- package/dist/posteffect/sss.js +1053 -0
- package/dist/posteffect/sss.js.map +1 -0
- package/dist/posteffect/taa.js +61 -60
- package/dist/posteffect/taa.js.map +1 -1
- package/dist/render/abuffer_oit.js +63 -12
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/cluster_light.js +6 -5
- package/dist/render/cluster_light.js.map +1 -1
- package/dist/render/drawable.js +1 -5
- package/dist/render/drawable.js.map +1 -1
- package/dist/render/drawable_mixin.js +2 -1
- package/dist/render/drawable_mixin.js.map +1 -1
- package/dist/render/fbm_wavegenerator.js +2 -1
- package/dist/render/fbm_wavegenerator.js.map +1 -1
- package/dist/render/gerstner_wavegenerator.js +2 -1
- package/dist/render/gerstner_wavegenerator.js.map +1 -1
- package/dist/render/globalbindgroup_allocator.js +2 -1
- package/dist/render/globalbindgroup_allocator.js.map +1 -1
- package/dist/render/lightpass.js +110 -23
- package/dist/render/lightpass.js.map +1 -1
- package/dist/render/render_queue.js +51 -8
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/renderer.js +80 -66
- package/dist/render/renderer.js.map +1 -1
- package/dist/render/rendergraph/device_pool_allocator.js +8 -0
- package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
- package/dist/render/rendergraph/forward_plus_builder.js +481 -95
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/render/rendergraph/history_resource_manager.js +55 -0
- package/dist/render/rendergraph/history_resource_manager.js.map +1 -1
- package/dist/render/rendergraph/history_resources.js +3 -1
- package/dist/render/rendergraph/history_resources.js.map +1 -1
- package/dist/render/rendergraph/types.js.map +1 -1
- package/dist/render/renderpass.js +10 -4
- package/dist/render/renderpass.js.map +1 -1
- package/dist/render/sky.js +31 -1
- package/dist/render/sky.js.map +1 -1
- package/dist/render/weightedblended_oit.js +23 -5
- package/dist/render/weightedblended_oit.js.map +1 -1
- package/dist/scene/basesprite.js +4 -2
- package/dist/scene/basesprite.js.map +1 -1
- package/dist/scene/batchgroup.js +3 -1
- package/dist/scene/batchgroup.js.map +1 -1
- package/dist/scene/environment.js +11 -1
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/light.js +21 -3
- package/dist/scene/light.js.map +1 -1
- package/dist/scene/mesh.js +29 -14
- package/dist/scene/mesh.js.map +1 -1
- package/dist/scene/meshdrawable.js +6 -0
- package/dist/scene/meshdrawable.js.map +1 -1
- package/dist/scene/msdftext.js +5 -2
- package/dist/scene/msdftext.js.map +1 -1
- package/dist/scene/msdftextsprite.js +5 -3
- package/dist/scene/msdftextsprite.js.map +1 -1
- package/dist/scene/particlesys.js +3 -1
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/scene.js +6 -5
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/terrain-cm/grass.js +4 -2
- package/dist/scene/terrain-cm/grass.js.map +1 -1
- package/dist/scene/terrain-cm/grassmaterial.js +2 -1
- package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +4 -2
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/scene/water.js +4 -2
- package/dist/scene/water.js.map +1 -1
- package/dist/shaders/shadow.js +26 -393
- package/dist/shaders/shadow.js.map +1 -1
- package/dist/shadow/esm.js +112 -12
- package/dist/shadow/esm.js.map +1 -1
- package/dist/shadow/pcf_opt.js +2 -2
- package/dist/shadow/pcf_opt.js.map +1 -1
- package/dist/shadow/pcf_pd.js +19 -10
- package/dist/shadow/pcf_pd.js.map +1 -1
- package/dist/shadow/shader.js +58 -7
- package/dist/shadow/shader.js.map +1 -1
- package/dist/shadow/shadow_impl.js +6 -0
- package/dist/shadow/shadow_impl.js.map +1 -1
- package/dist/shadow/shadow_region.js +229 -0
- package/dist/shadow/shadow_region.js.map +1 -0
- package/dist/shadow/shadowmapper.js +67 -59
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shadow/vsm.js +45 -19
- package/dist/shadow/vsm.js.map +1 -1
- package/dist/utility/blueprint/common/constants.js +8 -8
- package/dist/utility/blueprint/common/constants.js.map +1 -1
- package/dist/utility/blueprint/material/pbr.js +31 -4
- package/dist/utility/blueprint/material/pbr.js.map +1 -1
- package/dist/utility/blueprint/material/texture.js +1 -17
- package/dist/utility/blueprint/material/texture.js.map +1 -1
- package/dist/utility/serialization/manager.js +327 -359
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +5 -2
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/batch.js +4 -1
- package/dist/utility/serialization/scene/batch.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +249 -54
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/common.js +37 -1
- package/dist/utility/serialization/scene/common.js.map +1 -1
- package/dist/utility/serialization/scene/light.js +42 -3
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +1112 -646
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +7 -4
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +31 -12
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/particle.js +4 -1
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/primitive.js +3 -1
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/scene.js +18 -0
- package/dist/utility/serialization/scene/scene.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +6 -3
- package/dist/utility/serialization/scene/sprite.js.map +1 -1
- package/dist/utility/serialization/scene/terrain.js +5 -2
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/text.js +3 -1
- package/dist/utility/serialization/scene/text.js.map +1 -1
- package/dist/utility/serialization/scene/water.js +4 -1
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/utility/textures/ltcdata.js +6 -0
- package/dist/utility/textures/ltcdata.js.map +1 -0
- package/dist/utility/textures/ltclut.js +61 -0
- package/dist/utility/textures/ltclut.js.map +1 -0
- package/dist/values.js +9 -1
- package/dist/values.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,812 @@
|
|
|
1
|
+
import { Vector3 } from '@zephyr3d/base';
|
|
2
|
+
|
|
3
|
+
const SUBSURFACE_PROFILE_PRESET_ALIAS = {
|
|
4
|
+
skin: 'skin_default',
|
|
5
|
+
skin_thin: 'skin_thin',
|
|
6
|
+
skin_default: 'skin_default',
|
|
7
|
+
skin_heavy_makeup: 'skin_heavy_makeup',
|
|
8
|
+
wax: 'wax_backlit',
|
|
9
|
+
wax_backlit: 'wax_backlit',
|
|
10
|
+
wax_soft: 'wax_soft',
|
|
11
|
+
jade: 'jade_soft',
|
|
12
|
+
jade_backlit: 'jade_backlit',
|
|
13
|
+
jade_soft: 'jade_soft'
|
|
14
|
+
};
|
|
15
|
+
const SUBSURFACE_PROFILE_PRESET_INDEX = {
|
|
16
|
+
skin_thin: 0,
|
|
17
|
+
skin_default: 1,
|
|
18
|
+
skin_heavy_makeup: 2,
|
|
19
|
+
wax_backlit: 3,
|
|
20
|
+
wax_soft: 4,
|
|
21
|
+
jade_backlit: 5,
|
|
22
|
+
jade_soft: 6
|
|
23
|
+
};
|
|
24
|
+
const SUBSURFACE_PROFILE_PRESET_TEMPLATE = {
|
|
25
|
+
skin_thin: {
|
|
26
|
+
meanFreePathColor: [
|
|
27
|
+
1.0,
|
|
28
|
+
0.37,
|
|
29
|
+
0.11
|
|
30
|
+
],
|
|
31
|
+
meanFreePathDistance: 0.7,
|
|
32
|
+
falloffColor: [
|
|
33
|
+
1.0,
|
|
34
|
+
0.32,
|
|
35
|
+
0.2
|
|
36
|
+
],
|
|
37
|
+
strength: 0.68,
|
|
38
|
+
scale: 0.82,
|
|
39
|
+
worldUnitScale: 0.88,
|
|
40
|
+
boundaryColorBleed: 0.13,
|
|
41
|
+
transmissionTintColor: [
|
|
42
|
+
1,
|
|
43
|
+
0.37,
|
|
44
|
+
0.28
|
|
45
|
+
],
|
|
46
|
+
extinctionScale: 1.24,
|
|
47
|
+
normalScale: 1.18,
|
|
48
|
+
scatteringDistribution: 0.56
|
|
49
|
+
},
|
|
50
|
+
skin_default: {
|
|
51
|
+
meanFreePathColor: [
|
|
52
|
+
1.0,
|
|
53
|
+
0.45,
|
|
54
|
+
0.17
|
|
55
|
+
],
|
|
56
|
+
meanFreePathDistance: 0.92,
|
|
57
|
+
falloffColor: [
|
|
58
|
+
1.0,
|
|
59
|
+
0.39,
|
|
60
|
+
0.25
|
|
61
|
+
],
|
|
62
|
+
strength: 0.82,
|
|
63
|
+
scale: 0.96,
|
|
64
|
+
worldUnitScale: 1,
|
|
65
|
+
boundaryColorBleed: 0.22,
|
|
66
|
+
transmissionTintColor: [
|
|
67
|
+
1,
|
|
68
|
+
0.46,
|
|
69
|
+
0.34
|
|
70
|
+
],
|
|
71
|
+
extinctionScale: 1.06,
|
|
72
|
+
normalScale: 1,
|
|
73
|
+
scatteringDistribution: 0.6
|
|
74
|
+
},
|
|
75
|
+
skin_heavy_makeup: {
|
|
76
|
+
meanFreePathColor: [
|
|
77
|
+
1.0,
|
|
78
|
+
0.33,
|
|
79
|
+
0.11
|
|
80
|
+
],
|
|
81
|
+
meanFreePathDistance: 0.68,
|
|
82
|
+
falloffColor: [
|
|
83
|
+
1.0,
|
|
84
|
+
0.26,
|
|
85
|
+
0.16
|
|
86
|
+
],
|
|
87
|
+
strength: 0.56,
|
|
88
|
+
scale: 0.76,
|
|
89
|
+
worldUnitScale: 0.84,
|
|
90
|
+
boundaryColorBleed: 0.08,
|
|
91
|
+
transmissionTintColor: [
|
|
92
|
+
0.94,
|
|
93
|
+
0.31,
|
|
94
|
+
0.22
|
|
95
|
+
],
|
|
96
|
+
extinctionScale: 1.4,
|
|
97
|
+
normalScale: 1.26,
|
|
98
|
+
scatteringDistribution: 0.5
|
|
99
|
+
},
|
|
100
|
+
wax_backlit: {
|
|
101
|
+
meanFreePathColor: [
|
|
102
|
+
1.0,
|
|
103
|
+
0.68,
|
|
104
|
+
0.36
|
|
105
|
+
],
|
|
106
|
+
meanFreePathDistance: 1.54,
|
|
107
|
+
falloffColor: [
|
|
108
|
+
1.0,
|
|
109
|
+
0.8,
|
|
110
|
+
0.66
|
|
111
|
+
],
|
|
112
|
+
strength: 1.12,
|
|
113
|
+
scale: 1.42,
|
|
114
|
+
worldUnitScale: 1.26,
|
|
115
|
+
boundaryColorBleed: 0.42,
|
|
116
|
+
transmissionTintColor: [
|
|
117
|
+
1,
|
|
118
|
+
0.82,
|
|
119
|
+
0.7
|
|
120
|
+
],
|
|
121
|
+
extinctionScale: 0.78,
|
|
122
|
+
normalScale: 0.92,
|
|
123
|
+
scatteringDistribution: 0.82
|
|
124
|
+
},
|
|
125
|
+
wax_soft: {
|
|
126
|
+
meanFreePathColor: [
|
|
127
|
+
1.0,
|
|
128
|
+
0.72,
|
|
129
|
+
0.38
|
|
130
|
+
],
|
|
131
|
+
meanFreePathDistance: 1.2,
|
|
132
|
+
falloffColor: [
|
|
133
|
+
1.0,
|
|
134
|
+
0.86,
|
|
135
|
+
0.74
|
|
136
|
+
],
|
|
137
|
+
strength: 1.02,
|
|
138
|
+
scale: 1.28,
|
|
139
|
+
worldUnitScale: 1.12,
|
|
140
|
+
boundaryColorBleed: 0.36,
|
|
141
|
+
transmissionTintColor: [
|
|
142
|
+
1,
|
|
143
|
+
0.86,
|
|
144
|
+
0.74
|
|
145
|
+
],
|
|
146
|
+
extinctionScale: 0.86,
|
|
147
|
+
normalScale: 0.98,
|
|
148
|
+
scatteringDistribution: 0.74
|
|
149
|
+
},
|
|
150
|
+
jade_backlit: {
|
|
151
|
+
meanFreePathColor: [
|
|
152
|
+
0.74,
|
|
153
|
+
1.0,
|
|
154
|
+
0.88
|
|
155
|
+
],
|
|
156
|
+
meanFreePathDistance: 0.92,
|
|
157
|
+
falloffColor: [
|
|
158
|
+
0.66,
|
|
159
|
+
0.94,
|
|
160
|
+
0.88
|
|
161
|
+
],
|
|
162
|
+
strength: 0.92,
|
|
163
|
+
scale: 1.14,
|
|
164
|
+
worldUnitScale: 1.06,
|
|
165
|
+
boundaryColorBleed: 0.26,
|
|
166
|
+
transmissionTintColor: [
|
|
167
|
+
0.68,
|
|
168
|
+
0.92,
|
|
169
|
+
0.86
|
|
170
|
+
],
|
|
171
|
+
extinctionScale: 0.92,
|
|
172
|
+
normalScale: 1.02,
|
|
173
|
+
scatteringDistribution: 0.7
|
|
174
|
+
},
|
|
175
|
+
jade_soft: {
|
|
176
|
+
meanFreePathColor: [
|
|
177
|
+
0.68,
|
|
178
|
+
1.0,
|
|
179
|
+
0.84
|
|
180
|
+
],
|
|
181
|
+
meanFreePathDistance: 0.8,
|
|
182
|
+
falloffColor: [
|
|
183
|
+
0.72,
|
|
184
|
+
0.94,
|
|
185
|
+
0.86
|
|
186
|
+
],
|
|
187
|
+
strength: 0.82,
|
|
188
|
+
scale: 1.02,
|
|
189
|
+
worldUnitScale: 0.98,
|
|
190
|
+
boundaryColorBleed: 0.22,
|
|
191
|
+
transmissionTintColor: [
|
|
192
|
+
0.74,
|
|
193
|
+
0.96,
|
|
194
|
+
0.9
|
|
195
|
+
],
|
|
196
|
+
extinctionScale: 1,
|
|
197
|
+
normalScale: 1.04,
|
|
198
|
+
scatteringDistribution: 0.66
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
const SUBSURFACE_PROFILE_PRESET_TINT_BIAS = {
|
|
202
|
+
skin_thin: [
|
|
203
|
+
1,
|
|
204
|
+
0.56,
|
|
205
|
+
0.46
|
|
206
|
+
],
|
|
207
|
+
skin_default: [
|
|
208
|
+
1,
|
|
209
|
+
0.62,
|
|
210
|
+
0.5
|
|
211
|
+
],
|
|
212
|
+
skin_heavy_makeup: [
|
|
213
|
+
1,
|
|
214
|
+
0.5,
|
|
215
|
+
0.42
|
|
216
|
+
],
|
|
217
|
+
wax_backlit: [
|
|
218
|
+
1,
|
|
219
|
+
0.8,
|
|
220
|
+
0.7
|
|
221
|
+
],
|
|
222
|
+
wax_soft: [
|
|
223
|
+
1,
|
|
224
|
+
0.86,
|
|
225
|
+
0.78
|
|
226
|
+
],
|
|
227
|
+
jade_backlit: [
|
|
228
|
+
0.72,
|
|
229
|
+
0.92,
|
|
230
|
+
0.96
|
|
231
|
+
],
|
|
232
|
+
jade_soft: [
|
|
233
|
+
0.68,
|
|
234
|
+
0.96,
|
|
235
|
+
0.88
|
|
236
|
+
]
|
|
237
|
+
};
|
|
238
|
+
const SUBSURFACE_PROFILE_PRESET_RESPONSE = {
|
|
239
|
+
skin_thin: [
|
|
240
|
+
0.08,
|
|
241
|
+
0.12,
|
|
242
|
+
0.06,
|
|
243
|
+
0.12
|
|
244
|
+
],
|
|
245
|
+
skin_default: [
|
|
246
|
+
0.1,
|
|
247
|
+
0.14,
|
|
248
|
+
0.08,
|
|
249
|
+
0.16
|
|
250
|
+
],
|
|
251
|
+
skin_heavy_makeup: [
|
|
252
|
+
0.02,
|
|
253
|
+
0.05,
|
|
254
|
+
-0.02,
|
|
255
|
+
0.01
|
|
256
|
+
],
|
|
257
|
+
wax_backlit: [
|
|
258
|
+
0.12,
|
|
259
|
+
0.2,
|
|
260
|
+
0.26,
|
|
261
|
+
0.24
|
|
262
|
+
],
|
|
263
|
+
wax_soft: [
|
|
264
|
+
0.2,
|
|
265
|
+
0.3,
|
|
266
|
+
0.34,
|
|
267
|
+
0.1
|
|
268
|
+
],
|
|
269
|
+
jade_backlit: [
|
|
270
|
+
0.08,
|
|
271
|
+
0.18,
|
|
272
|
+
0.2,
|
|
273
|
+
0.24
|
|
274
|
+
],
|
|
275
|
+
jade_soft: [
|
|
276
|
+
0.16,
|
|
277
|
+
0.24,
|
|
278
|
+
0.22,
|
|
279
|
+
0.12
|
|
280
|
+
]
|
|
281
|
+
};
|
|
282
|
+
/**
|
|
283
|
+
* Serializable subsurface scattering profile.
|
|
284
|
+
*
|
|
285
|
+
* @remarks
|
|
286
|
+
* The profile stores the channel-dependent scattering radius and falloff used
|
|
287
|
+
* by the screen-space SSS post effect. Materials can share a profile instance
|
|
288
|
+
* to emulate Unreal-style skin profile assets.
|
|
289
|
+
*
|
|
290
|
+
* @public
|
|
291
|
+
*/ class SubsurfaceProfile {
|
|
292
|
+
static _maxProfiles = 255;
|
|
293
|
+
static _profiles = new Array(SubsurfaceProfile._maxProfiles + 1).fill(null);
|
|
294
|
+
static _version = 0;
|
|
295
|
+
static _defaultSkinProfile = null;
|
|
296
|
+
_scatterRadius;
|
|
297
|
+
_falloffColor;
|
|
298
|
+
_meanFreePathColor;
|
|
299
|
+
_transmissionTintColor;
|
|
300
|
+
_preset;
|
|
301
|
+
_meanFreePathDistance;
|
|
302
|
+
_strength;
|
|
303
|
+
_scale;
|
|
304
|
+
_worldUnitScale;
|
|
305
|
+
_boundaryColorBleed;
|
|
306
|
+
_extinctionScale;
|
|
307
|
+
_normalScale;
|
|
308
|
+
_scatteringDistribution;
|
|
309
|
+
_slot;
|
|
310
|
+
_changeListeners;
|
|
311
|
+
/**
|
|
312
|
+
* Creates a subsurface scattering profile initialized with the default skin preset.
|
|
313
|
+
*
|
|
314
|
+
* @public
|
|
315
|
+
*/ constructor(){
|
|
316
|
+
this._scatterRadius = new Vector3(0, 0, 0);
|
|
317
|
+
this._falloffColor = new Vector3(0, 0, 0);
|
|
318
|
+
this._meanFreePathColor = new Vector3(0, 0, 0);
|
|
319
|
+
this._transmissionTintColor = new Vector3(0, 0, 0);
|
|
320
|
+
this._preset = 'skin_default';
|
|
321
|
+
this._meanFreePathDistance = 0;
|
|
322
|
+
this._strength = 0;
|
|
323
|
+
this._scale = 0;
|
|
324
|
+
this._worldUnitScale = 1;
|
|
325
|
+
this._boundaryColorBleed = 0;
|
|
326
|
+
this._extinctionScale = 1;
|
|
327
|
+
this._normalScale = 1;
|
|
328
|
+
this._scatteringDistribution = 0.65;
|
|
329
|
+
this._changeListeners = new Set();
|
|
330
|
+
this._slot = SubsurfaceProfile.allocateSlot(this);
|
|
331
|
+
this.applyPresetTemplate(this._preset, false);
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Gets the global profile data version.
|
|
335
|
+
*
|
|
336
|
+
* @remarks
|
|
337
|
+
* The value is incremented whenever a profile slot is allocated or profile
|
|
338
|
+
* data changes, allowing render systems to refresh cached profile textures.
|
|
339
|
+
*
|
|
340
|
+
* @public
|
|
341
|
+
*/ static get version() {
|
|
342
|
+
return this._version;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Gets the profile assigned to a packed profile slot.
|
|
346
|
+
*
|
|
347
|
+
* @param slot - The 1-based profile slot index.
|
|
348
|
+
* @returns The profile assigned to the slot, or `null` if the slot is invalid or unused.
|
|
349
|
+
*
|
|
350
|
+
* @public
|
|
351
|
+
*/ static getProfileBySlot(slot) {
|
|
352
|
+
return slot > 0 && slot < this._profiles.length ? this._profiles[slot] : null;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Gets the shared default skin subsurface profile.
|
|
356
|
+
*
|
|
357
|
+
* @returns The lazily-created default skin profile.
|
|
358
|
+
*
|
|
359
|
+
* @public
|
|
360
|
+
*/ static getDefaultSkinProfile() {
|
|
361
|
+
if (!this._defaultSkinProfile) {
|
|
362
|
+
this._defaultSkinProfile = new SubsurfaceProfile();
|
|
363
|
+
}
|
|
364
|
+
return this._defaultSkinProfile;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Gets the preset tint bias used by the screen-space transmission model.
|
|
368
|
+
*
|
|
369
|
+
* @param index - The packed canonical preset index.
|
|
370
|
+
* @returns The RGB tint bias for the preset, or white when the index is unknown.
|
|
371
|
+
*
|
|
372
|
+
* @public
|
|
373
|
+
*/ static getPresetTintBiasByIndex(index) {
|
|
374
|
+
return SUBSURFACE_PROFILE_PRESET_TINT_BIAS[this.getPresetNameByIndex(index)] ?? [
|
|
375
|
+
1,
|
|
376
|
+
1,
|
|
377
|
+
1
|
|
378
|
+
];
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Gets the preset transmission response used by the screen-space SSS pass.
|
|
382
|
+
*
|
|
383
|
+
* @param index - The packed canonical preset index.
|
|
384
|
+
* @returns The four-component transmission response for the preset.
|
|
385
|
+
*
|
|
386
|
+
* @public
|
|
387
|
+
*/ static getPresetResponseByIndex(index) {
|
|
388
|
+
return SUBSURFACE_PROFILE_PRESET_RESPONSE[this.getPresetNameByIndex(index)] ?? [
|
|
389
|
+
0,
|
|
390
|
+
0,
|
|
391
|
+
0,
|
|
392
|
+
0
|
|
393
|
+
];
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Computes the effective tint bias from the preset and current profile settings.
|
|
397
|
+
*
|
|
398
|
+
* @returns The derived RGB tint bias used for transmission tinting.
|
|
399
|
+
*
|
|
400
|
+
* @public
|
|
401
|
+
*/ getDerivedTintBias() {
|
|
402
|
+
const base = SUBSURFACE_PROFILE_PRESET_TINT_BIAS[this._preset] ?? [
|
|
403
|
+
1,
|
|
404
|
+
1,
|
|
405
|
+
1
|
|
406
|
+
];
|
|
407
|
+
const factors = this.getDerivedProfileFactors();
|
|
408
|
+
const derived = [
|
|
409
|
+
this.clamp01(0.78 + factors.warmBias * 0.26 - factors.coolBias * 0.16 + factors.boundaryNorm * 0.04),
|
|
410
|
+
this.clamp01(0.3 + factors.meanFreePathColor[1] * 0.24 + factors.transmissionTintColor[1] * 0.28 + factors.distanceNorm * 0.08 + factors.scaleNorm * 0.05 + factors.boundaryNorm * 0.08 + factors.coolBias * 0.06),
|
|
411
|
+
this.clamp01(0.14 + factors.meanFreePathColor[2] * 0.22 + factors.transmissionTintColor[2] * 0.32 + factors.distanceNorm * 0.06 + factors.boundaryNorm * 0.06 + factors.coolBias * 0.12 - factors.warmBias * 0.06)
|
|
412
|
+
];
|
|
413
|
+
const blend = this.clampRange(0.26 + factors.radiusNorm * 0.16 + factors.scaleNorm * 0.1 + factors.strengthNorm * 0.08, 0.25, 0.88);
|
|
414
|
+
return [
|
|
415
|
+
this.mixNumber(base[0], derived[0], blend),
|
|
416
|
+
this.mixNumber(base[1], derived[1], blend),
|
|
417
|
+
this.mixNumber(base[2], derived[2], blend)
|
|
418
|
+
];
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Computes the effective transmission response from the preset and current profile settings.
|
|
422
|
+
*
|
|
423
|
+
* @returns The derived transmission response packed as four scalar channels.
|
|
424
|
+
*
|
|
425
|
+
* @public
|
|
426
|
+
*/ getDerivedTransmissionResponse() {
|
|
427
|
+
const base = SUBSURFACE_PROFILE_PRESET_RESPONSE[this._preset] ?? [
|
|
428
|
+
0,
|
|
429
|
+
0,
|
|
430
|
+
0,
|
|
431
|
+
0
|
|
432
|
+
];
|
|
433
|
+
const factors = this.getDerivedProfileFactors();
|
|
434
|
+
const blend = this.clampRange(0.32 + factors.distanceNorm * 0.18 + factors.scaleNorm * 0.12 + factors.strengthNorm * 0.1 + factors.boundaryNorm * 0.06, 0.28, 0.9);
|
|
435
|
+
const derived = [
|
|
436
|
+
this.clampRange(-0.06 + factors.radiusNorm * 0.08 + factors.distanceNorm * 0.08 + factors.strengthNorm * 0.05 + factors.distributionNorm * 0.04 + factors.boundaryNorm * 0.05 + factors.extinctionSoftness * 0.03, -0.25, 0.45),
|
|
437
|
+
this.clampRange(0.02 + factors.radiusNorm * 0.1 + factors.scaleNorm * 0.08 + factors.worldScaleNorm * 0.04 + factors.distributionNorm * 0.08 + factors.extinctionSoftness * 0.06, -0.25, 0.45),
|
|
438
|
+
this.clampRange(-0.08 + factors.strengthNorm * 0.12 + factors.scaleNorm * 0.08 + factors.extinctionSoftness * 0.12 + factors.boundaryNorm * 0.06 + factors.warmBias * 0.05 - factors.coolBias * 0.04, -0.25, 0.45),
|
|
439
|
+
this.clampRange(-0.02 + factors.radiusNorm * 0.12 + factors.scaleNorm * 0.08 + factors.strengthNorm * 0.06 + factors.boundaryNorm * 0.06 + factors.extinctionSoftness * 0.16 + factors.warmBias * 0.07 + factors.transmissionTintColor[0] * 0.04, -0.25, 0.5)
|
|
440
|
+
];
|
|
441
|
+
return [
|
|
442
|
+
this.clampRange(this.mixNumber(base[0], derived[0], blend), -0.25, 0.45),
|
|
443
|
+
this.clampRange(this.mixNumber(base[1], derived[1], blend), -0.25, 0.45),
|
|
444
|
+
this.clampRange(this.mixNumber(base[2], derived[2], blend), -0.25, 0.45),
|
|
445
|
+
this.clampRange(this.mixNumber(base[3], derived[3], blend), -0.25, 0.5)
|
|
446
|
+
];
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Gets the 1-based profile slot used when encoding this profile into SSS buffers.
|
|
450
|
+
*
|
|
451
|
+
* @public
|
|
452
|
+
*/ get slot() {
|
|
453
|
+
return this._slot;
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Gets or sets the RGB scatter radius.
|
|
457
|
+
*
|
|
458
|
+
* @remarks
|
|
459
|
+
* Assigning a radius also updates the mean-free-path authoring controls.
|
|
460
|
+
*
|
|
461
|
+
* @public
|
|
462
|
+
*/ get scatterRadius() {
|
|
463
|
+
return this._scatterRadius;
|
|
464
|
+
}
|
|
465
|
+
set scatterRadius(val) {
|
|
466
|
+
if (!val.equalsTo(this._scatterRadius)) {
|
|
467
|
+
this._scatterRadius.set(val);
|
|
468
|
+
this.syncMeanFreePathFromScatterRadius();
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Gets or sets the channel falloff color used by the diffusion kernel.
|
|
473
|
+
*
|
|
474
|
+
* @public
|
|
475
|
+
*/ get falloffColor() {
|
|
476
|
+
return this._falloffColor;
|
|
477
|
+
}
|
|
478
|
+
set falloffColor(val) {
|
|
479
|
+
if (!val.equalsTo(this._falloffColor)) {
|
|
480
|
+
this._falloffColor.set(val);
|
|
481
|
+
this.markDirty();
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Mean free path color used to derive channel-dependent scatter radius.
|
|
486
|
+
*
|
|
487
|
+
* @remarks
|
|
488
|
+
* This is a more UE-like authoring control that keeps the existing radius-
|
|
489
|
+
* based implementation, while letting tools expose a color + distance pair.
|
|
490
|
+
*
|
|
491
|
+
* @public
|
|
492
|
+
*/ get meanFreePathColor() {
|
|
493
|
+
return this._meanFreePathColor;
|
|
494
|
+
}
|
|
495
|
+
set meanFreePathColor(val) {
|
|
496
|
+
if (!val.equalsTo(this._meanFreePathColor)) {
|
|
497
|
+
this._meanFreePathColor.set(val);
|
|
498
|
+
this.syncScatterRadiusFromMeanFreePath();
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Gets or sets the mean free path distance used to derive the absolute scatter radius.
|
|
503
|
+
*
|
|
504
|
+
* @public
|
|
505
|
+
*/ get meanFreePathDistance() {
|
|
506
|
+
return this._meanFreePathDistance;
|
|
507
|
+
}
|
|
508
|
+
set meanFreePathDistance(val) {
|
|
509
|
+
const next = Math.max(0, val ?? 0);
|
|
510
|
+
if (next !== this._meanFreePathDistance) {
|
|
511
|
+
this._meanFreePathDistance = next;
|
|
512
|
+
this.syncScatterRadiusFromMeanFreePath();
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Gets or sets the active subsurface profile preset.
|
|
517
|
+
*
|
|
518
|
+
* @remarks
|
|
519
|
+
* Assigning a preset applies its template values to the profile. Alias preset
|
|
520
|
+
* names are resolved to their canonical preset.
|
|
521
|
+
*
|
|
522
|
+
* @public
|
|
523
|
+
*/ get preset() {
|
|
524
|
+
return this._preset;
|
|
525
|
+
}
|
|
526
|
+
set preset(val) {
|
|
527
|
+
const next = SubsurfaceProfile.resolvePreset(val);
|
|
528
|
+
if (next !== this._preset) {
|
|
529
|
+
this._preset = next;
|
|
530
|
+
this.applyPresetTemplate(next);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
/**
|
|
534
|
+
* Gets the packed canonical preset index.
|
|
535
|
+
*
|
|
536
|
+
* @public
|
|
537
|
+
*/ get presetIndex() {
|
|
538
|
+
return SUBSURFACE_PROFILE_PRESET_INDEX[this._preset] ?? 0;
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Gets or sets the SSS strength multiplier.
|
|
542
|
+
*
|
|
543
|
+
* @public
|
|
544
|
+
*/ get strength() {
|
|
545
|
+
return this._strength;
|
|
546
|
+
}
|
|
547
|
+
set strength(val) {
|
|
548
|
+
if (val !== this._strength) {
|
|
549
|
+
this._strength = val;
|
|
550
|
+
this.markDirty();
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Gets or sets the screen-space scatter width scale.
|
|
555
|
+
*
|
|
556
|
+
* @public
|
|
557
|
+
*/ get scale() {
|
|
558
|
+
return this._scale;
|
|
559
|
+
}
|
|
560
|
+
set scale(val) {
|
|
561
|
+
if (val !== this._scale) {
|
|
562
|
+
this._scale = val;
|
|
563
|
+
this.markDirty();
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Gets or sets the world-unit scale used when converting profile radii.
|
|
568
|
+
*
|
|
569
|
+
* @public
|
|
570
|
+
*/ get worldUnitScale() {
|
|
571
|
+
return this._worldUnitScale;
|
|
572
|
+
}
|
|
573
|
+
set worldUnitScale(val) {
|
|
574
|
+
const next = Math.max(0.05, val ?? 0.05);
|
|
575
|
+
if (next !== this._worldUnitScale) {
|
|
576
|
+
this._worldUnitScale = next;
|
|
577
|
+
this.markDirty();
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Gets or sets the amount of color bleeding preserved near SSS boundaries.
|
|
582
|
+
*
|
|
583
|
+
* @remarks
|
|
584
|
+
* Values are clamped to the `[0, 1]` range.
|
|
585
|
+
*
|
|
586
|
+
* @public
|
|
587
|
+
*/ get boundaryColorBleed() {
|
|
588
|
+
return this._boundaryColorBleed;
|
|
589
|
+
}
|
|
590
|
+
set boundaryColorBleed(val) {
|
|
591
|
+
const next = this.clamp01(val ?? 0);
|
|
592
|
+
if (next !== this._boundaryColorBleed) {
|
|
593
|
+
this._boundaryColorBleed = next;
|
|
594
|
+
this.markDirty();
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Gets or sets the RGB tint applied to transmitted subsurface light.
|
|
599
|
+
*
|
|
600
|
+
* @public
|
|
601
|
+
*/ get transmissionTintColor() {
|
|
602
|
+
return this._transmissionTintColor;
|
|
603
|
+
}
|
|
604
|
+
set transmissionTintColor(val) {
|
|
605
|
+
if (!val.equalsTo(this._transmissionTintColor)) {
|
|
606
|
+
this._transmissionTintColor.set(val);
|
|
607
|
+
this.markDirty();
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Gets or sets the extinction multiplier used by transmission attenuation.
|
|
612
|
+
*
|
|
613
|
+
* @remarks
|
|
614
|
+
* Values are clamped to zero or greater.
|
|
615
|
+
*
|
|
616
|
+
* @public
|
|
617
|
+
*/ get extinctionScale() {
|
|
618
|
+
return this._extinctionScale;
|
|
619
|
+
}
|
|
620
|
+
set extinctionScale(val) {
|
|
621
|
+
const next = Math.max(0, val ?? 0);
|
|
622
|
+
if (next !== this._extinctionScale) {
|
|
623
|
+
this._extinctionScale = next;
|
|
624
|
+
this.markDirty();
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Gets or sets the normal sensitivity scale used by SSS filtering.
|
|
629
|
+
*
|
|
630
|
+
* @remarks
|
|
631
|
+
* Values are clamped to zero or greater.
|
|
632
|
+
*
|
|
633
|
+
* @public
|
|
634
|
+
*/ get normalScale() {
|
|
635
|
+
return this._normalScale;
|
|
636
|
+
}
|
|
637
|
+
set normalScale(val) {
|
|
638
|
+
const next = Math.max(0, val ?? 0);
|
|
639
|
+
if (next !== this._normalScale) {
|
|
640
|
+
this._normalScale = next;
|
|
641
|
+
this.markDirty();
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* Gets or sets the scattering distribution blend.
|
|
646
|
+
*
|
|
647
|
+
* @remarks
|
|
648
|
+
* Values are clamped to the `[0, 1]` range.
|
|
649
|
+
*
|
|
650
|
+
* @public
|
|
651
|
+
*/ get scatteringDistribution() {
|
|
652
|
+
return this._scatteringDistribution;
|
|
653
|
+
}
|
|
654
|
+
set scatteringDistribution(val) {
|
|
655
|
+
const next = this.clamp01(val ?? 0);
|
|
656
|
+
if (next !== this._scatteringDistribution) {
|
|
657
|
+
this._scatteringDistribution = next;
|
|
658
|
+
this.markDirty();
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* Adds a listener that is invoked whenever this profile changes.
|
|
663
|
+
*
|
|
664
|
+
* @param listener - The callback to invoke after profile data changes.
|
|
665
|
+
*
|
|
666
|
+
* @public
|
|
667
|
+
*/ addChangeListener(listener) {
|
|
668
|
+
this._changeListeners.add(listener);
|
|
669
|
+
}
|
|
670
|
+
/**
|
|
671
|
+
* Removes a previously registered profile change listener.
|
|
672
|
+
*
|
|
673
|
+
* @param listener - The callback to remove.
|
|
674
|
+
*
|
|
675
|
+
* @public
|
|
676
|
+
*/ removeChangeListener(listener) {
|
|
677
|
+
this._changeListeners.delete(listener);
|
|
678
|
+
}
|
|
679
|
+
static allocateSlot(profile) {
|
|
680
|
+
for(let i = 1; i < this._profiles.length; i++){
|
|
681
|
+
if (!this._profiles[i]) {
|
|
682
|
+
this._profiles[i] = profile;
|
|
683
|
+
this._version++;
|
|
684
|
+
return i;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
throw new Error('SubsurfaceProfile limit exceeded');
|
|
688
|
+
}
|
|
689
|
+
markDirty() {
|
|
690
|
+
SubsurfaceProfile._version++;
|
|
691
|
+
this._changeListeners.forEach((listener)=>listener());
|
|
692
|
+
}
|
|
693
|
+
static resolvePreset(preset) {
|
|
694
|
+
return SUBSURFACE_PROFILE_PRESET_ALIAS[preset ?? 'skin_default'] ?? 'skin_default';
|
|
695
|
+
}
|
|
696
|
+
static getPresetNameByIndex(index) {
|
|
697
|
+
for (const [name, presetIndex] of Object.entries(SUBSURFACE_PROFILE_PRESET_INDEX)){
|
|
698
|
+
if (presetIndex === index) {
|
|
699
|
+
return name;
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
return 'skin_default';
|
|
703
|
+
}
|
|
704
|
+
applyPresetTemplate(preset, markDirty = true) {
|
|
705
|
+
const template = SUBSURFACE_PROFILE_PRESET_TEMPLATE[preset] ?? SUBSURFACE_PROFILE_PRESET_TEMPLATE.skin_default;
|
|
706
|
+
this._meanFreePathColor.setXYZ(template.meanFreePathColor[0], template.meanFreePathColor[1], template.meanFreePathColor[2]);
|
|
707
|
+
this._meanFreePathDistance = template.meanFreePathDistance;
|
|
708
|
+
this._strength = template.strength;
|
|
709
|
+
this._scale = template.scale;
|
|
710
|
+
this._worldUnitScale = template.worldUnitScale;
|
|
711
|
+
this._boundaryColorBleed = template.boundaryColorBleed;
|
|
712
|
+
this._transmissionTintColor.setXYZ(template.transmissionTintColor[0], template.transmissionTintColor[1], template.transmissionTintColor[2]);
|
|
713
|
+
this._extinctionScale = template.extinctionScale;
|
|
714
|
+
this._normalScale = template.normalScale;
|
|
715
|
+
this._scatteringDistribution = template.scatteringDistribution;
|
|
716
|
+
this.syncScatterRadiusFromMeanFreePath(false);
|
|
717
|
+
if (markDirty) {
|
|
718
|
+
this.markDirty();
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
syncMeanFreePathFromScatterRadius(markDirty = true) {
|
|
722
|
+
const maxRadius = Math.max(this._scatterRadius.x, this._scatterRadius.y, this._scatterRadius.z);
|
|
723
|
+
if (maxRadius > 1e-5) {
|
|
724
|
+
this._meanFreePathDistance = maxRadius;
|
|
725
|
+
this._meanFreePathColor.setXYZ(this._scatterRadius.x / maxRadius, this._scatterRadius.y / maxRadius, this._scatterRadius.z / maxRadius);
|
|
726
|
+
} else {
|
|
727
|
+
this._meanFreePathDistance = 0;
|
|
728
|
+
this._meanFreePathColor.setXYZ(0, 0, 0);
|
|
729
|
+
}
|
|
730
|
+
this.syncFalloffFromMeanFreePath(false);
|
|
731
|
+
if (markDirty) {
|
|
732
|
+
this.markDirty();
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
syncScatterRadiusFromMeanFreePath(markDirty = true) {
|
|
736
|
+
const distance = Math.max(0, this._meanFreePathDistance);
|
|
737
|
+
this._scatterRadius.setXYZ(Math.max(0, this._meanFreePathColor.x) * distance, Math.max(0, this._meanFreePathColor.y) * distance, Math.max(0, this._meanFreePathColor.z) * distance);
|
|
738
|
+
this.syncFalloffFromMeanFreePath(false);
|
|
739
|
+
if (markDirty) {
|
|
740
|
+
this.markDirty();
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
syncFalloffFromMeanFreePath(markDirty = true) {
|
|
744
|
+
const base = SUBSURFACE_PROFILE_PRESET_TEMPLATE[this._preset]?.falloffColor ?? SUBSURFACE_PROFILE_PRESET_TEMPLATE.skin_default.falloffColor;
|
|
745
|
+
const factors = this.getDerivedProfileFactors();
|
|
746
|
+
const derivedG = this.clamp01(0.12 + factors.meanFreePathColor[1] * 0.4 + factors.transmissionTintColor[1] * 0.12 + factors.distanceNorm * 0.05 + factors.scaleNorm * 0.05 + factors.distributionNorm * 0.05 - (1 - factors.extinctionSoftness) * 0.04);
|
|
747
|
+
const derivedB = this.clamp01(0.04 + factors.meanFreePathColor[2] * 0.32 + factors.transmissionTintColor[2] * 0.18 + factors.distanceNorm * 0.04 + factors.boundaryNorm * 0.05 + factors.coolBias * 0.08 - factors.warmBias * 0.04);
|
|
748
|
+
const blend = this.clampRange(0.24 + factors.distanceNorm * 0.16 + factors.scaleNorm * 0.12 + factors.strengthNorm * 0.08, 0.22, 0.82);
|
|
749
|
+
this._falloffColor.setXYZ(1, this.mixNumber(base[1], derivedG, blend), this.mixNumber(base[2], derivedB, blend));
|
|
750
|
+
if (markDirty) {
|
|
751
|
+
this.markDirty();
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
getNormalizedTransmissionTintColor() {
|
|
755
|
+
const maxChannel = Math.max(this._transmissionTintColor.x, this._transmissionTintColor.y, this._transmissionTintColor.z, 1e-5);
|
|
756
|
+
return [
|
|
757
|
+
Math.max(0, this._transmissionTintColor.x) / maxChannel,
|
|
758
|
+
Math.max(0, this._transmissionTintColor.y) / maxChannel,
|
|
759
|
+
Math.max(0, this._transmissionTintColor.z) / maxChannel
|
|
760
|
+
];
|
|
761
|
+
}
|
|
762
|
+
getDerivedProfileFactors() {
|
|
763
|
+
const meanFreePathColor = this.getNormalizedMeanFreePathColor();
|
|
764
|
+
const transmissionTintColor = this.getNormalizedTransmissionTintColor();
|
|
765
|
+
const maxRadius = Math.max(this._scatterRadius.x, this._scatterRadius.y, this._scatterRadius.z);
|
|
766
|
+
const radiusNorm = this.clampRange(maxRadius / 1.35, 0, 1.5);
|
|
767
|
+
const distanceNorm = this.clampRange(this._meanFreePathDistance / 1.25, 0, 1.5);
|
|
768
|
+
const scaleNorm = this.clampRange(this._scale / 1.35, 0, 1.5);
|
|
769
|
+
const strengthNorm = this.clampRange(this._strength / 1.2, 0, 1.5);
|
|
770
|
+
const worldScaleNorm = this.clampRange(this._worldUnitScale / 1.25, 0, 1.5);
|
|
771
|
+
const boundaryNorm = this.clamp01(this._boundaryColorBleed);
|
|
772
|
+
const distributionNorm = this.clamp01(this._scatteringDistribution);
|
|
773
|
+
const extinctionWeight = this.clampRange(1 / Math.max(this._extinctionScale, 0.35), 0.25, 1.35);
|
|
774
|
+
const extinctionSoftness = this.clamp01((extinctionWeight - 0.25) / 1.1);
|
|
775
|
+
const warmBias = this.clamp01(0.5 + (meanFreePathColor[0] - Math.max(meanFreePathColor[1], meanFreePathColor[2]) * 0.72) * 0.95 + (transmissionTintColor[0] - Math.max(transmissionTintColor[1], transmissionTintColor[2]) * 0.78) * 0.7);
|
|
776
|
+
const coolBias = this.clamp01(0.32 + (transmissionTintColor[2] - transmissionTintColor[0] * 0.55) * 0.55 + (meanFreePathColor[2] - meanFreePathColor[0] * 0.65) * 0.45);
|
|
777
|
+
return {
|
|
778
|
+
meanFreePathColor,
|
|
779
|
+
transmissionTintColor,
|
|
780
|
+
radiusNorm,
|
|
781
|
+
distanceNorm,
|
|
782
|
+
scaleNorm,
|
|
783
|
+
strengthNorm,
|
|
784
|
+
worldScaleNorm,
|
|
785
|
+
boundaryNorm,
|
|
786
|
+
distributionNorm,
|
|
787
|
+
extinctionSoftness,
|
|
788
|
+
warmBias,
|
|
789
|
+
coolBias
|
|
790
|
+
};
|
|
791
|
+
}
|
|
792
|
+
getNormalizedMeanFreePathColor() {
|
|
793
|
+
const maxChannel = Math.max(this._meanFreePathColor.x, this._meanFreePathColor.y, this._meanFreePathColor.z, 1e-5);
|
|
794
|
+
return [
|
|
795
|
+
Math.max(0, this._meanFreePathColor.x) / maxChannel,
|
|
796
|
+
Math.max(0, this._meanFreePathColor.y) / maxChannel,
|
|
797
|
+
Math.max(0, this._meanFreePathColor.z) / maxChannel
|
|
798
|
+
];
|
|
799
|
+
}
|
|
800
|
+
mixNumber(a, b, t) {
|
|
801
|
+
return a * (1 - t) + b * t;
|
|
802
|
+
}
|
|
803
|
+
clampRange(value, minValue, maxValue) {
|
|
804
|
+
return Math.max(minValue, Math.min(maxValue, value));
|
|
805
|
+
}
|
|
806
|
+
clamp01(value) {
|
|
807
|
+
return Math.max(0, Math.min(1, value));
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
export { SubsurfaceProfile };
|
|
812
|
+
//# sourceMappingURL=subsurfaceprofile.js.map
|