@zephyr3d/scene 0.9.26 → 0.10.0
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/README.md +60 -27
- package/dist/animation/animation_bank.js +634 -0
- package/dist/animation/animation_bank.js.map +1 -0
- package/dist/animation/animation_bank_gpu.js +256 -0
- package/dist/animation/animation_bank_gpu.js.map +1 -0
- package/dist/animation/animationset.js +146 -30
- package/dist/animation/animationset.js.map +1 -1
- package/dist/animation/cloth/gpu_cloth_component.js +406 -0
- package/dist/animation/cloth/gpu_cloth_component.js.map +1 -0
- package/dist/animation/cloth/gpu_cloth_system.js +332 -202
- package/dist/animation/cloth/gpu_cloth_system.js.map +1 -1
- package/dist/animation/gpu_animation_driver.js +289 -0
- package/dist/animation/gpu_animation_driver.js.map +1 -0
- package/dist/animation/joint_dynamics/collision.js +112 -1
- package/dist/animation/joint_dynamics/collision.js.map +1 -1
- package/dist/animation/joint_dynamics/controller.js +6 -0
- package/dist/animation/joint_dynamics/controller.js.map +1 -1
- package/dist/animation/joint_dynamics/joint_dynamics_system.js +11 -0
- package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
- package/dist/animation/joint_dynamics/solver.js +50 -12
- package/dist/animation/joint_dynamics/solver.js.map +1 -1
- package/dist/animation/joint_dynamics/types.js.map +1 -1
- package/dist/animation/skeleton.js +300 -56
- package/dist/animation/skeleton.js.map +1 -1
- package/dist/animation/skin_palette_atlas.js +252 -0
- package/dist/animation/skin_palette_atlas.js.map +1 -0
- package/dist/animation/spring/multi_chain_spring_system.js +298 -38
- package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
- package/dist/animation/spring/spring_chain.js +2 -0
- package/dist/animation/spring/spring_chain.js.map +1 -1
- package/dist/animation/spring/spring_collider.js +159 -21
- package/dist/animation/spring/spring_collider.js.map +1 -1
- package/dist/animation/spring/spring_particle.js +1 -0
- package/dist/animation/spring/spring_particle.js.map +1 -1
- package/dist/animation/spring/spring_solver.js +173 -0
- package/dist/animation/spring/spring_solver.js.map +1 -0
- package/dist/animation/spring/spring_system.js +249 -24
- package/dist/animation/spring/spring_system.js.map +1 -1
- package/dist/animation/spring_modifier.js +32 -1
- package/dist/animation/spring_modifier.js.map +1 -1
- package/dist/app/app.js +26 -0
- package/dist/app/app.js.map +1 -1
- package/dist/app/engine.js +86 -15
- package/dist/app/engine.js.map +1 -1
- package/dist/app/gamepad.js +191 -0
- package/dist/app/gamepad.js.map +1 -0
- package/dist/app/inputactions.js +271 -0
- package/dist/app/inputactions.js.map +1 -0
- package/dist/app/inputmgr.js +331 -22
- package/dist/app/inputmgr.js.map +1 -1
- package/dist/app/loading.js +138 -0
- package/dist/app/loading.js.map +1 -0
- package/dist/app/pipelinecache.js +209 -0
- package/dist/app/pipelinecache.js.map +1 -0
- package/dist/app/runtimescript.js +25 -0
- package/dist/app/runtimescript.js.map +1 -1
- package/dist/app/scriptingsystem.js +54 -0
- package/dist/app/scriptingsystem.js.map +1 -1
- package/dist/app/scriptregistry.js +7 -2
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/asset_manifest.js +59 -0
- package/dist/asset/asset_manifest.js.map +1 -0
- package/dist/asset/asset_preload.js +258 -0
- package/dist/asset/asset_preload.js.map +1 -0
- package/dist/asset/assetmanager.js +117 -65
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/loaders/ktx2/basis/LICENSE +201 -0
- package/dist/asset/loaders/ktx2/basis/basis_transcoder.js +2 -0
- package/dist/asset/loaders/ktx2/basis/basis_transcoder.wasm +0 -0
- package/dist/asset/loaders/ktx2/basis_location.js +17 -0
- package/dist/asset/loaders/ktx2/basis_location.js.map +1 -0
- package/dist/asset/loaders/ktx2/ktx2_loader.js +88 -0
- package/dist/asset/loaders/ktx2/ktx2_loader.js.map +1 -0
- package/dist/asset/loaders/ktx2/ktx2_targets.js +118 -0
- package/dist/asset/loaders/ktx2/ktx2_targets.js.map +1 -0
- package/dist/asset/loaders/ktx2/transcoder_pool.js +259 -0
- package/dist/asset/loaders/ktx2/transcoder_pool.js.map +1 -0
- package/dist/asset/mesh_lod_builder.js +104 -0
- package/dist/asset/mesh_lod_builder.js.map +1 -0
- package/dist/asset/mesh_settings.js +111 -0
- package/dist/asset/mesh_settings.js.map +1 -0
- package/dist/asset/meshopt_decoder.js +18 -0
- package/dist/asset/meshopt_decoder.js.map +1 -0
- package/dist/asset/meshopt_simplifier.js +26 -0
- package/dist/asset/meshopt_simplifier.js.map +1 -0
- package/dist/asset/model.js +177 -3
- package/dist/asset/model.js.map +1 -1
- package/dist/asset/texture_settings.js +231 -0
- package/dist/asset/texture_settings.js.map +1 -0
- package/dist/asset/zmsh_binary.js +131 -0
- package/dist/asset/zmsh_binary.js.map +1 -0
- package/dist/asset/zsdf_binary.js +111 -0
- package/dist/asset/zsdf_binary.js.map +1 -0
- package/dist/blitter/bilateralblur.js +1 -2
- package/dist/blitter/bilateralblur.js.map +1 -1
- package/dist/blitter/gaussianblur.js +1 -6
- package/dist/blitter/gaussianblur.js.map +1 -1
- package/dist/camera/base.js +31 -10
- package/dist/camera/base.js.map +1 -1
- package/dist/camera/camera.js +178 -200
- package/dist/camera/camera.js.map +1 -1
- package/dist/camera/follow.js +342 -0
- package/dist/camera/follow.js.map +1 -0
- package/dist/camera/fps.js +9 -7
- package/dist/camera/fps.js.map +1 -1
- package/dist/camera/orbit.js +46 -19
- package/dist/camera/orbit.js.map +1 -1
- package/dist/index.d.ts +30475 -19865
- package/dist/index.js +67 -12
- package/dist/index.js.map +1 -1
- package/dist/material/blinn.js +3 -0
- package/dist/material/blinn.js.map +1 -1
- package/dist/material/eye.js +1 -1
- package/dist/material/eye.js.map +1 -1
- package/dist/material/hair.js +2 -3
- package/dist/material/hair.js.map +1 -1
- package/dist/material/hairstrand.js +235 -235
- package/dist/material/hairstrand.js.map +1 -1
- package/dist/material/lambert.js +4 -1
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/material.js +362 -300
- package/dist/material/material.js.map +1 -1
- package/dist/material/meshmaterial.js +118 -45
- package/dist/material/meshmaterial.js.map +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
- package/dist/material/mixins/lightmodel/lambert.js +1 -1
- package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +34 -61
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +16 -2
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js +2 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
- package/dist/material/mixins/lit.js +223 -83
- package/dist/material/mixins/lit.js.map +1 -1
- package/dist/material/mixins/pbr/common.js +31 -206
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/material/mtoon.js +1 -1
- package/dist/material/mtoon.js.map +1 -1
- package/dist/material/pbrmr.js +3 -0
- package/dist/material/pbrmr.js.map +1 -1
- package/dist/material/pbrsg.js +3 -0
- package/dist/material/pbrsg.js.map +1 -1
- package/dist/material/sdf_debug.js +78 -0
- package/dist/material/sdf_debug.js.map +1 -0
- package/dist/material/shader/helper.js +733 -190
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/shader/terrain_blend.js +204 -43
- package/dist/material/shader/terrain_blend.js.map +1 -1
- package/dist/material/skin.js +331 -297
- package/dist/material/skin.js.map +1 -1
- package/dist/material/skinprofile.js +1058 -0
- package/dist/material/skinprofile.js.map +1 -0
- package/dist/material/sss.js +353 -0
- package/dist/material/sss.js.map +1 -0
- package/dist/material/sss_kernel.js +265 -0
- package/dist/material/sss_kernel.js.map +1 -0
- package/dist/material/sssprofile.js +879 -0
- package/dist/material/sssprofile.js.map +1 -0
- package/dist/material/subsurfaceprofile.js +4 -8
- package/dist/material/subsurfaceprofile.js.map +1 -1
- package/dist/material/terrain-cm.js +464 -188
- package/dist/material/terrain-cm.js.map +1 -1
- package/dist/material/unlit.js +3 -0
- package/dist/material/unlit.js.map +1 -1
- package/dist/material/water.js +2009 -201
- package/dist/material/water.js.map +1 -1
- package/dist/node_modules/meshoptimizer/LICENSE +21 -0
- package/dist/node_modules/meshoptimizer/meshopt_decoder.js +197 -0
- package/dist/node_modules/meshoptimizer/meshopt_decoder.js.map +1 -0
- package/dist/node_modules/meshoptimizer/meshopt_simplifier.js +677 -0
- package/dist/node_modules/meshoptimizer/meshopt_simplifier.js.map +1 -0
- package/dist/physics/character.js +226 -0
- package/dist/physics/character.js.map +1 -0
- package/dist/physics/collider.js +209 -0
- package/dist/physics/collider.js.map +1 -0
- package/dist/physics/events.js +79 -0
- package/dist/physics/events.js.map +1 -0
- package/dist/physics/joint.js +272 -0
- package/dist/physics/joint.js.map +1 -0
- package/dist/physics/node_physics.js +234 -0
- package/dist/physics/node_physics.js.map +1 -0
- package/dist/physics/part.js +91 -0
- package/dist/physics/part.js.map +1 -0
- package/dist/physics/rigid_body.js +379 -0
- package/dist/physics/rigid_body.js.map +1 -0
- package/dist/physics/vehicle.js +335 -0
- package/dist/physics/vehicle.js.map +1 -0
- package/dist/physics/world.js +25 -0
- package/dist/physics/world.js.map +1 -0
- package/dist/posteffect/bloom.js +49 -14
- package/dist/posteffect/bloom.js.map +1 -1
- package/dist/posteffect/motionblur.js +668 -63
- package/dist/posteffect/motionblur.js.map +1 -1
- package/dist/posteffect/posteffect.js +12 -1
- package/dist/posteffect/posteffect.js.map +1 -1
- package/dist/posteffect/postsss.js +572 -0
- package/dist/posteffect/postsss.js.map +1 -0
- package/dist/posteffect/sao.js +48 -50
- package/dist/posteffect/sao.js.map +1 -1
- package/dist/posteffect/skinsss.js +605 -355
- package/dist/posteffect/skinsss.js.map +1 -1
- package/dist/posteffect/ssgi.js +91 -162
- package/dist/posteffect/ssgi.js.map +1 -1
- package/dist/posteffect/ssr.js +3 -11
- package/dist/posteffect/ssr.js.map +1 -1
- package/dist/posteffect/sss.js +34 -15
- package/dist/posteffect/sss.js.map +1 -1
- package/dist/posteffect/taa.js +1 -0
- package/dist/posteffect/taa.js.map +1 -1
- package/dist/render/abuffer_oit.js +40 -39
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/clipmap.js +328 -62
- package/dist/render/clipmap.js.map +1 -1
- package/dist/render/cluster_light.js +958 -224
- package/dist/render/cluster_light.js.map +1 -1
- package/dist/render/cull_visitor.js +26 -5
- package/dist/render/cull_visitor.js.map +1 -1
- package/dist/render/debug_views.js +37 -0
- package/dist/render/debug_views.js.map +1 -0
- package/dist/render/depthpass.js +5 -1
- package/dist/render/depthpass.js.map +1 -1
- package/dist/render/drawable_mixin.js +53 -6
- package/dist/render/drawable_mixin.js.map +1 -1
- package/dist/render/dualdepthpeeling_oit.js +53 -53
- package/dist/render/dualdepthpeeling_oit.js.map +1 -1
- package/dist/render/envlight.js +196 -113
- package/dist/render/envlight.js.map +1 -1
- package/dist/render/fbm_wavegenerator.js +8 -13
- package/dist/render/fbm_wavegenerator.js.map +1 -1
- package/dist/render/fft_wavegenerator.js +268 -136
- package/dist/render/fft_wavegenerator.js.map +1 -1
- package/dist/render/gerstner_wavegenerator.js +113 -28
- package/dist/render/gerstner_wavegenerator.js.map +1 -1
- package/dist/render/gi/probe_volume.js +1334 -0
- package/dist/render/gi/probe_volume.js.map +1 -0
- package/dist/render/gi/scene_gi.js +282 -0
- package/dist/render/gi/scene_gi.js.map +1 -0
- package/dist/render/gi/voxel_atlas.js +198 -0
- package/dist/render/gi/voxel_atlas.js.map +1 -0
- package/dist/render/gi/voxel_lighting.js +652 -0
- package/dist/render/gi/voxel_lighting.js.map +1 -0
- package/dist/render/gi/voxel_scene.js +642 -0
- package/dist/render/gi/voxel_scene.js.map +1 -0
- package/dist/render/gi/voxelize_pass.js +223 -0
- package/dist/render/gi/voxelize_pass.js.map +1 -0
- package/dist/render/globalbindgroup_allocator.js +3 -2
- package/dist/render/globalbindgroup_allocator.js.map +1 -1
- package/dist/render/gpu_picking.js +9 -36
- package/dist/render/gpu_picking.js.map +1 -1
- package/dist/render/hzb.js +80 -22
- package/dist/render/hzb.js.map +1 -1
- package/dist/render/instance_culling.js +499 -0
- package/dist/render/instance_culling.js.map +1 -0
- package/dist/render/lightpass.js +23 -9
- package/dist/render/lightpass.js.map +1 -1
- package/dist/render/lod.js +46 -0
- package/dist/render/lod.js.map +1 -0
- package/dist/render/oit.js +11 -11
- package/dist/render/oit.js.map +1 -1
- package/dist/render/primitive.js +301 -9
- package/dist/render/primitive.js.map +1 -1
- package/dist/render/primitive_readback.js +209 -0
- package/dist/render/primitive_readback.js.map +1 -0
- package/dist/render/render_queue.js +198 -11
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/renderer.js +14 -7
- package/dist/render/renderer.js.map +1 -1
- package/dist/render/rendergraph/blackboard.js +15 -1
- package/dist/render/rendergraph/blackboard.js.map +1 -1
- package/dist/render/rendergraph/executor.js +136 -0
- package/dist/render/rendergraph/executor.js.map +1 -1
- package/dist/render/rendergraph/forward_plus_builder.js +585 -59
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/render/rendergraph/frame_resource_requirements.js +1 -0
- package/dist/render/rendergraph/frame_resource_requirements.js.map +1 -1
- package/dist/render/rendergraph/history_resources.js +8 -1
- package/dist/render/rendergraph/history_resources.js.map +1 -1
- package/dist/render/rendergraph/scene_render_context.js +31 -2
- package/dist/render/rendergraph/scene_render_context.js.map +1 -1
- package/dist/render/rendergraph/types.js.map +1 -1
- package/dist/render/renderpass.js +28 -5
- package/dist/render/renderpass.js.map +1 -1
- package/dist/render/sdf/box_allocator.js +98 -0
- package/dist/render/sdf/box_allocator.js.map +1 -0
- package/dist/render/sdf/global_sdf.js +865 -0
- package/dist/render/sdf/global_sdf.js.map +1 -0
- package/dist/render/sdf/scene_sdf.js +562 -0
- package/dist/render/sdf/scene_sdf.js.map +1 -0
- package/dist/render/sdf/sdf_atlas.js +227 -0
- package/dist/render/sdf/sdf_atlas.js.map +1 -0
- package/dist/render/sdf/sdf_programs.js +42 -0
- package/dist/render/sdf/sdf_programs.js.map +1 -0
- package/dist/render/sdf/sdf_view.js +199 -0
- package/dist/render/sdf/sdf_view.js.map +1 -0
- package/dist/render/sdf/waterline.js +610 -0
- package/dist/render/sdf/waterline.js.map +1 -0
- package/dist/render/shadow_mask_pass.js +142 -25
- package/dist/render/shadow_mask_pass.js.map +1 -1
- package/dist/render/shore_wave_generator.js +1193 -0
- package/dist/render/shore_wave_generator.js.map +1 -0
- package/dist/render/sky.js +516 -86
- package/dist/render/sky.js.map +1 -1
- package/dist/render/transmission_thickness_pass.js +477 -0
- package/dist/render/transmission_thickness_pass.js.map +1 -0
- package/dist/render/underwater.js +524 -0
- package/dist/render/underwater.js.map +1 -0
- package/dist/render/virtualtexture/virtual_texture.js +1214 -0
- package/dist/render/virtualtexture/virtual_texture.js.map +1 -0
- package/dist/render/volumetric_cloud/cloud_common.js +472 -0
- package/dist/render/volumetric_cloud/cloud_common.js.map +1 -0
- package/dist/render/volumetric_cloud/cloud_noise.js +189 -0
- package/dist/render/volumetric_cloud/cloud_noise.js.map +1 -0
- package/dist/render/volumetric_cloud/debug_view.js +131 -0
- package/dist/render/volumetric_cloud/debug_view.js.map +1 -0
- package/dist/render/volumetric_cloud/resources.js +380 -0
- package/dist/render/volumetric_cloud/resources.js.map +1 -0
- package/dist/render/volumetric_cloud/sky_cache.js +380 -0
- package/dist/render/volumetric_cloud/sky_cache.js.map +1 -0
- package/dist/render/volumetric_cloud/volumetric_cloud.js +318 -0
- package/dist/render/volumetric_cloud/volumetric_cloud.js.map +1 -0
- package/dist/render/water_caustics.js +1195 -0
- package/dist/render/water_caustics.js.map +1 -0
- package/dist/render/water_foam.js +627 -0
- package/dist/render/water_foam.js.map +1 -0
- package/dist/render/water_interaction.js +1795 -0
- package/dist/render/water_interaction.js.map +1 -0
- package/dist/render/weightedblended_oit.js +36 -36
- package/dist/render/weightedblended_oit.js.map +1 -1
- package/dist/scene/basesprite.js +9 -4
- package/dist/scene/basesprite.js.map +1 -1
- package/dist/scene/batchgroup.js +108 -12
- package/dist/scene/batchgroup.js.map +1 -1
- package/dist/scene/environment.js +28 -7
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/foliage.js +1020 -0
- package/dist/scene/foliage.js.map +1 -0
- package/dist/scene/foliage_buckets.js +147 -0
- package/dist/scene/foliage_buckets.js.map +1 -0
- package/dist/scene/foliage_mask.js +358 -0
- package/dist/scene/foliage_mask.js.map +1 -0
- package/dist/scene/hair.js +15 -4
- package/dist/scene/hair.js.map +1 -1
- package/dist/scene/light.js +179 -13
- package/dist/scene/light.js.map +1 -1
- package/dist/scene/mesh.js +327 -45
- 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 +9 -3
- package/dist/scene/msdftext.js.map +1 -1
- package/dist/scene/msdftextsprite.js +9 -3
- package/dist/scene/msdftextsprite.js.map +1 -1
- package/dist/scene/particlesys.js +8 -2
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/physics_settings.js +157 -0
- package/dist/scene/physics_settings.js.map +1 -0
- package/dist/scene/scene.js +190 -44
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/scene_node.js +147 -6
- package/dist/scene/scene_node.js.map +1 -1
- package/dist/scene/terrain-cm/bladegrassmaterial.js +735 -0
- package/dist/scene/terrain-cm/bladegrassmaterial.js.map +1 -0
- package/dist/scene/terrain-cm/grass.js +881 -42
- package/dist/scene/terrain-cm/grass.js.map +1 -1
- package/dist/scene/terrain-cm/grass_gpu.js +929 -0
- package/dist/scene/terrain-cm/grass_gpu.js.map +1 -0
- package/dist/scene/terrain-cm/grassmaterial.js +180 -9
- package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +465 -36
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/scene/terrain-cm/terrain_gi_albedo.js +257 -0
- package/dist/scene/terrain-cm/terrain_gi_albedo.js.map +1 -0
- package/dist/scene/terrain-cm/terrain_rvt.js +395 -0
- package/dist/scene/terrain-cm/terrain_rvt.js.map +1 -0
- package/dist/scene/update_queue.js +54 -0
- package/dist/scene/update_queue.js.map +1 -0
- package/dist/scene/water.js +997 -96
- package/dist/scene/water.js.map +1 -1
- package/dist/scene/water_surface_sampler.js +324 -0
- package/dist/scene/water_surface_sampler.js.map +1 -0
- package/dist/scene/wind.js +317 -0
- package/dist/scene/wind.js.map +1 -0
- package/dist/shaders/atmosphere.js +388 -166
- package/dist/shaders/atmosphere.js.map +1 -1
- package/dist/shaders/fog.js +100 -32
- package/dist/shaders/fog.js.map +1 -1
- package/dist/shaders/gi.js +365 -0
- package/dist/shaders/gi.js.map +1 -0
- package/dist/shaders/ltc_rect.js +202 -0
- package/dist/shaders/ltc_rect.js.map +1 -0
- package/dist/shaders/misc.js +1 -10
- package/dist/shaders/misc.js.map +1 -1
- package/dist/shaders/noise.js +5 -1
- package/dist/shaders/noise.js.map +1 -1
- package/dist/shaders/probes.js +309 -0
- package/dist/shaders/probes.js.map +1 -0
- package/dist/shaders/sdf.js +537 -0
- package/dist/shaders/sdf.js.map +1 -0
- package/dist/shaders/shadow.js +104 -70
- package/dist/shaders/shadow.js.map +1 -1
- package/dist/shaders/skin_brdf.js +243 -0
- package/dist/shaders/skin_brdf.js.map +1 -0
- package/dist/shaders/ssr.js +6 -159
- package/dist/shaders/ssr.js.map +1 -1
- package/dist/shaders/temporal.js +38 -27
- package/dist/shaders/temporal.js.map +1 -1
- package/dist/shaders/water.js +40 -87
- package/dist/shaders/water.js.map +1 -1
- package/dist/shaders/water_medium.js +42 -0
- package/dist/shaders/water_medium.js.map +1 -0
- package/dist/shadow/dom.js +110 -19
- package/dist/shadow/dom.js.map +1 -1
- package/dist/shadow/esm.js +3 -3
- package/dist/shadow/esm.js.map +1 -1
- package/dist/shadow/pcf_opt.js +15 -48
- package/dist/shadow/pcf_opt.js.map +1 -1
- package/dist/shadow/pcf_pd.js +15 -53
- package/dist/shadow/pcf_pd.js.map +1 -1
- package/dist/shadow/pcss.js +34 -9
- package/dist/shadow/pcss.js.map +1 -1
- package/dist/shadow/shadow_impl.js +3 -8
- package/dist/shadow/shadow_impl.js.map +1 -1
- package/dist/shadow/shadow_region.js +87 -49
- package/dist/shadow/shadow_region.js.map +1 -1
- package/dist/shadow/shadowmapper.js +93 -53
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shadow/ssm.js +18 -72
- package/dist/shadow/ssm.js.map +1 -1
- package/dist/shadow/vsm.js +3 -3
- package/dist/shadow/vsm.js.map +1 -1
- package/dist/shapes/shape.js +44 -1
- package/dist/shapes/shape.js.map +1 -1
- package/dist/utility/buoyancy.js +287 -0
- package/dist/utility/buoyancy.js.map +1 -0
- package/dist/utility/physical.js +10 -1
- package/dist/utility/physical.js.map +1 -1
- package/dist/utility/pmrem.js +17 -43
- package/dist/utility/pmrem.js.map +1 -1
- package/dist/utility/sdf/bake.js +435 -0
- package/dist/utility/sdf/bake.js.map +1 -0
- package/dist/utility/sdf/bvh.js +576 -0
- package/dist/utility/sdf/bvh.js.map +1 -0
- package/dist/utility/serialization/manager.js +36 -6
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +77 -7
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/batch.js +11 -4
- package/dist/utility/serialization/scene/batch.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +140 -279
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/cloth.js +25 -0
- package/dist/utility/serialization/scene/cloth.js.map +1 -0
- package/dist/utility/serialization/scene/common.js +14 -6
- package/dist/utility/serialization/scene/common.js.map +1 -1
- package/dist/utility/serialization/scene/foliage.js +821 -0
- package/dist/utility/serialization/scene/foliage.js.map +1 -0
- package/dist/utility/serialization/scene/hair.js +11 -4
- package/dist/utility/serialization/scene/hair.js.map +1 -1
- package/dist/utility/serialization/scene/light.js +115 -7
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +388 -220
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +69 -4
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +140 -5
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/node_physics.js +1318 -0
- package/dist/utility/serialization/scene/node_physics.js.map +1 -0
- package/dist/utility/serialization/scene/particle.js +11 -4
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/physics.js +120 -0
- package/dist/utility/serialization/scene/physics.js.map +1 -0
- package/dist/utility/serialization/scene/primitive.js +124 -10
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/scene.js +1687 -51
- package/dist/utility/serialization/scene/scene.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +11 -4
- package/dist/utility/serialization/scene/sprite.js.map +1 -1
- package/dist/utility/serialization/scene/terrain.js +163 -33
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/text.js +11 -4
- package/dist/utility/serialization/scene/text.js.map +1 -1
- package/dist/utility/serialization/scene/water.js +2473 -114
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/utility/serialization/types.js.map +1 -1
- package/dist/utility/shprojector.js +97 -109
- package/dist/utility/shprojector.js.map +1 -1
- package/dist/utility/textures/foam.js +170 -0
- package/dist/utility/textures/foam.js.map +1 -0
- package/dist/utility/textures/ggxlut.js +17 -43
- package/dist/utility/textures/ggxlut.js.map +1 -1
- package/dist/utility/textures/ltcdata.js +4 -4
- package/dist/utility/textures/ltcdata.js.map +1 -1
- package/dist/utility/textures/ltclut.js +16 -6
- package/dist/utility/textures/ltclut.js.map +1 -1
- package/dist/utility/unsupported.js +24 -0
- package/dist/utility/unsupported.js.map +1 -0
- package/dist/values.js +13 -1
- package/dist/values.js.map +1 -1
- package/package.json +25 -12
- package/src/asset/loaders/ktx2/basis/LICENSE +201 -0
- package/src/asset/loaders/ktx2/basis/basis_transcoder.js +2 -0
- package/src/asset/loaders/ktx2/basis/basis_transcoder.wasm +0 -0
- package/src/asset/meshoptimizer/LICENSE +21 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skinprofile.js","sources":["../../src/material/skinprofile.ts"],"sourcesContent":["import { Vector3, type Immutable } from '@zephyr3d/base';\nimport type { AbstractDevice, Texture2D } from '@zephyr3d/device';\n\n/**\n * Number of scalar parameter columns stored per profile row.\n *\n * @remarks\n * Mirrors the row layout UE5 uses in its `SSProfiles` texture, read back from\n * `UEDigitalHuman.rdc` (SSS::PassOne_Burley lines 143-157).\n *\n * @internal\n */\nconst SKIN_PROFILE_PARAM_COLUMNS = 6;\n\n/**\n * Number of texels the baked transmission profile occupies.\n *\n * @remarks\n * `BSSS_TRANSMISSION_PROFILE_SIZE` in UE5 (`SubsurfaceProfileCommon.ush:27`).\n *\n * @internal\n */\nconst SKIN_TRANSMISSION_LUT_SIZE = 32;\n\n/**\n * Total columns per profile row: the scalar parameters followed by the baked\n * transmission profile, exactly as UE5 lays out an `SSProfiles` row.\n *\n * @internal\n */\nconst SKIN_PROFILE_COLUMNS = SKIN_PROFILE_PARAM_COLUMNS + SKIN_TRANSMISSION_LUT_SIZE;\n\n/** Maximum number of live skin profiles, matching the 8-bit profile id channel. @internal */\nconst SKIN_PROFILE_CAPACITY = 256;\n\n/**\n * Gate on {@link SkinProfile}'s constructor.\n *\n * @remarks\n * Module-private, so only {@link SkinProfile.createOwned} can pass it. See the\n * constructor for why a `private` modifier alone is not enough.\n *\n * @internal\n */\nconst CREATE_TOKEN = Symbol('SkinProfile.create');\n\n/**\n * Largest optical depth the transmission profile is defined over.\n *\n * @remarks\n * `SSSS_MAX_TRANSMISSION_PROFILE_DISTANCE` in UE5. It appears in two places that\n * have to agree, which is why it lives here rather than next to either of them:\n * the thickness pass encodes its optical depth as `1 - opticalDepth / MAX`, and\n * the transmission BxDF decodes that and divides by `MAX` again to index the\n * baked profile below.\n *\n * @internal\n */\nexport const SKIN_MAX_TRANSMISSION_OPTICAL_DEPTH = 5;\n\n/**\n * Floor the averaged optical depth is clamped to before encoding.\n *\n * @remarks\n * UE5's `clamp(..., 0.15, 5)` in `CalculateOpticalDepth`.\n *\n * @internal\n */\nexport const SKIN_TRANSMISSION_OPTICAL_DEPTH_FLOOR = 0.15;\n\n/**\n * Constant added to the optical depth after clamping.\n *\n * @remarks\n * UE5's trailing `+ 0.25` in `CalculateOpticalDepth`.\n *\n * @internal\n */\nexport const SKIN_TRANSMISSION_OPTICAL_DEPTH_BIAS = 0.25;\n\n/**\n * Largest value the thickness pass can write, and with it the sentinel that\n * separates a real measurement from \"no light wrote this\".\n *\n * @remarks\n * The encoding is `1 - opticalDepth / MAX` and the optical depth never falls\n * below `FLOOR + BIAS`, so the pass tops out at 0.92 and the cleared value of 1\n * is unreachable — which makes it usable as \"no data\".\n *\n * The distinction matters because 1 decodes to zero optical depth, the profile's\n * *strongest* entry: read as a measurement it would light every non-transmitting\n * light's pixels at full transmission.\n *\n * @internal\n */\nexport const SKIN_TRANSMISSION_NO_DATA_ENCODING =\n 1 -\n (SKIN_TRANSMISSION_OPTICAL_DEPTH_FLOOR + SKIN_TRANSMISSION_OPTICAL_DEPTH_BIAS) /\n SKIN_MAX_TRANSMISSION_OPTICAL_DEPTH;\n\n/**\n * Distance, in profile millimetres, the baked transmission profile spans.\n *\n * @remarks\n * `MaxTransmissionProfileDistance * CmToMm = 5 * 10` in\n * `ComputeTransmissionProfileBurley`.\n *\n * The 5 here and the one in {@link SKIN_MAX_TRANSMISSION_OPTICAL_DEPTH} are the\n * same number by construction: UE5's world unit is the centimetre, so an optical\n * depth of 1 at unit extinction *is* one centimetre, and this axis is that span\n * in the millimetres the mean free paths use. The shader indexes the table with\n * optical depth directly — self-consistent only once that is accounted for.\n *\n * The thickness pass must therefore be calibrated against this axis;\n * {@link SKIN_OPTICAL_DEPTH_PER_WORLD_UNIT} is that calibration, and changing\n * this constant without it slides the whole profile along the thickness axis.\n *\n * @internal\n */\nconst TRANSMISSION_LUT_MAX_DISTANCE_MM = 50;\n\n/**\n * Radius the baked transmission profile is offset by, in profile millimetres.\n *\n * @remarks\n * `ProfileRadiusOffset` in `BurleyNormalizedSSS.cpp:22`, 0.06 cm, times the same\n * `CmToMm`. It keeps the zero-thickness entry off the singular `r = 0` end of\n * the diffusion profile.\n *\n * @internal\n */\nconst TRANSMISSION_LUT_RADIUS_OFFSET_MM = 0.6;\n\n/**\n * Profile-space millimetres per world unit, before the profile's own world unit\n * scale is applied.\n *\n * @remarks\n * This engine is metric throughout, so a world unit is a metre and the profile\n * distances are millimetres. UE5 instead carries a `BURLEY_CM_2_MM = 10` because\n * its world unit is the centimetre; that factor has no analogue here and must\n * not be transcribed (see the diffusion pass, which likewise omits it).\n *\n * @internal\n */\nconst WORLD_UNITS_TO_PROFILE_MM = 1000;\n\n/**\n * Optical depth accumulated per world unit of light path, before the profile's\n * `extinctionScale`.\n *\n * @remarks\n * Derived rather than chosen, so the thickness pass and the baked profile cannot\n * drift apart. The BxDF indexes entry `opticalDepth / MAX * (size - 1)` and entry\n * `i` was baked for `i / size * LUT_MAX_MM` profile millimetres, so one unit of\n * optical depth is `LUT_MAX_MM * (size - 1) / size / MAX` millimetres.\n *\n * `worldUnitScale` deliberately does not appear: it divides both the table's axis\n * and the path's conversion into profile space, so it cancels. UE5 likewise keeps\n * it out of `CalculateOpticalDepth`.\n *\n * The `(size - 1) / size` is a deliberate 3% departure from UE5, whose index and\n * axis disagree by that factor. Correcting it makes a path of `t` metres index\n * exactly the entry baked for `t` millimetres.\n *\n * @internal\n */\nexport const SKIN_OPTICAL_DEPTH_PER_WORLD_UNIT =\n (WORLD_UNITS_TO_PROFILE_MM * SKIN_MAX_TRANSMISSION_OPTICAL_DEPTH) /\n (TRANSMISSION_LUT_MAX_DISTANCE_MM * ((SKIN_TRANSMISSION_LUT_SIZE - 1) / SKIN_TRANSMISSION_LUT_SIZE));\n\n/**\n * Column indices within a packed profile row.\n *\n * @internal\n */\nconst enum ProfileColumn {\n /** World unit scale + overall scatter scaling. */\n Scaling = 0,\n /** Per-channel scattering albedo (the `A` in Burley's shaping term). */\n SurfaceAlbedo = 1,\n /** Per-channel diffuse mean free path, in world units. */\n MeanFreePath = 2,\n /** Boundary color bleed. */\n Boundary = 3,\n /**\n * Transmission parameters: `(extinctionScale, normalScale,\n * scatteringDistribution, 1 / ior)`.\n *\n * @remarks\n * UE5's `SSSS_TRANSMISSION_OFFSET` column, unpacked in this order by\n * `GetTransmissionProfileParams`. The transmission tint is absent by design:\n * it is baked into the profile, and a second copy here could drift from it.\n */\n Transmission = 4,\n /** Dual-lobe specular parameters. */\n Specular = 5\n}\n\n/**\n * `GetSearchLightDiffuseScalingFactor`, the default variant.\n *\n * @remarks\n * `s = 3.5 + 100 (A - 0.33)^4`. The same curve the diffusion evaluates on the\n * GPU (`posteffect/skinsss.ts`, `scalingFactor`); the transmission profile is\n * baked on the CPU and needs its own copy.\n *\n * @internal\n */\nfunction searchLightDiffuseScalingFactor(albedo: number): number {\n const v = albedo - 0.33;\n return 3.5 + 100 * v * v * v * v;\n}\n\n/**\n * Built-in {@link SkinProfile} presets.\n *\n * @public\n */\nexport type SkinProfilePreset = 'skin' | 'skin_pale' | 'skin_tan' | 'skin_dark' | 'wax' | 'jade' | 'marble';\n\ninterface SkinProfileTemplate {\n surfaceAlbedo: [number, number, number];\n meanFreePath: [number, number, number];\n meanFreePathDistance: number;\n worldUnitScale: number;\n scatterScale: number;\n boundaryColorBleed: [number, number, number];\n transmissionTint: [number, number, number];\n extinctionScale: number;\n normalScale: number;\n scatteringDistribution: number;\n ior: number;\n roughness0: number;\n roughness1: number;\n lobeMix: number;\n}\n\n/**\n * Preset parameters.\n *\n * @remarks\n * `skin` reproduces UE5's `FSubsurfaceProfileStruct` defaults exactly, converted\n * into this engine's metre-based scene units:\n *\n * | UE5 parameter | UE5 default | here |\n * | -------------------- | ------------------------------- | --------------------------- |\n * | SurfaceAlbedo | (0.91058, 0.338275, 0.2718) | `surfaceAlbedo`, unchanged |\n * | MeanFreePathColor | (1, 0.1983/2.229, 0.1607/2.229) | `meanFreePath`, unchanged |\n * | MeanFreePathDistance | 1.2 × 2.229 = 2.6748 cm | `meanFreePathDistance` in m |\n * | WorldUnitScale | 0.1 cm | folded into the distance |\n * | BoundaryColorBleed | white | white |\n *\n * The red-shifted mean free path (roughly 1 : 0.089 : 0.072) and the equally\n * red-shifted albedo are together what make the diffusion read as skin rather\n * than as a neutral blur — the first thing to check when scattering looks washed\n * out. UE5 ships only `skin`; the rest are this engine's own, pitched around the\n * same regime to stay comparable.\n *\n * `boundaryColorBleed` is white throughout, as in UE5: it tints taps belonging to\n * a *different* profile, so anything darker attenuates every profile boundary.\n *\n * @internal\n */\nconst SKIN_PROFILE_TEMPLATES: Record<SkinProfilePreset, SkinProfileTemplate> = {\n skin: {\n surfaceAlbedo: [0.91058, 0.338275, 0.2718],\n meanFreePath: [1.0, 0.0889636, 0.0720951],\n meanFreePathDistance: 0.026748,\n worldUnitScale: 1,\n scatterScale: 1,\n boundaryColorBleed: [1, 1, 1],\n transmissionTint: [1.0, 0.42, 0.3],\n extinctionScale: 1,\n normalScale: 0.08,\n scatteringDistribution: 0.93,\n ior: 1.55,\n roughness0: 0.75,\n roughness1: 1.3,\n lobeMix: 0.85\n },\n skin_pale: {\n surfaceAlbedo: [0.93, 0.4, 0.33],\n meanFreePath: [1.0, 0.1, 0.083],\n meanFreePathDistance: 0.0294,\n worldUnitScale: 1,\n scatterScale: 1,\n boundaryColorBleed: [1, 1, 1],\n transmissionTint: [1.0, 0.48, 0.38],\n extinctionScale: 1,\n normalScale: 0.08,\n scatteringDistribution: 0.93,\n ior: 1.55,\n roughness0: 0.72,\n roughness1: 1.25,\n lobeMix: 0.85\n },\n skin_tan: {\n surfaceAlbedo: [0.88, 0.3, 0.235],\n meanFreePath: [1.0, 0.082, 0.066],\n meanFreePathDistance: 0.0254,\n worldUnitScale: 1,\n scatterScale: 1,\n boundaryColorBleed: [1, 1, 1],\n transmissionTint: [1.0, 0.38, 0.26],\n extinctionScale: 1,\n normalScale: 0.08,\n scatteringDistribution: 0.93,\n ior: 1.55,\n roughness0: 0.76,\n roughness1: 1.32,\n lobeMix: 0.85\n },\n skin_dark: {\n surfaceAlbedo: [0.8, 0.24, 0.185],\n meanFreePath: [1.0, 0.072, 0.057],\n meanFreePathDistance: 0.0227,\n worldUnitScale: 1,\n scatterScale: 1,\n boundaryColorBleed: [1, 1, 1],\n transmissionTint: [1.0, 0.3, 0.2],\n extinctionScale: 1,\n normalScale: 0.08,\n scatteringDistribution: 0.93,\n ior: 1.55,\n roughness0: 0.78,\n roughness1: 1.35,\n lobeMix: 0.85\n },\n wax: {\n surfaceAlbedo: [0.95, 0.9, 0.8],\n meanFreePath: [1.0, 0.85, 0.68],\n meanFreePathDistance: 0.05,\n worldUnitScale: 1,\n scatterScale: 1,\n boundaryColorBleed: [1, 1, 1],\n transmissionTint: [1.0, 0.88, 0.74],\n extinctionScale: 1,\n normalScale: 0.05,\n scatteringDistribution: 0.85,\n ior: 1.45,\n roughness0: 0.85,\n roughness1: 1.4,\n lobeMix: 0.8\n },\n jade: {\n surfaceAlbedo: [0.75, 0.93, 0.86],\n meanFreePath: [0.6, 1.0, 0.85],\n meanFreePathDistance: 0.045,\n worldUnitScale: 1,\n scatterScale: 1,\n boundaryColorBleed: [1, 1, 1],\n transmissionTint: [0.68, 0.95, 0.88],\n extinctionScale: 1,\n normalScale: 0.05,\n scatteringDistribution: 0.7,\n ior: 1.6,\n roughness0: 0.6,\n roughness1: 1.1,\n lobeMix: 0.75\n },\n marble: {\n surfaceAlbedo: [0.95, 0.94, 0.92],\n meanFreePath: [1.0, 0.96, 0.92],\n meanFreePathDistance: 0.035,\n worldUnitScale: 1,\n scatterScale: 1,\n boundaryColorBleed: [1, 1, 1],\n transmissionTint: [0.96, 0.95, 0.94],\n extinctionScale: 1,\n normalScale: 0.04,\n scatteringDistribution: 0.6,\n ior: 1.55,\n roughness0: 0.55,\n roughness1: 1.05,\n lobeMix: 0.7\n }\n};\n\n/**\n * Subsurface profile for {@link SSSMaterial}, holding the parameters UE5's\n * Burley diffusion is driven by.\n *\n * @remarks\n * Profiles are packed into a shared GPU table keyed by {@link SkinProfile.id},\n * and materials write that id per pixel. This lets several profiles — face, ears,\n * lips — diffuse independently in a single screen-space pass, which is how UE5\n * drives its subsurface scattering.\n *\n * This is a separate type from the older `SubsurfaceProfile`, which continues to\n * serve `PBRMetallicRoughnessMaterial` and the generic SSS post effect. The two\n * are independent and may be used side by side.\n *\n * @public\n */\nexport class SkinProfile {\n private static readonly _profiles: Array<SkinProfile | null> = new Array(SKIN_PROFILE_CAPACITY).fill(null);\n private static _table: Texture2D | null = null;\n /** Device {@link SkinProfile._table} belongs to, so a device swap can be spotted. */\n private static _tableDevice: AbstractDevice | null = null;\n private static _tableData: Float32Array<ArrayBuffer> | null = null;\n private static _tableDirty = true;\n private static _defaultProfile: SkinProfile | null = null;\n private readonly _id: number;\n private readonly _surfaceAlbedo: Vector3;\n private readonly _meanFreePath: Vector3;\n private readonly _boundaryColorBleed: Vector3;\n private readonly _transmissionTint: Vector3;\n private _preset: SkinProfilePreset;\n private _meanFreePathDistance: number;\n private _worldUnitScale: number;\n private _scatterScale: number;\n private _extinctionScale: number;\n private _normalScale: number;\n private _scatteringDistribution: number;\n private _ior: number;\n private _roughness0: number;\n private _roughness1: number;\n private _lobeMix: number;\n private _disposed: boolean;\n private readonly _changeListeners: Set<() => void>;\n\n /**\n * Not constructible from outside. Use {@link SSSMaterial.subsurfaceProfile},\n * which owns one for the material's lifetime.\n *\n * @remarks\n * The token check is not redundant with `private`: profiles hold a row of a\n * 256-entry GPU table that only {@link SkinProfile.dispose} returns, and the\n * editor ships as prebuilt JavaScript that drives this class through\n * serialization metadata, where TypeScript's visibility rules do not apply.\n *\n * @internal\n */\n private constructor(token: typeof CREATE_TOKEN, preset: SkinProfilePreset = 'skin') {\n if (token !== CREATE_TOKEN) {\n throw new Error(\n 'SkinProfile is not constructible directly; it is owned by the SSSMaterial that created it.'\n );\n }\n this._surfaceAlbedo = new Vector3();\n this._meanFreePath = new Vector3();\n this._boundaryColorBleed = new Vector3();\n this._transmissionTint = new Vector3();\n this._preset = preset;\n this._meanFreePathDistance = 0;\n this._worldUnitScale = 1;\n this._scatterScale = 1;\n this._extinctionScale = 1;\n this._normalScale = 0.08;\n this._scatteringDistribution = 0.93;\n this._ior = 1.55;\n this._roughness0 = 0.75;\n this._roughness1 = 1.3;\n this._lobeMix = 0.85;\n this._disposed = false;\n this._changeListeners = new Set();\n this._id = SkinProfile.allocateId(this);\n this.applyPreset(preset);\n }\n\n /**\n * Registers a callback invoked whenever this profile's parameters change.\n *\n * @param listener - The callback to add.\n *\n * @public\n */\n addChangeListener(listener: () => void) {\n this._changeListeners.add(listener);\n }\n\n /**\n * Removes a previously registered change listener.\n *\n * @param listener - The callback to remove.\n *\n * @public\n */\n removeChangeListener(listener: () => void) {\n this._changeListeners.delete(listener);\n }\n\n /**\n * Creates a profile for a material to own.\n *\n * @remarks\n * The only way to obtain one. The caller takes on releasing its table row — in\n * practice {@link SSSMaterial}, which disposes the profile with itself.\n *\n * @param preset - Preset to start from. Defaults to `'skin'`.\n * @returns The new profile.\n *\n * @internal\n */\n static createOwned(preset: SkinProfilePreset = 'skin') {\n return new SkinProfile(CREATE_TOKEN, preset);\n }\n\n /**\n * The shared default skin profile.\n *\n * @remarks\n * A fallback for consumers with no material to ask — the diffusion uses it for\n * pixels whose id is not in the table. Created lazily, since it holds a table\n * row for the lifetime of the process.\n *\n * @public\n */\n static getDefault() {\n if (!this._defaultProfile) {\n this._defaultProfile = new SkinProfile(CREATE_TOKEN, 'skin');\n }\n return this._defaultProfile;\n }\n\n /**\n * Looks up a profile by its packed id.\n *\n * @param id - The profile id, as written to the per-pixel profile channel.\n * @returns The profile, or `null` when the id is unused.\n *\n * @public\n */\n static getById(id: number) {\n return id > 0 && id < SKIN_PROFILE_CAPACITY ? this._profiles[id] : null;\n }\n\n /**\n * The packed parameter table, rebuilt when any profile has changed.\n *\n * @remarks\n * Rows are indexed by profile id, columns by parameter group. The skin\n * diffusion passes sample this to recover per-pixel scattering parameters.\n *\n * @param device - Device used to create and upload the table.\n * @returns The table texture, or `null` when it could not be created.\n *\n * @public\n */\n static getTable(device: AbstractDevice): Texture2D | null {\n // The table is static and outlives any one device. A texture belonging to a\n // dead device silently swallows every `update`, which strands the last values\n // uploaded before the swap on screen until the page is reloaded.\n if (this._table && (this._tableDevice !== device || this._table.disposed)) {\n this._table = null;\n this._tableData = null;\n }\n if (!this._table) {\n this._table = device.createTexture2D('rgba32f', SKIN_PROFILE_COLUMNS, SKIN_PROFILE_CAPACITY, {\n mipmapping: false,\n samplerOptions: { minFilter: 'nearest', magFilter: 'nearest', mipFilter: 'none' }\n });\n this._tableDevice = device;\n this._tableData = new Float32Array(SKIN_PROFILE_COLUMNS * SKIN_PROFILE_CAPACITY * 4);\n this._tableDirty = true;\n }\n if (this._tableDirty && this._table && this._tableData) {\n this.packTable(this._tableData);\n this._table.update(this._tableData, 0, 0, SKIN_PROFILE_COLUMNS, SKIN_PROFILE_CAPACITY);\n this._tableDirty = false;\n }\n return this._table;\n }\n\n /** Number of parameter columns in the packed table. @public */\n static get tableColumns() {\n return SKIN_PROFILE_COLUMNS;\n }\n\n /**\n * Column the baked transmission profile starts at.\n *\n * @remarks\n * UE5's `BSSS_TRANSMISSION_PROFILE_OFFSET`. Entry `i` lives at column\n * `transmissionLutOffset + i`.\n *\n * @public\n */\n static get transmissionLutOffset() {\n return SKIN_PROFILE_PARAM_COLUMNS;\n }\n\n /**\n * Column holding `(worldUnitScale, scatterScale, 0, 0)`.\n *\n * @remarks\n * Read by the transmission thickness pass, which needs the world unit scale to\n * size its normal shrink against the asset.\n *\n * @public\n */\n static get scalingParamColumn() {\n return ProfileColumn.Scaling as number;\n }\n\n /**\n * Column holding `(extinctionScale, normalScale, scatteringDistribution,\n * 1 / ior)`.\n *\n * @remarks\n * UE5's `SSSS_TRANSMISSION_OFFSET`, unpacked by\n * `GetTransmissionProfileParams`.\n *\n * @public\n */\n static get transmissionParamColumn() {\n return ProfileColumn.Transmission as number;\n }\n\n /** Number of entries in the baked transmission profile. @public */\n static get transmissionLutSize() {\n return SKIN_TRANSMISSION_LUT_SIZE;\n }\n\n /** Number of rows in the packed table. @public */\n static get tableRows() {\n return SKIN_PROFILE_CAPACITY;\n }\n\n /**\n * The id this profile occupies in the packed table.\n *\n * @remarks\n * Ids start at 1; 0 means \"not skin\" in the per-pixel profile channel. The\n * material encodes this as `id / 255`.\n *\n * @public\n */\n get id() {\n return this._id;\n }\n\n /** Normalized id as written to an 8-bit per-pixel channel. @public */\n get encodedId() {\n return this._id / 255;\n }\n\n /** The preset this profile was last initialized from. @public */\n get preset() {\n return this._preset;\n }\n set preset(val: SkinProfilePreset) {\n if (val !== this._preset) {\n this.applyPreset(val);\n }\n }\n\n /**\n * Per-channel scattering albedo.\n *\n * @remarks\n * Drives Burley's shaping term `s = (albedo - 0.33)^4 * 100 + 3.5`, so values\n * near 0.33 give the widest diffusion and values at either extreme tighten it.\n *\n * @public\n */\n get surfaceAlbedo(): Immutable<Vector3> {\n return this._surfaceAlbedo;\n }\n set surfaceAlbedo(val: Immutable<Vector3>) {\n if (!val.equalsTo(this._surfaceAlbedo)) {\n this._surfaceAlbedo.set(val);\n this.notifyChanged();\n }\n }\n\n /**\n * Per-channel diffuse mean free path, as a ratio.\n *\n * @remarks\n * Scaled by {@link SkinProfile.meanFreePathDistance} to reach world units. The\n * red channel is normally much longer than blue, which is what makes thin\n * geometry such as an ear rim glow red.\n *\n * @public\n */\n get meanFreePath(): Immutable<Vector3> {\n return this._meanFreePath;\n }\n set meanFreePath(val: Immutable<Vector3>) {\n if (!val.equalsTo(this._meanFreePath)) {\n this._meanFreePath.set(val);\n this.notifyChanged();\n }\n }\n\n /** Mean free path of the widest channel, in profile space. @public */\n get meanFreePathDistance() {\n return this._meanFreePathDistance;\n }\n set meanFreePathDistance(val: number) {\n const next = Math.max(0, val ?? 0);\n if (next !== this._meanFreePathDistance) {\n this._meanFreePathDistance = next;\n this.notifyChanged();\n }\n }\n\n /**\n * Profile-space to world-unit conversion, for scenes not authored in metres.\n *\n * @remarks\n * Applied once, when the diffusion converts a scatter radius into a screen\n * offset — the same place UE5 applies it, in `CalculateBurleyScale`. It is\n * deliberately absent from {@link SkinProfile.getScatterDistance}.\n *\n * @public\n */\n get worldUnitScale() {\n return this._worldUnitScale;\n }\n set worldUnitScale(val: number) {\n const next = Math.max(0.01, val ?? 1);\n if (next !== this._worldUnitScale) {\n this._worldUnitScale = next;\n this.notifyChanged();\n }\n }\n\n /** Overall multiplier on the diffusion width. @public */\n get scatterScale() {\n return this._scatterScale;\n }\n set scatterScale(val: number) {\n const next = Math.max(0, val ?? 1);\n if (next !== this._scatterScale) {\n this._scatterScale = next;\n this.notifyChanged();\n }\n }\n\n /**\n * Per-channel tint applied where two different profiles meet.\n *\n * @remarks\n * Taps that belong to another profile are attenuated by this instead of being\n * rejected outright, so a face/lip boundary softens rather than forming a seam.\n *\n * @public\n */\n get boundaryColorBleed(): Immutable<Vector3> {\n return this._boundaryColorBleed;\n }\n set boundaryColorBleed(val: Immutable<Vector3>) {\n if (!val.equalsTo(this._boundaryColorBleed)) {\n this._boundaryColorBleed.set(val);\n this.notifyChanged();\n }\n }\n\n /** Tint applied to light transmitted through thin geometry. @public */\n get transmissionTint(): Immutable<Vector3> {\n return this._transmissionTint;\n }\n set transmissionTint(val: Immutable<Vector3>) {\n if (!val.equalsTo(this._transmissionTint)) {\n this._transmissionTint.set(val);\n this.notifyChanged();\n }\n }\n\n /** Extinction multiplier for transmission attenuation. @public */\n get extinctionScale() {\n return this._extinctionScale;\n }\n set extinctionScale(val: number) {\n const next = Math.max(0, val ?? 1);\n if (next !== this._extinctionScale) {\n this._extinctionScale = next;\n this.notifyChanged();\n }\n }\n\n /** How much surface normal detail survives the diffusion. @public */\n get normalScale() {\n return this._normalScale;\n }\n set normalScale(val: number) {\n const next = Math.max(0, val ?? 0);\n if (next !== this._normalScale) {\n this._normalScale = next;\n this.notifyChanged();\n }\n }\n\n /**\n * Henyey-Greenstein asymmetry of the transmitted light, in `[-1, 1]`.\n *\n * @remarks\n * UE5's `ScatteringDistribution`, default 0.93 for skin. Positive values throw\n * the transmitted light forward, concentrating a backlit ear's glow where the\n * light shines through rather than spreading it as a uniform wash.\n *\n * Only the transmission BxDF uses this; the screen-space diffusion is isotropic\n * and ignores it. Stored raw, unlike UE5's `[0, 1]` remap for an 8-bit texture.\n *\n * @public\n */\n get scatteringDistribution() {\n return this._scatteringDistribution;\n }\n set scatteringDistribution(val: number) {\n const next = Math.min(1, Math.max(-1, val ?? 0));\n if (next !== this._scatteringDistribution) {\n this._scatteringDistribution = next;\n this.notifyChanged();\n }\n }\n\n /**\n * Index of refraction used to bend the view ray before the phase function.\n *\n * @remarks\n * UE5's `IOR`, default 1.55 for skin, stored in the table as `1 / ior` since\n * that is the form `refract` takes. This drives transmission only — the\n * specular Fresnel stays on the dielectric `F0 = 0.08 * Specular` mapping, as\n * {@link SSSMaterial.specularF0} notes.\n *\n * @public\n */\n get ior() {\n return this._ior;\n }\n set ior(val: number) {\n const next = Math.min(3, Math.max(1, val ?? 1.55));\n if (next !== this._ior) {\n this._ior = next;\n this.notifyChanged();\n }\n }\n\n /**\n * Multiplier on the material roughness for the narrow specular lobe.\n *\n * @remarks\n * A direct multiplier, so 1 leaves the material roughness alone and skin's\n * default 0.75 tightens the narrow lobe. The 0.5..2 range matches UE5's, whose\n * halve-on-pack encoding has no counterpart here.\n *\n * @public\n */\n get roughness0() {\n return this._roughness0;\n }\n set roughness0(val: number) {\n const next = Math.min(2, Math.max(0.5, val ?? 0.75));\n if (next !== this._roughness0) {\n this._roughness0 = next;\n this.notifyChanged();\n }\n }\n\n /**\n * Multiplier on the material roughness for the wide specular lobe.\n *\n * @remarks\n * Same scaling as {@link SkinProfile.roughness0}; skin's default 1.3 broadens\n * the second lobe, giving it a soft sheen alongside the tighter highlight.\n *\n * @public\n */\n get roughness1() {\n return this._roughness1;\n }\n set roughness1(val: number) {\n const next = Math.min(2, Math.max(0.5, val ?? 1.3));\n if (next !== this._roughness1) {\n this._roughness1 = next;\n this.notifyChanged();\n }\n }\n\n /** Blend between the narrow and wide specular lobes. @public */\n get lobeMix() {\n return this._lobeMix;\n }\n set lobeMix(val: number) {\n const next = Math.min(0.9, Math.max(0.1, val ?? 0.85));\n if (next !== this._lobeMix) {\n this._lobeMix = next;\n this.notifyChanged();\n }\n }\n\n /**\n * Per-channel diffusion distance, in profile space.\n *\n * @remarks\n * Deliberately *not* scaled by {@link SkinProfile.worldUnitScale}, which UE5\n * applies later in `CalculateBurleyScale`; applying it in both places would\n * make the diffusion scale with its square. The result must therefore be read\n * together with that factor to reach world units.\n *\n * @returns Mean free path scaled by the profile's distance and scatter scale.\n *\n * @public\n */\n getScatterDistance(): Vector3 {\n const s = this._meanFreePathDistance * this._scatterScale;\n return new Vector3(this._meanFreePath.x * s, this._meanFreePath.y * s, this._meanFreePath.z * s);\n }\n\n /**\n * Overwrites every parameter from another profile.\n *\n * @remarks\n * The only way to transfer a look, since profiles cannot be shared or cloned.\n * The table row is untouched: it identifies the profile, not its contents.\n *\n * @param other - Profile to copy the parameters from.\n *\n * @public\n */\n copyFrom(other: SkinProfile) {\n this._preset = other._preset;\n this._surfaceAlbedo.set(other._surfaceAlbedo);\n this._meanFreePath.set(other._meanFreePath);\n this._boundaryColorBleed.set(other._boundaryColorBleed);\n this._transmissionTint.set(other._transmissionTint);\n this._meanFreePathDistance = other._meanFreePathDistance;\n this._worldUnitScale = other._worldUnitScale;\n this._scatterScale = other._scatterScale;\n this._extinctionScale = other._extinctionScale;\n this._normalScale = other._normalScale;\n this._scatteringDistribution = other._scatteringDistribution;\n this._ior = other._ior;\n this._roughness0 = other._roughness0;\n this._roughness1 = other._roughness1;\n this._lobeMix = other._lobeMix;\n this.notifyChanged();\n }\n\n /**\n * Releases this profile's table slot.\n *\n * @public\n */\n dispose() {\n if (this._disposed) {\n return;\n }\n this._disposed = true;\n if (SkinProfile._profiles[this._id] === this) {\n SkinProfile._profiles[this._id] = null;\n SkinProfile.markDirty();\n }\n }\n\n private applyPreset(preset: SkinProfilePreset) {\n const t = SKIN_PROFILE_TEMPLATES[preset] ?? SKIN_PROFILE_TEMPLATES.skin;\n this._preset = preset;\n this._surfaceAlbedo.setXYZ(t.surfaceAlbedo[0], t.surfaceAlbedo[1], t.surfaceAlbedo[2]);\n this._meanFreePath.setXYZ(t.meanFreePath[0], t.meanFreePath[1], t.meanFreePath[2]);\n this._boundaryColorBleed.setXYZ(\n t.boundaryColorBleed[0],\n t.boundaryColorBleed[1],\n t.boundaryColorBleed[2]\n );\n this._transmissionTint.setXYZ(t.transmissionTint[0], t.transmissionTint[1], t.transmissionTint[2]);\n this._meanFreePathDistance = t.meanFreePathDistance;\n this._worldUnitScale = t.worldUnitScale;\n this._scatterScale = t.scatterScale;\n this._extinctionScale = t.extinctionScale;\n this._normalScale = t.normalScale;\n this._scatteringDistribution = t.scatteringDistribution;\n this._ior = t.ior;\n this._roughness0 = t.roughness0;\n this._roughness1 = t.roughness1;\n this._lobeMix = t.lobeMix;\n this.notifyChanged();\n }\n\n private static allocateId(profile: SkinProfile) {\n for (let i = 1; i < SKIN_PROFILE_CAPACITY; i++) {\n if (!this._profiles[i]) {\n this._profiles[i] = profile;\n this.markDirty();\n return i;\n }\n }\n throw new Error('SkinProfile limit exceeded');\n }\n\n private static markDirty() {\n this._tableDirty = true;\n }\n\n /**\n * Flags the packed table for a rebuild and notifies materials using this\n * profile so they can refresh their uniforms.\n */\n private notifyChanged() {\n SkinProfile.markDirty();\n this._changeListeners.forEach((listener) => listener());\n }\n\n private static packTable(out: Float32Array<ArrayBuffer>) {\n out.fill(0);\n const stride = SKIN_PROFILE_COLUMNS * 4;\n for (let id = 1; id < SKIN_PROFILE_CAPACITY; id++) {\n const p = this._profiles[id];\n if (!p) {\n continue;\n }\n const row = id * stride;\n const write = (column: ProfileColumn, x: number, y: number, z: number, w: number) => {\n const o = row + column * 4;\n out[o] = x;\n out[o + 1] = y;\n out[o + 2] = z;\n out[o + 3] = w;\n };\n // The diffusion draws its radii from one representative channel, kept in\n // the `w` of both rows as UE5 does, and evaluates all three kernels at\n // those radii. The widest channel represents, so the sample distribution\n // covers every channel's tail.\n const d = p.getScatterDistance();\n const widest = Math.max(d.x, d.y, d.z);\n const albedoForSampling =\n widest > 0\n ? [p._surfaceAlbedo.x, p._surfaceAlbedo.y, p._surfaceAlbedo.z][[d.x, d.y, d.z].indexOf(widest)]\n : p._surfaceAlbedo.x;\n write(ProfileColumn.Scaling, p._worldUnitScale, p._scatterScale, 0, 0);\n write(\n ProfileColumn.SurfaceAlbedo,\n p._surfaceAlbedo.x,\n p._surfaceAlbedo.y,\n p._surfaceAlbedo.z,\n albedoForSampling\n );\n write(ProfileColumn.MeanFreePath, d.x, d.y, d.z, widest);\n write(\n ProfileColumn.Boundary,\n p._boundaryColorBleed.x,\n p._boundaryColorBleed.y,\n p._boundaryColorBleed.z,\n 0\n );\n write(\n ProfileColumn.Transmission,\n p._extinctionScale,\n p._normalScale,\n p._scatteringDistribution,\n 1 / Math.max(p._ior, 1e-4)\n );\n write(ProfileColumn.Specular, p._roughness0, p._roughness1, p._lobeMix, 0);\n // The LUT columns are consecutive within the row, so the baked profile\n // drops straight in after the scalar parameters.\n p.writeTransmissionProfile(out, row + SKIN_PROFILE_PARAM_COLUMNS * 4);\n }\n }\n\n /**\n * Bakes this profile's transmission table.\n *\n * @remarks\n * `ComputeTransmissionProfileBurley` (`BurleyNormalizedSSS.cpp:171`),\n * transcribed. Each entry is the Burley diffusion profile integrated from that\n * radius out to infinity,\n *\n * ```\n * T(r) = 0.25 A (exp(-s r / L) + 3 exp(-s r / 3L))\n * ```\n *\n * evaluated per channel at its own `s` and `L`, times the transmission tint.\n * The surface albedo is absent — UE5 passes white for `A` — so this carries\n * only the *shape* of the falloff; the base colour is applied where the\n * transmission joins the diffuse.\n *\n * The alpha is `exp(-distance x extinctionScale)`, UE5's separate \"SSSS shadow\"\n * curve. The BxDF reads `.rgb` only, but storing it costs nothing.\n *\n * @param out - Destination, `4 x transmissionLutSize` floats from `offset`.\n * @param offset - Index of the first float to write.\n *\n * @public\n */\n writeTransmissionProfile(out: Float32Array, offset = 0) {\n // The world unit scale applies to this table's *distance axis*, not to the\n // mean free paths, which UE5 likewise leaves unscaled.\n const invUnitScale = 1 / Math.max(this._worldUnitScale, 1e-4);\n const d = this.getScatterDistance();\n const l = [\n d.x * WORLD_UNITS_TO_PROFILE_MM,\n d.y * WORLD_UNITS_TO_PROFILE_MM,\n d.z * WORLD_UNITS_TO_PROFILE_MM\n ];\n const s = [\n searchLightDiffuseScalingFactor(this._surfaceAlbedo.x),\n searchLightDiffuseScalingFactor(this._surfaceAlbedo.y),\n searchLightDiffuseScalingFactor(this._surfaceAlbedo.z)\n ];\n const tint = [this._transmissionTint.x, this._transmissionTint.y, this._transmissionTint.z];\n const offsetMM = TRANSMISSION_LUT_RADIUS_OFFSET_MM * invUnitScale;\n for (let i = 0; i < SKIN_TRANSMISSION_LUT_SIZE; i++) {\n const o = offset + i * 4;\n // UE5's `bMakeLastPixelBlack`: 50 mm leaves a red tail still visible after\n // tone mapping, so forcing the last entry black is what makes anything\n // thicker than the table stop transmitting outright.\n if (i === SKIN_TRANSMISSION_LUT_SIZE - 1) {\n out[o] = 0;\n out[o + 1] = 0;\n out[o + 2] = 0;\n out[o + 3] = 0;\n break;\n }\n // Note the divisor is the table size, not `size - 1`: the last entry is\n // blacked out anyway, so UE5 spends the axis on the entries that survive.\n const distanceMM = (i / SKIN_TRANSMISSION_LUT_SIZE) * TRANSMISSION_LUT_MAX_DISTANCE_MM * invUnitScale;\n const r = distanceMM + offsetMM;\n for (let c = 0; c < 3; c++) {\n out[o + c] =\n l[c] > 0\n ? 0.25 * (Math.exp((-s[c] * r) / l[c]) + 3 * Math.exp((-s[c] * r) / (3 * l[c]))) * tint[c]\n : 0;\n }\n out[o + 3] = Math.exp(-distanceMM * this._extinctionScale);\n }\n }\n}\n"],"names":["SKIN_PROFILE_PARAM_COLUMNS","SKIN_TRANSMISSION_LUT_SIZE","SKIN_PROFILE_COLUMNS","SKIN_PROFILE_CAPACITY","CREATE_TOKEN","Symbol","SKIN_MAX_TRANSMISSION_OPTICAL_DEPTH","SKIN_TRANSMISSION_OPTICAL_DEPTH_FLOOR","SKIN_TRANSMISSION_OPTICAL_DEPTH_BIAS","SKIN_TRANSMISSION_NO_DATA_ENCODING","TRANSMISSION_LUT_MAX_DISTANCE_MM","TRANSMISSION_LUT_RADIUS_OFFSET_MM","WORLD_UNITS_TO_PROFILE_MM","SKIN_OPTICAL_DEPTH_PER_WORLD_UNIT","searchLightDiffuseScalingFactor","albedo","v","SKIN_PROFILE_TEMPLATES","skin","surfaceAlbedo","meanFreePath","meanFreePathDistance","worldUnitScale","scatterScale","boundaryColorBleed","transmissionTint","extinctionScale","normalScale","scatteringDistribution","ior","roughness0","roughness1","lobeMix","skin_pale","skin_tan","skin_dark","wax","jade","marble","SkinProfile","_profiles","Array","fill","_table","_tableDevice","_tableData","_tableDirty","_defaultProfile","_id","_surfaceAlbedo","_meanFreePath","_boundaryColorBleed","_transmissionTint","_preset","_meanFreePathDistance","_worldUnitScale","_scatterScale","_extinctionScale","_normalScale","_scatteringDistribution","_ior","_roughness0","_roughness1","_lobeMix","_disposed","_changeListeners","token","preset","Error","Vector3","Set","allocateId","applyPreset","addChangeListener","listener","add","removeChangeListener","delete","createOwned","getDefault","getById","id","getTable","device","disposed","createTexture2D","mipmapping","samplerOptions","minFilter","magFilter","mipFilter","Float32Array","packTable","update","tableColumns","transmissionLutOffset","scalingParamColumn","transmissionParamColumn","transmissionLutSize","tableRows","encodedId","val","equalsTo","set","notifyChanged","next","Math","max","min","getScatterDistance","s","x","y","z","copyFrom","other","dispose","markDirty","t","setXYZ","profile","i","forEach","out","stride","p","row","write","column","w","o","d","widest","albedoForSampling","indexOf","writeTransmissionProfile","offset","invUnitScale","l","tint","offsetMM","distanceMM","r","c","exp"],"mappings":"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"}
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
import { Vector3, Vector2 } from '@zephyr3d/base';
|
|
2
|
+
import { applyMaterialMixins, MeshMaterial } from './meshmaterial.js';
|
|
3
|
+
import { mixinLight } from './mixins/lit.js';
|
|
4
|
+
import { mixinVertexColor } from './mixins/vertexcolor.js';
|
|
5
|
+
import { mixinTextureProps } from './mixins/texture.js';
|
|
6
|
+
import { ShaderHelper } from './shader/helper.js';
|
|
7
|
+
import { RENDER_PASS_TYPE_LIGHT, RENDER_PASS_TYPE_DEPTH, LIGHT_TYPE_POINT, MaterialVaryingFlags } from '../values.js';
|
|
8
|
+
import { skinDualSpecularRoughness, skinSpecularEnergyTerms, skinDiffuseBRDF, skinTransmission, skinDualLobeSpecular } from '../shaders/skin_brdf.js';
|
|
9
|
+
import { SSSProfile } from './sssprofile.js';
|
|
10
|
+
import { fetchSampler } from '../utility/misc.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* HDR range that used to be packed into the PostSSS side buffer when the render
|
|
14
|
+
* graph fell back to an 8-bit format.
|
|
15
|
+
*
|
|
16
|
+
* @deprecated The SSS scattering source is now recovered from `SceneColor` via
|
|
17
|
+
* the diffuse luminance stored in its alpha channel, so no side buffer and no
|
|
18
|
+
* LDR encoding is involved. Kept for source compatibility; it has no effect on
|
|
19
|
+
* rendering.
|
|
20
|
+
*
|
|
21
|
+
* @public
|
|
22
|
+
*/ const SKIN_SSS_LDR_ENCODE_RANGE = 4;
|
|
23
|
+
/**
|
|
24
|
+
* Physically-based SSS material.
|
|
25
|
+
*
|
|
26
|
+
* @remarks
|
|
27
|
+
* Uses a pre-integrated curvature-dependent diffuse BRDF and dual-lobe GGX specular
|
|
28
|
+
* driven by subsurface profile parameters. The **diffuse** luminance is written to
|
|
29
|
+
* `SceneColor.a` so the {@link PostSSS} post effect can recover the diffusible
|
|
30
|
+
* fraction as `saturate(SceneColor.a / luma(SceneColor.rgb))`.
|
|
31
|
+
*
|
|
32
|
+
* The optional `subsurfaceTexture` uses R as the SSS mask, which gates both the
|
|
33
|
+
* screen-space diffusion and the dual specular lobe. Its other channels are
|
|
34
|
+
* unused: transmission thickness is measured against the light's shadow map by
|
|
35
|
+
* the transmission thickness pass rather than painted, and curvature is not part
|
|
36
|
+
* of this path.
|
|
37
|
+
*
|
|
38
|
+
* @public
|
|
39
|
+
*/ class SSSMaterial extends applyMaterialMixins(MeshMaterial, mixinLight, mixinVertexColor, mixinTextureProps('subsurface')) {
|
|
40
|
+
static FEATURE_VERTEX_NORMAL = this.defineFeature();
|
|
41
|
+
static FEATURE_VERTEX_TANGENT = this.defineFeature();
|
|
42
|
+
_roughness;
|
|
43
|
+
_specularF0;
|
|
44
|
+
_transmissionStrength;
|
|
45
|
+
_profile;
|
|
46
|
+
_subsurfaceProfileChanged;
|
|
47
|
+
_lobeParams;
|
|
48
|
+
_profileTexelSize;
|
|
49
|
+
constructor(){
|
|
50
|
+
super();
|
|
51
|
+
this._subsurfaceProfileChanged = ()=>this.uniformChanged();
|
|
52
|
+
// Created here and released in onDispose: the profile holds a row of a
|
|
53
|
+
// 256-entry GPU table, and tying its life to the material's is what keeps
|
|
54
|
+
// those rows from accumulating.
|
|
55
|
+
this._profile = SSSProfile.createOwned();
|
|
56
|
+
this._profile.addChangeListener(this._subsurfaceProfileChanged);
|
|
57
|
+
this._lobeParams = new Vector3();
|
|
58
|
+
this._profileTexelSize = new Vector2();
|
|
59
|
+
this._roughness = 0.5;
|
|
60
|
+
this._specularF0 = 0.04;
|
|
61
|
+
this._transmissionStrength = 1;
|
|
62
|
+
this.useFeature(SSSMaterial.FEATURE_VERTEX_NORMAL, true);
|
|
63
|
+
}
|
|
64
|
+
/** Releases the profile's table row along with the material. */ onDispose() {
|
|
65
|
+
super.onDispose();
|
|
66
|
+
this._profile.removeChangeListener(this._subsurfaceProfileChanged);
|
|
67
|
+
this._profile.dispose();
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Marker used by the forward render graph to enable the PostSSS post effect.
|
|
71
|
+
*
|
|
72
|
+
* @remarks
|
|
73
|
+
* This no longer allocates a side buffer: the scattering source is recovered
|
|
74
|
+
* from `SceneColor` and its diffuse-luminance alpha.
|
|
75
|
+
*/ get postSSS() {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The profile driving this material's subsurface scattering.
|
|
80
|
+
*
|
|
81
|
+
* @remarks
|
|
82
|
+
* Read-only and never null: the material creates one in its constructor and
|
|
83
|
+
* owns it for life, so edit it in place rather than assigning a new one.
|
|
84
|
+
*
|
|
85
|
+
* ```ts
|
|
86
|
+
* material.subsurfaceProfile.preset = 'jade';
|
|
87
|
+
* material.subsurfaceProfile.meanFreePathDistance = 0.03;
|
|
88
|
+
* ```
|
|
89
|
+
*
|
|
90
|
+
* Per-material ownership is what lets face, ears and lips scatter differently
|
|
91
|
+
* in a single screen-space pass: the material writes its profile's id per pixel
|
|
92
|
+
* and the diffusion looks the parameters up from there. Profiles are therefore
|
|
93
|
+
* not shared - to transfer a look, use {@link SSSProfile.copyFrom}.
|
|
94
|
+
*
|
|
95
|
+
* @public
|
|
96
|
+
*/ get subsurfaceProfile() {
|
|
97
|
+
return this._profile;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Keeps the diffuse luminance written to `SceneColor.a` instead of letting the
|
|
101
|
+
* opaque path overwrite it with 1. {@link PostSSS} needs it to separate the
|
|
102
|
+
* diffusible energy from the specular it must leave untouched.
|
|
103
|
+
*/ preservesOpaqueAlpha(ctx) {
|
|
104
|
+
return ctx.renderPass.type === RENDER_PASS_TYPE_LIGHT;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Keeps `SceneColor.a` additive across the multi-pass light loop.
|
|
108
|
+
*
|
|
109
|
+
* @remarks
|
|
110
|
+
* The base implementation uses `zero/one` for alpha so that additive light
|
|
111
|
+
* passes preserve whatever the base pass wrote. That is wrong here: the alpha
|
|
112
|
+
* carries the diffuse luminance of the accumulated RGB, so it has to be summed
|
|
113
|
+
* alongside it — otherwise `SceneColor.a / luma(SceneColor.rgb)` under-reports
|
|
114
|
+
* the diffusible fraction as soon as a second light contributes, and the SSS
|
|
115
|
+
* passes would scatter only the first light's diffuse energy.
|
|
116
|
+
*/ updateRenderStates(pass, stateSet, ctx) {
|
|
117
|
+
super.updateRenderStates(pass, stateSet, ctx);
|
|
118
|
+
if (ctx.lightBlending && ctx.renderPass.type === RENDER_PASS_TYPE_LIGHT) {
|
|
119
|
+
const blendingState = stateSet.useBlendingState();
|
|
120
|
+
if (blendingState.enabled) {
|
|
121
|
+
blendingState.setBlendFuncAlpha('one', 'one');
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
clone() {
|
|
126
|
+
const other = new SSSMaterial();
|
|
127
|
+
other.copyFrom(this);
|
|
128
|
+
return other;
|
|
129
|
+
}
|
|
130
|
+
copyFrom(other) {
|
|
131
|
+
super.copyFrom(other);
|
|
132
|
+
// The values, not the profile: a clone owns its own row of the table, so
|
|
133
|
+
// that disposing either material cannot pull the parameters out from under
|
|
134
|
+
// the other.
|
|
135
|
+
this._profile.copyFrom(other._profile);
|
|
136
|
+
this.vertexNormal = other.vertexNormal;
|
|
137
|
+
this.vertexTangent = other.vertexTangent;
|
|
138
|
+
this.roughness = other.roughness;
|
|
139
|
+
this.specularF0 = other.specularF0;
|
|
140
|
+
this.transmissionStrength = other.transmissionStrength;
|
|
141
|
+
}
|
|
142
|
+
get vertexNormal() {
|
|
143
|
+
return this.featureUsed(SSSMaterial.FEATURE_VERTEX_NORMAL);
|
|
144
|
+
}
|
|
145
|
+
set vertexNormal(val) {
|
|
146
|
+
this.useFeature(SSSMaterial.FEATURE_VERTEX_NORMAL, !!val);
|
|
147
|
+
}
|
|
148
|
+
get vertexTangent() {
|
|
149
|
+
return this.featureUsed(SSSMaterial.FEATURE_VERTEX_TANGENT);
|
|
150
|
+
}
|
|
151
|
+
set vertexTangent(val) {
|
|
152
|
+
this.useFeature(SSSMaterial.FEATURE_VERTEX_TANGENT, !!val);
|
|
153
|
+
}
|
|
154
|
+
/** GGX base roughness the two specular lobes are derived from. */ get roughness() {
|
|
155
|
+
return this._roughness;
|
|
156
|
+
}
|
|
157
|
+
set roughness(val) {
|
|
158
|
+
const next = Math.max(0.045, Math.min(1, val ?? 0.5));
|
|
159
|
+
if (next !== this._roughness) {
|
|
160
|
+
this._roughness = next;
|
|
161
|
+
this.uniformChanged();
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/** Fresnel reflectance at normal incidence. */ get specularF0() {
|
|
165
|
+
return this._specularF0;
|
|
166
|
+
}
|
|
167
|
+
set specularF0(val) {
|
|
168
|
+
const next = Math.max(0, Math.min(0.2, val ?? 0.04));
|
|
169
|
+
if (next !== this._specularF0) {
|
|
170
|
+
this._specularF0 = next;
|
|
171
|
+
this.uniformChanged();
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/** Overall multiplier on the back-lit transmission. */ get transmissionStrength() {
|
|
175
|
+
return this._transmissionStrength;
|
|
176
|
+
}
|
|
177
|
+
set transmissionStrength(val) {
|
|
178
|
+
const next = Math.max(0, val ?? 1);
|
|
179
|
+
if (next !== this._transmissionStrength) {
|
|
180
|
+
this._transmissionStrength = next;
|
|
181
|
+
this.uniformChanged();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
vertexShader(scope) {
|
|
185
|
+
super.vertexShader(scope);
|
|
186
|
+
const pb = scope.$builder;
|
|
187
|
+
scope.$l.oPos = ShaderHelper.resolveVertexPosition(scope);
|
|
188
|
+
scope.$outputs.worldPos = pb.mul(ShaderHelper.getWorldMatrix(scope), pb.vec4(scope.oPos, 1)).xyz;
|
|
189
|
+
ShaderHelper.setClipSpacePosition(scope, pb.mul(ShaderHelper.getViewProjectionMatrix(scope), pb.vec4(scope.$outputs.worldPos, 1)));
|
|
190
|
+
if (this.vertexNormal) {
|
|
191
|
+
scope.$l.oNorm = ShaderHelper.resolveVertexNormal(scope);
|
|
192
|
+
scope.$outputs.wNorm = pb.mul(ShaderHelper.getNormalMatrix(scope), pb.vec4(scope.oNorm, 0)).xyz;
|
|
193
|
+
if (this.vertexTangent) {
|
|
194
|
+
scope.$l.oTangent = ShaderHelper.resolveVertexTangent(scope);
|
|
195
|
+
scope.$outputs.wTangent = pb.mul(ShaderHelper.getNormalMatrix(scope), pb.vec4(scope.oTangent.xyz, 0)).xyz;
|
|
196
|
+
scope.$outputs.wBinormal = pb.mul(pb.cross(scope.$outputs.wNorm, scope.$outputs.wTangent), scope.oTangent.w);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
fragmentShader(scope) {
|
|
201
|
+
super.fragmentShader(scope);
|
|
202
|
+
const pb = scope.$builder;
|
|
203
|
+
const that = this;
|
|
204
|
+
const lightPass = this.drawContext.renderPass.type === RENDER_PASS_TYPE_LIGHT;
|
|
205
|
+
// Declared outside `needFragmentColorInput` deliberately: that predicate is
|
|
206
|
+
// false in the prepass for an ordinary opaque material, so a declaration
|
|
207
|
+
// inside it would leave the uniform undefined and the prepass would write id
|
|
208
|
+
// 0 for every SSS pixel.
|
|
209
|
+
const depthPassProfileId = this.drawContext.renderPass.type === RENDER_PASS_TYPE_DEPTH && this.drawContext.sssProfileId;
|
|
210
|
+
if (lightPass || depthPassProfileId) {
|
|
211
|
+
scope.zSSSProfileId = pb.float().uniform(2);
|
|
212
|
+
}
|
|
213
|
+
if (this.needFragmentColorInput()) {
|
|
214
|
+
if (lightPass) {
|
|
215
|
+
scope.zSSSRoughness = pb.float().uniform(2);
|
|
216
|
+
scope.zSSSSpecularF0 = pb.float().uniform(2);
|
|
217
|
+
scope.zSSSLobeParams = pb.vec3().uniform(2);
|
|
218
|
+
// Transmission is compiled in only when the thickness it needs exists.
|
|
219
|
+
// The flag is part of the shader's cache key (render/lightpass.ts), and
|
|
220
|
+
// it also guards against the per-light additive path, which has no
|
|
221
|
+
// thickness texture and hands the BxDF a placeholder.
|
|
222
|
+
if (this.drawContext.transmissionThickness) {
|
|
223
|
+
scope.zSSSTransmissionStrength = pb.float().uniform(2);
|
|
224
|
+
// rgba32f, so WebGPU will only accept a non-filtering sampler here;
|
|
225
|
+
// the transmission profile is interpolated by hand for that reason.
|
|
226
|
+
scope.zSSSProfileTex = pb.tex2D().sampleType('unfilterable-float').uniform(2);
|
|
227
|
+
scope.zSSSProfileTexelSize = pb.vec2().uniform(2);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
scope.$l.albedo = this.calculateAlbedoColor(scope);
|
|
231
|
+
if (this.vertexColor) {
|
|
232
|
+
scope.albedo = pb.mul(scope.albedo, this.getVertexColor(scope));
|
|
233
|
+
}
|
|
234
|
+
if (this.drawContext.renderPass.type === RENDER_PASS_TYPE_LIGHT) {
|
|
235
|
+
const baseLightPass = !this.drawContext.lightBlending;
|
|
236
|
+
scope.$l.normalInfo = this.calculateNormalAndTBN(scope, scope.$inputs.worldPos, scope.$inputs.wNorm, scope.$inputs.wTangent, scope.$inputs.wBinormal);
|
|
237
|
+
scope.$l.normal = scope.normalInfo.normal;
|
|
238
|
+
scope.$l.viewVec = this.calculateViewVector(scope, scope.$inputs.worldPos);
|
|
239
|
+
scope.$l.roughness = scope.zSSSRoughness;
|
|
240
|
+
scope.$l.skinMask = pb.float(1);
|
|
241
|
+
if (this.subsurfaceTexture) {
|
|
242
|
+
scope.$l.subsurfaceTexel = this.sampleSubsurfaceTexture(scope);
|
|
243
|
+
scope.skinMask = pb.clamp(scope.subsurfaceTexel.r, 0, 1);
|
|
244
|
+
}
|
|
245
|
+
scope.$l.diffuseLighting = pb.vec3(0);
|
|
246
|
+
scope.$l.transmissionLighting = pb.vec3(0);
|
|
247
|
+
scope.$l.specularLighting = pb.vec3(0);
|
|
248
|
+
scope.$l.envSpecular = pb.vec3(0);
|
|
249
|
+
scope.$l.NoV = pb.clamp(pb.dot(scope.normal, scope.viewVec), 0.0001, 1);
|
|
250
|
+
scope.$l.lobeRoughness = skinDualSpecularRoughness(scope, scope.roughness, scope.skinMask, scope.zSSSLobeParams.x, scope.zSSSLobeParams.y);
|
|
251
|
+
scope.$l.avgLobeRoughness = pb.mix(scope.lobeRoughness.x, scope.lobeRoughness.y, scope.zSSSLobeParams.z);
|
|
252
|
+
scope.$l.energyTerms = skinSpecularEnergyTerms(scope, scope.avgLobeRoughness, scope.NoV, scope.zSSSSpecularF0);
|
|
253
|
+
// x scales specular back up to unit albedo; 1 - y is the energy left for
|
|
254
|
+
// the diffuse underneath.
|
|
255
|
+
scope.$l.energyConservation = scope.energyTerms.x;
|
|
256
|
+
scope.$l.energyPreservation = pb.sub(1, scope.energyTerms.y);
|
|
257
|
+
// --- Environment lighting ---
|
|
258
|
+
if (this.needCalculateEnvLight() && baseLightPass) {
|
|
259
|
+
scope.$l.envDiffuse = this.getEnvLightIrradiance(scope, scope.normal);
|
|
260
|
+
scope.diffuseLighting = pb.add(scope.diffuseLighting, scope.envDiffuse);
|
|
261
|
+
scope.$l.reflectVec = this.calculateReflectionVector(scope, scope.normal, scope.viewVec);
|
|
262
|
+
scope.$l.envEnergyTerms = skinSpecularEnergyTerms(scope, scope.roughness, scope.NoV, scope.zSSSSpecularF0);
|
|
263
|
+
scope.envSpecular = pb.mul(this.getEnvLightRadiance(scope, scope.reflectVec, scope.roughness), scope.envEnergyTerms.y);
|
|
264
|
+
}
|
|
265
|
+
this.forEachLight(scope, function(type, posRange, dirCutoff, colorIntensity, extra, shadow, thickness, unshadowedColorIntensity) {
|
|
266
|
+
this.$l.diffuseScale = pb.float(1);
|
|
267
|
+
this.$l.specularScale = pb.float(1);
|
|
268
|
+
this.$l.sourceRadiusFactor = pb.float(0);
|
|
269
|
+
this.$if(pb.equal(type, LIGHT_TYPE_POINT), function() {
|
|
270
|
+
this.diffuseScale = extra.x;
|
|
271
|
+
this.specularScale = extra.y;
|
|
272
|
+
this.sourceRadiusFactor = pb.div(extra.z, pb.max(pb.distance(posRange.xyz, this.$inputs.worldPos), 0.0001));
|
|
273
|
+
});
|
|
274
|
+
this.$l.lightAtten = that.calculateLightAttenuation(this, type, this.$inputs.worldPos, posRange, dirCutoff, extra);
|
|
275
|
+
this.$l.lightDir = that.calculateLightDirection(this, type, this.$inputs.worldPos, posRange, dirCutoff, extra);
|
|
276
|
+
this.$l.rawNdotL = pb.dot(this.normal, this.lightDir);
|
|
277
|
+
this.$l.NoL = pb.clamp(this.rawNdotL, 0, 1);
|
|
278
|
+
this.$l.VdotL = pb.dot(this.viewVec, this.lightDir);
|
|
279
|
+
// Shadow: pre-integrated BRDF handles NdotL internally, so pass a
|
|
280
|
+
// fixed bias to keep normal-offset stable at the terminator.
|
|
281
|
+
this.$l.shadowTerm = shadow ? that.calculateShadow(this, this.$inputs.worldPos, scope.normalInfo.TBN[2], pb.float(0.5)) : pb.float(1);
|
|
282
|
+
this.$l.lightColor = pb.mul(colorIntensity.rgb, colorIntensity.a, this.lightAtten);
|
|
283
|
+
this.$l.halfVec = pb.normalize(pb.add(this.viewVec, this.lightDir));
|
|
284
|
+
this.$l.NoH = pb.clamp(pb.dot(this.normal, this.halfVec), 0, 1);
|
|
285
|
+
this.$l.VoH = pb.clamp(pb.dot(this.viewVec, this.halfVec), 0, 1);
|
|
286
|
+
this.$l.skinDiff = skinDiffuseBRDF(this, this.NoV, this.NoL, this.VoH, this.roughness);
|
|
287
|
+
this.diffuseLighting = pb.add(this.diffuseLighting, pb.mul(this.lightColor, this.shadowTerm, this.skinDiff, this.NoL, this.diffuseScale));
|
|
288
|
+
if (that.drawContext.transmissionThickness) {
|
|
289
|
+
this.$l.transmission = skinTransmission(this, this.zSSSProfileTex, this.zSSSProfileTexelSize, this.zSSSProfileId, thickness, this.normal, this.viewVec, this.lightDir);
|
|
290
|
+
this.$l.transmissionLightColor = pb.mul(unshadowedColorIntensity.rgb, unshadowedColorIntensity.a, this.lightAtten);
|
|
291
|
+
this.transmissionLighting = pb.add(this.transmissionLighting, pb.mul(this.transmissionLightColor, this.transmission, thickness, this.zSSSTransmissionStrength, this.diffuseScale));
|
|
292
|
+
}
|
|
293
|
+
this.$l.spec = skinDualLobeSpecular(this, this.NoH, this.NoV, this.NoL, this.VoH, this.lobeRoughness, this.zSSSLobeParams.z, this.zSSSSpecularF0);
|
|
294
|
+
this.specularLighting = pb.add(this.specularLighting, pb.mul(this.lightColor, this.shadowTerm, this.spec, this.NoL, this.specularScale));
|
|
295
|
+
});
|
|
296
|
+
scope.$l.diffusible = pb.mul(scope.albedo.rgb, pb.add(pb.mul(scope.diffuseLighting, scope.energyPreservation), scope.transmissionLighting));
|
|
297
|
+
scope.specularLighting = pb.add(pb.mul(scope.specularLighting, scope.energyConservation), scope.envSpecular);
|
|
298
|
+
scope.$l.litColor = pb.add(scope.diffusible, scope.specularLighting);
|
|
299
|
+
scope.$l.diffLum = pb.dot(scope.diffusible, pb.vec3(0.2126, 0.7152, 0.0722));
|
|
300
|
+
scope.$l.postSSSMask = pb.vec4(pb.add(pb.mul(scope.normal, 0.5), pb.vec3(0.5)), scope.skinMask);
|
|
301
|
+
if (this.drawContext.materialFlags & (MaterialVaryingFlags.SCENE_STORE_ROUGHNESS | MaterialVaryingFlags.SCENE_STORE_NORMAL)) {
|
|
302
|
+
scope.$l.outRoughness = pb.vec4(pb.mul(scope.albedo.rgb, pb.sub(1, scope.roughness)), pb.mul(scope.roughness, ShaderHelper.getCameraRoughnessFactor(scope)));
|
|
303
|
+
this.outputFragmentColor(scope, scope.$inputs.worldPos, pb.vec4(scope.litColor, scope.diffLum), scope.outRoughness, pb.vec4(pb.add(pb.mul(scope.normal, 0.5), pb.vec3(0.5)), 1), undefined, undefined, undefined, undefined, false, scope.postSSSMask);
|
|
304
|
+
} else {
|
|
305
|
+
this.outputFragmentColor(scope, scope.$inputs.worldPos, pb.vec4(scope.litColor, scope.diffLum), undefined, undefined, undefined, undefined, undefined, undefined, false, scope.postSSSMask);
|
|
306
|
+
}
|
|
307
|
+
} else {
|
|
308
|
+
this.outputFragmentColor(scope, scope.$inputs.worldPos, scope.albedo);
|
|
309
|
+
}
|
|
310
|
+
} else {
|
|
311
|
+
this.outputFragmentColor(scope, scope.$inputs.worldPos, null);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* The profile id the depth prepass writes for this material.
|
|
316
|
+
*
|
|
317
|
+
* @remarks
|
|
318
|
+
* Overrides {@link MeshMaterial.getDepthPassProfileId}. The uniform is declared
|
|
319
|
+
* in {@link SSSMaterial.fragmentShader} for the prepass as well as the light
|
|
320
|
+
* pass, and bound below.
|
|
321
|
+
*/ getDepthPassProfileId(scope) {
|
|
322
|
+
return scope.zSSSProfileId;
|
|
323
|
+
}
|
|
324
|
+
applyUniformValues(bindGroup, ctx, pass) {
|
|
325
|
+
super.applyUniformValues(bindGroup, ctx, pass);
|
|
326
|
+
const lightPass = ctx.renderPass.type === RENDER_PASS_TYPE_LIGHT;
|
|
327
|
+
const depthPassProfileId = ctx.renderPass.type === RENDER_PASS_TYPE_DEPTH && ctx.sssProfileId;
|
|
328
|
+
// Not gated on needFragmentColor: the prepass declares this uniform for
|
|
329
|
+
// every SSS material, including the opaque ones that predicate excludes.
|
|
330
|
+
if (lightPass || depthPassProfileId) {
|
|
331
|
+
bindGroup.setValue('zSSSProfileId', this._profile.encodedId);
|
|
332
|
+
}
|
|
333
|
+
if (!this.needFragmentColor(ctx) || !lightPass) {
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
bindGroup.setValue('zSSSRoughness', this._roughness);
|
|
337
|
+
bindGroup.setValue('zSSSSpecularF0', this._specularF0);
|
|
338
|
+
const profile = this._profile;
|
|
339
|
+
bindGroup.setValue('zSSSLobeParams', this._lobeParams.setXYZ(profile.roughness0, profile.roughness1, profile.lobeMix));
|
|
340
|
+
if (ctx.transmissionThickness) {
|
|
341
|
+
bindGroup.setValue('zSSSTransmissionStrength', this._transmissionStrength);
|
|
342
|
+
const table = SSSProfile.getTable(ctx.device);
|
|
343
|
+
if (table) {
|
|
344
|
+
bindGroup.setTexture('zSSSProfileTex', table, fetchSampler('clamp_nearest_nomip'));
|
|
345
|
+
this._profileTexelSize.setXY(1 / SSSProfile.tableColumns, 1 / SSSProfile.tableRows);
|
|
346
|
+
bindGroup.setValue('zSSSProfileTexelSize', this._profileTexelSize);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
export { SKIN_SSS_LDR_ENCODE_RANGE, SSSMaterial };
|
|
353
|
+
//# sourceMappingURL=sss.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sss.js","sources":["../../src/material/sss.ts"],"sourcesContent":["import type { BindGroup, PBFunctionScope, PBInsideFunctionScope, RenderStateSet } from '@zephyr3d/device';\r\nimport { Vector2, Vector3, type Clonable } from '@zephyr3d/base';\r\nimport { MeshMaterial, applyMaterialMixins } from './meshmaterial';\r\nimport { mixinLight } from './mixins/lit';\r\nimport { mixinVertexColor } from './mixins/vertexcolor';\r\nimport { mixinTextureProps } from './mixins/texture';\r\nimport { ShaderHelper } from './shader/helper';\r\nimport type { DrawContext } from '../render';\r\nimport {\r\n LIGHT_TYPE_POINT,\r\n MaterialVaryingFlags,\r\n RENDER_PASS_TYPE_DEPTH,\r\n RENDER_PASS_TYPE_LIGHT\r\n} from '../values';\r\nimport {\r\n skinDiffuseBRDF,\r\n skinDualLobeSpecular,\r\n skinDualSpecularRoughness,\r\n skinSpecularEnergyTerms,\r\n skinTransmission\r\n} from '../shaders/skin_brdf';\r\nimport { SSSProfile } from './sssprofile';\r\nimport { fetchSampler } from '../utility/misc';\r\n\r\n/**\r\n * HDR range that used to be packed into the PostSSS side buffer when the render\r\n * graph fell back to an 8-bit format.\r\n *\r\n * @deprecated The SSS scattering source is now recovered from `SceneColor` via\r\n * the diffuse luminance stored in its alpha channel, so no side buffer and no\r\n * LDR encoding is involved. Kept for source compatibility; it has no effect on\r\n * rendering.\r\n *\r\n * @public\r\n */\r\nexport const SKIN_SSS_LDR_ENCODE_RANGE = 4;\r\n\r\n/**\r\n * Physically-based SSS material.\r\n *\r\n * @remarks\r\n * Uses a pre-integrated curvature-dependent diffuse BRDF and dual-lobe GGX specular\r\n * driven by subsurface profile parameters. The **diffuse** luminance is written to\r\n * `SceneColor.a` so the {@link PostSSS} post effect can recover the diffusible\r\n * fraction as `saturate(SceneColor.a / luma(SceneColor.rgb))`.\r\n *\r\n * The optional `subsurfaceTexture` uses R as the SSS mask, which gates both the\r\n * screen-space diffusion and the dual specular lobe. Its other channels are\r\n * unused: transmission thickness is measured against the light's shadow map by\r\n * the transmission thickness pass rather than painted, and curvature is not part\r\n * of this path.\r\n *\r\n * @public\r\n */\r\nexport class SSSMaterial\r\n extends applyMaterialMixins(MeshMaterial, mixinLight, mixinVertexColor, mixinTextureProps('subsurface'))\r\n implements Clonable<SSSMaterial>\r\n{\r\n private static readonly FEATURE_VERTEX_NORMAL = this.defineFeature();\r\n private static readonly FEATURE_VERTEX_TANGENT = this.defineFeature();\r\n private _roughness: number;\r\n private _specularF0: number;\r\n private _transmissionStrength: number;\r\n private readonly _profile: SSSProfile;\r\n private readonly _subsurfaceProfileChanged: () => void;\r\n private readonly _lobeParams: Vector3;\r\n private readonly _profileTexelSize: Vector2;\r\n\r\n constructor() {\r\n super();\r\n this._subsurfaceProfileChanged = () => this.uniformChanged();\r\n // Created here and released in onDispose: the profile holds a row of a\r\n // 256-entry GPU table, and tying its life to the material's is what keeps\r\n // those rows from accumulating.\r\n this._profile = SSSProfile.createOwned();\r\n this._profile.addChangeListener(this._subsurfaceProfileChanged);\r\n this._lobeParams = new Vector3();\r\n this._profileTexelSize = new Vector2();\r\n this._roughness = 0.5;\r\n this._specularF0 = 0.04;\r\n this._transmissionStrength = 1;\r\n this.useFeature(SSSMaterial.FEATURE_VERTEX_NORMAL, true);\r\n }\r\n\r\n /** Releases the profile's table row along with the material. */\r\n protected onDispose() {\r\n super.onDispose();\r\n this._profile.removeChangeListener(this._subsurfaceProfileChanged);\r\n this._profile.dispose();\r\n }\r\n\r\n /**\r\n * Marker used by the forward render graph to enable the PostSSS post effect.\r\n *\r\n * @remarks\r\n * This no longer allocates a side buffer: the scattering source is recovered\r\n * from `SceneColor` and its diffuse-luminance alpha.\r\n */\r\n get postSSS() {\r\n return true;\r\n }\r\n\r\n /**\r\n * The profile driving this material's subsurface scattering.\r\n *\r\n * @remarks\r\n * Read-only and never null: the material creates one in its constructor and\r\n * owns it for life, so edit it in place rather than assigning a new one.\r\n *\r\n * ```ts\r\n * material.subsurfaceProfile.preset = 'jade';\r\n * material.subsurfaceProfile.meanFreePathDistance = 0.03;\r\n * ```\r\n *\r\n * Per-material ownership is what lets face, ears and lips scatter differently\r\n * in a single screen-space pass: the material writes its profile's id per pixel\r\n * and the diffusion looks the parameters up from there. Profiles are therefore\r\n * not shared - to transfer a look, use {@link SSSProfile.copyFrom}.\r\n *\r\n * @public\r\n */\r\n get subsurfaceProfile(): SSSProfile {\r\n return this._profile;\r\n }\r\n\r\n /**\r\n * Keeps the diffuse luminance written to `SceneColor.a` instead of letting the\r\n * opaque path overwrite it with 1. {@link PostSSS} needs it to separate the\r\n * diffusible energy from the specular it must leave untouched.\r\n */\r\n protected preservesOpaqueAlpha(ctx: DrawContext): boolean {\r\n return ctx.renderPass!.type === RENDER_PASS_TYPE_LIGHT;\r\n }\r\n\r\n /**\r\n * Keeps `SceneColor.a` additive across the multi-pass light loop.\r\n *\r\n * @remarks\r\n * The base implementation uses `zero/one` for alpha so that additive light\r\n * passes preserve whatever the base pass wrote. That is wrong here: the alpha\r\n * carries the diffuse luminance of the accumulated RGB, so it has to be summed\r\n * alongside it — otherwise `SceneColor.a / luma(SceneColor.rgb)` under-reports\r\n * the diffusible fraction as soon as a second light contributes, and the SSS\r\n * passes would scatter only the first light's diffuse energy.\r\n */\r\n protected updateRenderStates(pass: number, stateSet: RenderStateSet, ctx: DrawContext) {\r\n super.updateRenderStates(pass, stateSet, ctx);\r\n if (ctx.lightBlending && ctx.renderPass!.type === RENDER_PASS_TYPE_LIGHT) {\r\n const blendingState = stateSet.useBlendingState();\r\n if (blendingState.enabled) {\r\n blendingState.setBlendFuncAlpha('one', 'one');\r\n }\r\n }\r\n }\r\n\r\n clone() {\r\n const other = new SSSMaterial();\r\n other.copyFrom(this);\r\n return other;\r\n }\r\n\r\n copyFrom(other: this) {\r\n super.copyFrom(other);\r\n // The values, not the profile: a clone owns its own row of the table, so\r\n // that disposing either material cannot pull the parameters out from under\r\n // the other.\r\n this._profile.copyFrom(other._profile);\r\n this.vertexNormal = other.vertexNormal;\r\n this.vertexTangent = other.vertexTangent;\r\n this.roughness = other.roughness;\r\n this.specularF0 = other.specularF0;\r\n this.transmissionStrength = other.transmissionStrength;\r\n }\r\n\r\n get vertexNormal() {\r\n return this.featureUsed<boolean>(SSSMaterial.FEATURE_VERTEX_NORMAL);\r\n }\r\n set vertexNormal(val) {\r\n this.useFeature(SSSMaterial.FEATURE_VERTEX_NORMAL, !!val);\r\n }\r\n\r\n get vertexTangent() {\r\n return this.featureUsed<boolean>(SSSMaterial.FEATURE_VERTEX_TANGENT);\r\n }\r\n set vertexTangent(val) {\r\n this.useFeature(SSSMaterial.FEATURE_VERTEX_TANGENT, !!val);\r\n }\r\n\r\n /** GGX base roughness the two specular lobes are derived from. */\r\n get roughness() {\r\n return this._roughness;\r\n }\r\n set roughness(val) {\r\n const next = Math.max(0.045, Math.min(1, val ?? 0.5));\r\n if (next !== this._roughness) {\r\n this._roughness = next;\r\n this.uniformChanged();\r\n }\r\n }\r\n\r\n /** Fresnel reflectance at normal incidence. */\r\n get specularF0() {\r\n return this._specularF0;\r\n }\r\n set specularF0(val) {\r\n const next = Math.max(0, Math.min(0.2, val ?? 0.04));\r\n if (next !== this._specularF0) {\r\n this._specularF0 = next;\r\n this.uniformChanged();\r\n }\r\n }\r\n\r\n /** Overall multiplier on the back-lit transmission. */\r\n get transmissionStrength() {\r\n return this._transmissionStrength;\r\n }\r\n set transmissionStrength(val) {\r\n const next = Math.max(0, val ?? 1);\r\n if (next !== this._transmissionStrength) {\r\n this._transmissionStrength = next;\r\n this.uniformChanged();\r\n }\r\n }\r\n\r\n vertexShader(scope: PBFunctionScope) {\r\n super.vertexShader(scope);\r\n const pb = scope.$builder;\r\n scope.$l.oPos = ShaderHelper.resolveVertexPosition(scope);\r\n scope.$outputs.worldPos = pb.mul(ShaderHelper.getWorldMatrix(scope), pb.vec4(scope.oPos, 1)).xyz;\r\n ShaderHelper.setClipSpacePosition(\r\n scope,\r\n pb.mul(ShaderHelper.getViewProjectionMatrix(scope), pb.vec4(scope.$outputs.worldPos, 1))\r\n );\r\n if (this.vertexNormal) {\r\n scope.$l.oNorm = ShaderHelper.resolveVertexNormal(scope);\r\n scope.$outputs.wNorm = pb.mul(ShaderHelper.getNormalMatrix(scope), pb.vec4(scope.oNorm, 0)).xyz;\r\n if (this.vertexTangent) {\r\n scope.$l.oTangent = ShaderHelper.resolveVertexTangent(scope);\r\n scope.$outputs.wTangent = pb.mul(\r\n ShaderHelper.getNormalMatrix(scope),\r\n pb.vec4(scope.oTangent.xyz, 0)\r\n ).xyz;\r\n scope.$outputs.wBinormal = pb.mul(\r\n pb.cross(scope.$outputs.wNorm, scope.$outputs.wTangent),\r\n scope.oTangent.w\r\n );\r\n }\r\n }\r\n }\r\n\r\n fragmentShader(scope: PBFunctionScope) {\r\n super.fragmentShader(scope);\r\n const pb = scope.$builder;\r\n const that = this;\r\n const lightPass = this.drawContext.renderPass!.type === RENDER_PASS_TYPE_LIGHT;\r\n // Declared outside `needFragmentColorInput` deliberately: that predicate is\r\n // false in the prepass for an ordinary opaque material, so a declaration\r\n // inside it would leave the uniform undefined and the prepass would write id\r\n // 0 for every SSS pixel.\r\n const depthPassProfileId =\r\n this.drawContext.renderPass!.type === RENDER_PASS_TYPE_DEPTH && this.drawContext.sssProfileId;\r\n if (lightPass || depthPassProfileId) {\r\n scope.zSSSProfileId = pb.float().uniform(2);\r\n }\r\n if (this.needFragmentColorInput()) {\r\n if (lightPass) {\r\n scope.zSSSRoughness = pb.float().uniform(2);\r\n scope.zSSSSpecularF0 = pb.float().uniform(2);\r\n scope.zSSSLobeParams = pb.vec3().uniform(2);\r\n // Transmission is compiled in only when the thickness it needs exists.\r\n // The flag is part of the shader's cache key (render/lightpass.ts), and\r\n // it also guards against the per-light additive path, which has no\r\n // thickness texture and hands the BxDF a placeholder.\r\n if (this.drawContext.transmissionThickness) {\r\n scope.zSSSTransmissionStrength = pb.float().uniform(2);\r\n // rgba32f, so WebGPU will only accept a non-filtering sampler here;\r\n // the transmission profile is interpolated by hand for that reason.\r\n scope.zSSSProfileTex = pb.tex2D().sampleType('unfilterable-float').uniform(2);\r\n scope.zSSSProfileTexelSize = pb.vec2().uniform(2);\r\n }\r\n }\r\n scope.$l.albedo = this.calculateAlbedoColor(scope);\r\n if (this.vertexColor) {\r\n scope.albedo = pb.mul(scope.albedo, this.getVertexColor(scope));\r\n }\r\n if (this.drawContext.renderPass!.type === RENDER_PASS_TYPE_LIGHT) {\r\n const baseLightPass = !this.drawContext.lightBlending;\r\n scope.$l.normalInfo = this.calculateNormalAndTBN(\r\n scope,\r\n scope.$inputs.worldPos,\r\n scope.$inputs.wNorm,\r\n scope.$inputs.wTangent,\r\n scope.$inputs.wBinormal\r\n );\r\n scope.$l.normal = scope.normalInfo.normal;\r\n scope.$l.viewVec = this.calculateViewVector(scope, scope.$inputs.worldPos);\r\n scope.$l.roughness = scope.zSSSRoughness;\r\n scope.$l.skinMask = pb.float(1);\r\n if (this.subsurfaceTexture) {\r\n scope.$l.subsurfaceTexel = this.sampleSubsurfaceTexture(scope);\r\n scope.skinMask = pb.clamp(scope.subsurfaceTexel.r, 0, 1);\r\n }\r\n scope.$l.diffuseLighting = pb.vec3(0);\r\n scope.$l.transmissionLighting = pb.vec3(0);\r\n scope.$l.specularLighting = pb.vec3(0);\r\n scope.$l.envSpecular = pb.vec3(0);\r\n scope.$l.NoV = pb.clamp(pb.dot(scope.normal, scope.viewVec), 0.0001, 1);\r\n scope.$l.lobeRoughness = skinDualSpecularRoughness(\r\n scope,\r\n scope.roughness,\r\n scope.skinMask,\r\n scope.zSSSLobeParams.x,\r\n scope.zSSSLobeParams.y\r\n );\r\n scope.$l.avgLobeRoughness = pb.mix(\r\n scope.lobeRoughness.x,\r\n scope.lobeRoughness.y,\r\n scope.zSSSLobeParams.z\r\n );\r\n scope.$l.energyTerms = skinSpecularEnergyTerms(\r\n scope,\r\n scope.avgLobeRoughness,\r\n scope.NoV,\r\n scope.zSSSSpecularF0\r\n );\r\n // x scales specular back up to unit albedo; 1 - y is the energy left for\r\n // the diffuse underneath.\r\n scope.$l.energyConservation = scope.energyTerms.x;\r\n scope.$l.energyPreservation = pb.sub(1, scope.energyTerms.y);\r\n // --- Environment lighting ---\r\n if (this.needCalculateEnvLight() && baseLightPass) {\r\n scope.$l.envDiffuse = this.getEnvLightIrradiance(scope, scope.normal);\r\n scope.diffuseLighting = pb.add(scope.diffuseLighting, scope.envDiffuse);\r\n scope.$l.reflectVec = this.calculateReflectionVector(scope, scope.normal, scope.viewVec);\r\n scope.$l.envEnergyTerms = skinSpecularEnergyTerms(\r\n scope,\r\n scope.roughness,\r\n scope.NoV,\r\n scope.zSSSSpecularF0\r\n );\r\n scope.envSpecular = pb.mul(\r\n this.getEnvLightRadiance(scope, scope.reflectVec, scope.roughness),\r\n scope.envEnergyTerms.y\r\n );\r\n }\r\n this.forEachLight(\r\n scope,\r\n function (\r\n type,\r\n posRange,\r\n dirCutoff,\r\n colorIntensity,\r\n extra,\r\n shadow,\r\n thickness,\r\n unshadowedColorIntensity\r\n ) {\r\n this.$l.diffuseScale = pb.float(1);\r\n this.$l.specularScale = pb.float(1);\r\n this.$l.sourceRadiusFactor = pb.float(0);\r\n this.$if(pb.equal(type, LIGHT_TYPE_POINT), function () {\r\n this.diffuseScale = extra.x;\r\n this.specularScale = extra.y;\r\n this.sourceRadiusFactor = pb.div(\r\n extra.z,\r\n pb.max(pb.distance(posRange.xyz, this.$inputs.worldPos), 0.0001)\r\n );\r\n });\r\n this.$l.lightAtten = that.calculateLightAttenuation(\r\n this,\r\n type,\r\n this.$inputs.worldPos,\r\n posRange,\r\n dirCutoff,\r\n extra\r\n );\r\n this.$l.lightDir = that.calculateLightDirection(\r\n this,\r\n type,\r\n this.$inputs.worldPos,\r\n posRange,\r\n dirCutoff,\r\n extra\r\n );\r\n this.$l.rawNdotL = pb.dot(this.normal, this.lightDir);\r\n this.$l.NoL = pb.clamp(this.rawNdotL, 0, 1);\r\n this.$l.VdotL = pb.dot(this.viewVec, this.lightDir);\r\n // Shadow: pre-integrated BRDF handles NdotL internally, so pass a\r\n // fixed bias to keep normal-offset stable at the terminator.\r\n this.$l.shadowTerm = shadow\r\n ? that.calculateShadow(this, this.$inputs.worldPos, scope.normalInfo.TBN[2], pb.float(0.5))\r\n : pb.float(1);\r\n this.$l.lightColor = pb.mul(colorIntensity.rgb, colorIntensity.a, this.lightAtten);\r\n this.$l.halfVec = pb.normalize(pb.add(this.viewVec, this.lightDir));\r\n this.$l.NoH = pb.clamp(pb.dot(this.normal, this.halfVec), 0, 1);\r\n this.$l.VoH = pb.clamp(pb.dot(this.viewVec, this.halfVec), 0, 1);\r\n this.$l.skinDiff = skinDiffuseBRDF(this, this.NoV, this.NoL, this.VoH, this.roughness);\r\n this.diffuseLighting = pb.add(\r\n this.diffuseLighting,\r\n pb.mul(this.lightColor, this.shadowTerm, this.skinDiff, this.NoL, this.diffuseScale)\r\n );\r\n if (that.drawContext.transmissionThickness) {\r\n this.$l.transmission = skinTransmission(\r\n this,\r\n this.zSSSProfileTex,\r\n this.zSSSProfileTexelSize,\r\n this.zSSSProfileId,\r\n thickness,\r\n this.normal,\r\n this.viewVec,\r\n this.lightDir\r\n );\r\n this.$l.transmissionLightColor = pb.mul(\r\n unshadowedColorIntensity.rgb,\r\n unshadowedColorIntensity.a,\r\n this.lightAtten\r\n );\r\n this.transmissionLighting = pb.add(\r\n this.transmissionLighting,\r\n pb.mul(\r\n this.transmissionLightColor,\r\n this.transmission,\r\n thickness,\r\n this.zSSSTransmissionStrength,\r\n this.diffuseScale\r\n )\r\n );\r\n }\r\n this.$l.spec = skinDualLobeSpecular(\r\n this,\r\n this.NoH,\r\n this.NoV,\r\n this.NoL,\r\n this.VoH,\r\n this.lobeRoughness,\r\n this.zSSSLobeParams.z,\r\n this.zSSSSpecularF0\r\n );\r\n this.specularLighting = pb.add(\r\n this.specularLighting,\r\n pb.mul(this.lightColor, this.shadowTerm, this.spec, this.NoL, this.specularScale)\r\n );\r\n }\r\n );\r\n scope.$l.diffusible = pb.mul(\r\n scope.albedo.rgb,\r\n pb.add(pb.mul(scope.diffuseLighting, scope.energyPreservation), scope.transmissionLighting)\r\n );\r\n scope.specularLighting = pb.add(\r\n pb.mul(scope.specularLighting, scope.energyConservation),\r\n scope.envSpecular\r\n );\r\n scope.$l.litColor = pb.add(scope.diffusible, scope.specularLighting);\r\n scope.$l.diffLum = pb.dot(scope.diffusible, pb.vec3(0.2126, 0.7152, 0.0722));\r\n scope.$l.postSSSMask = pb.vec4(pb.add(pb.mul(scope.normal, 0.5), pb.vec3(0.5)), scope.skinMask);\r\n if (\r\n this.drawContext.materialFlags &\r\n (MaterialVaryingFlags.SCENE_STORE_ROUGHNESS | MaterialVaryingFlags.SCENE_STORE_NORMAL)\r\n ) {\r\n scope.$l.outRoughness = pb.vec4(\r\n pb.mul(scope.albedo.rgb, pb.sub(1, scope.roughness)),\r\n pb.mul(scope.roughness, ShaderHelper.getCameraRoughnessFactor(scope))\r\n );\r\n this.outputFragmentColor(\r\n scope,\r\n scope.$inputs.worldPos,\r\n pb.vec4(scope.litColor, scope.diffLum),\r\n scope.outRoughness,\r\n pb.vec4(pb.add(pb.mul(scope.normal, 0.5), pb.vec3(0.5)), 1),\r\n undefined,\r\n undefined,\r\n undefined,\r\n undefined,\r\n false,\r\n scope.postSSSMask\r\n );\r\n } else {\r\n this.outputFragmentColor(\r\n scope,\r\n scope.$inputs.worldPos,\r\n pb.vec4(scope.litColor, scope.diffLum),\r\n undefined,\r\n undefined,\r\n undefined,\r\n undefined,\r\n undefined,\r\n undefined,\r\n false,\r\n scope.postSSSMask\r\n );\r\n }\r\n } else {\r\n this.outputFragmentColor(scope, scope.$inputs.worldPos, scope.albedo);\r\n }\r\n } else {\r\n this.outputFragmentColor(scope, scope.$inputs.worldPos, null);\r\n }\r\n }\r\n\r\n /**\r\n * The profile id the depth prepass writes for this material.\r\n *\r\n * @remarks\r\n * Overrides {@link MeshMaterial.getDepthPassProfileId}. The uniform is declared\r\n * in {@link SSSMaterial.fragmentShader} for the prepass as well as the light\r\n * pass, and bound below.\r\n */\r\n protected getDepthPassProfileId(scope: PBInsideFunctionScope) {\r\n return scope.zSSSProfileId;\r\n }\r\n\r\n applyUniformValues(bindGroup: BindGroup, ctx: DrawContext, pass: number) {\r\n super.applyUniformValues(bindGroup, ctx, pass);\r\n const lightPass = ctx.renderPass!.type === RENDER_PASS_TYPE_LIGHT;\r\n const depthPassProfileId = ctx.renderPass!.type === RENDER_PASS_TYPE_DEPTH && ctx.sssProfileId;\r\n // Not gated on needFragmentColor: the prepass declares this uniform for\r\n // every SSS material, including the opaque ones that predicate excludes.\r\n if (lightPass || depthPassProfileId) {\r\n bindGroup.setValue('zSSSProfileId', this._profile.encodedId);\r\n }\r\n if (!this.needFragmentColor(ctx) || !lightPass) {\r\n return;\r\n }\r\n bindGroup.setValue('zSSSRoughness', this._roughness);\r\n bindGroup.setValue('zSSSSpecularF0', this._specularF0);\r\n const profile = this._profile;\r\n bindGroup.setValue(\r\n 'zSSSLobeParams',\r\n this._lobeParams.setXYZ(profile.roughness0, profile.roughness1, profile.lobeMix)\r\n );\r\n if (ctx.transmissionThickness) {\r\n bindGroup.setValue('zSSSTransmissionStrength', this._transmissionStrength);\r\n const table = SSSProfile.getTable(ctx.device);\r\n if (table) {\r\n bindGroup.setTexture('zSSSProfileTex', table, fetchSampler('clamp_nearest_nomip'));\r\n this._profileTexelSize.setXY(1 / SSSProfile.tableColumns, 1 / SSSProfile.tableRows);\r\n bindGroup.setValue('zSSSProfileTexelSize', this._profileTexelSize);\r\n }\r\n }\r\n }\r\n}\r\n"],"names":["SKIN_SSS_LDR_ENCODE_RANGE","SSSMaterial","applyMaterialMixins","MeshMaterial","mixinLight","mixinVertexColor","mixinTextureProps","FEATURE_VERTEX_NORMAL","defineFeature","FEATURE_VERTEX_TANGENT","_roughness","_specularF0","_transmissionStrength","_profile","_subsurfaceProfileChanged","_lobeParams","_profileTexelSize","uniformChanged","SSSProfile","createOwned","addChangeListener","Vector3","Vector2","useFeature","onDispose","removeChangeListener","dispose","postSSS","subsurfaceProfile","preservesOpaqueAlpha","ctx","renderPass","type","RENDER_PASS_TYPE_LIGHT","pass","stateSet","updateRenderStates","lightBlending","blendingState","useBlendingState","enabled","setBlendFuncAlpha","clone","other","copyFrom","vertexNormal","vertexTangent","roughness","specularF0","transmissionStrength","featureUsed","val","next","Math","max","min","vertexShader","scope","pb","$builder","$l","oPos","ShaderHelper","resolveVertexPosition","$outputs","worldPos","mul","getWorldMatrix","vec4","xyz","setClipSpacePosition","getViewProjectionMatrix","oNorm","resolveVertexNormal","wNorm","getNormalMatrix","oTangent","resolveVertexTangent","wTangent","wBinormal","cross","w","fragmentShader","that","lightPass","drawContext","depthPassProfileId","RENDER_PASS_TYPE_DEPTH","sssProfileId","zSSSProfileId","float","uniform","needFragmentColorInput","zSSSRoughness","zSSSSpecularF0","zSSSLobeParams","vec3","transmissionThickness","zSSSTransmissionStrength","zSSSProfileTex","tex2D","sampleType","zSSSProfileTexelSize","vec2","albedo","calculateAlbedoColor","vertexColor","getVertexColor","baseLightPass","normalInfo","calculateNormalAndTBN","$inputs","normal","viewVec","calculateViewVector","skinMask","subsurfaceTexture","subsurfaceTexel","sampleSubsurfaceTexture","clamp","r","diffuseLighting","transmissionLighting","specularLighting","envSpecular","NoV","dot","lobeRoughness","skinDualSpecularRoughness","x","y","avgLobeRoughness","mix","z","energyTerms","skinSpecularEnergyTerms","energyConservation","energyPreservation","sub","needCalculateEnvLight","envDiffuse","getEnvLightIrradiance","add","reflectVec","calculateReflectionVector","envEnergyTerms","getEnvLightRadiance","forEachLight","posRange","dirCutoff","colorIntensity","extra","shadow","thickness","unshadowedColorIntensity","diffuseScale","specularScale","sourceRadiusFactor","$if","equal","LIGHT_TYPE_POINT","div","distance","lightAtten","calculateLightAttenuation","lightDir","calculateLightDirection","rawNdotL","NoL","VdotL","shadowTerm","calculateShadow","TBN","lightColor","rgb","a","halfVec","normalize","NoH","VoH","skinDiff","skinDiffuseBRDF","transmission","skinTransmission","transmissionLightColor","spec","skinDualLobeSpecular","diffusible","litColor","diffLum","postSSSMask","materialFlags","MaterialVaryingFlags","SCENE_STORE_ROUGHNESS","SCENE_STORE_NORMAL","outRoughness","getCameraRoughnessFactor","outputFragmentColor","undefined","getDepthPassProfileId","applyUniformValues","bindGroup","setValue","encodedId","needFragmentColor","profile","setXYZ","roughness0","roughness1","lobeMix","table","getTable","device","setTexture","fetchSampler","setXY","tableColumns","tableRows"],"mappings":"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"}
|