@zephyr3d/scene 0.9.25 → 0.9.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/animation/animationset.js +92 -30
- package/dist/animation/animationset.js.map +1 -1
- package/dist/animation/hair/gpu_hair_simulation.js +1090 -0
- package/dist/animation/hair/gpu_hair_simulation.js.map +1 -0
- package/dist/animation/joint_dynamics/controller.js +7 -5
- package/dist/animation/joint_dynamics/controller.js.map +1 -1
- package/dist/animation/joint_dynamics/convex_collider.js +320 -0
- package/dist/animation/joint_dynamics/convex_collider.js.map +1 -0
- package/dist/animation/joint_dynamics/joint_dynamics_system.js +81 -5
- package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
- package/dist/animation/morphtrack.js +3 -4
- package/dist/animation/morphtrack.js.map +1 -1
- package/dist/animation/skeleton.js +79 -25
- package/dist/animation/skeleton.js.map +1 -1
- package/dist/animation/spring/multi_chain_spring_system.js +577 -179
- package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
- package/dist/animation/spring/spring_collider.js +4 -3
- package/dist/animation/spring/spring_collider.js.map +1 -1
- package/dist/animation/spring/spring_node_pose_tracker.js +40 -0
- package/dist/animation/spring/spring_node_pose_tracker.js.map +1 -0
- package/dist/animation/spring/spring_particle.js +2 -0
- package/dist/animation/spring/spring_particle.js.map +1 -1
- package/dist/animation/spring/spring_system.js +11 -3
- package/dist/animation/spring/spring_system.js.map +1 -1
- package/dist/animation/spring_modifier.js +10 -0
- package/dist/animation/spring_modifier.js.map +1 -1
- package/dist/app/engine.js +53 -43
- package/dist/app/engine.js.map +1 -1
- package/dist/app/scriptingsystem.js +119 -6
- package/dist/app/scriptingsystem.js.map +1 -1
- package/dist/app/scriptregistry.js +3 -2
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/assetmanager.js +284 -67
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/loaders/zhair/zhair_format.js +288 -0
- package/dist/asset/loaders/zhair/zhair_format.js.map +1 -0
- package/dist/asset/loaders/zhair/zhair_loader.js +221 -0
- package/dist/asset/loaders/zhair/zhair_loader.js.map +1 -0
- package/dist/asset/model.js +184 -69
- package/dist/asset/model.js.map +1 -1
- package/dist/camera/camera.js +268 -44
- package/dist/camera/camera.js.map +1 -1
- package/dist/camera/perspectivecamera.js +3 -1
- package/dist/camera/perspectivecamera.js.map +1 -1
- package/dist/index.d.ts +9044 -5139
- package/dist/index.js +17 -6
- package/dist/index.js.map +1 -1
- package/dist/material/eye.js +932 -0
- package/dist/material/eye.js.map +1 -0
- package/dist/material/hair.js +917 -0
- package/dist/material/hair.js.map +1 -0
- package/dist/material/hairstrand.js +842 -0
- package/dist/material/hairstrand.js.map +1 -0
- package/dist/material/hairstrand_data.js +162 -0
- package/dist/material/hairstrand_data.js.map +1 -0
- package/dist/material/lambert.js +5 -2
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/material.js +48 -10
- package/dist/material/material.js.map +1 -1
- package/dist/material/meshmaterial.js +120 -19
- package/dist/material/meshmaterial.js.map +1 -1
- package/dist/material/mixins/albedocolor.js +1 -1
- package/dist/material/mixins/albedocolor.js.map +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js +5 -3
- package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
- package/dist/material/mixins/lightmodel/lambert.js +5 -4
- package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +3 -3
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +5 -5
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js +3 -3
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
- package/dist/material/mixins/lit.js +106 -19
- package/dist/material/mixins/lit.js.map +1 -1
- package/dist/material/mixins/pbr/common.js +4 -4
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/material/mixins/texture.js +48 -11
- package/dist/material/mixins/texture.js.map +1 -1
- package/dist/material/mtoon.js +6 -5
- package/dist/material/mtoon.js.map +1 -1
- package/dist/material/pbrblueprint.js +146 -28
- package/dist/material/pbrblueprint.js.map +1 -1
- package/dist/material/pbrblueprint_instance.js +501 -0
- package/dist/material/pbrblueprint_instance.js.map +1 -0
- package/dist/material/pbrmr.js +15 -16
- package/dist/material/pbrmr.js.map +1 -1
- package/dist/material/shader/helper.js +734 -23
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/shader/terrain_blend.js +55 -0
- package/dist/material/shader/terrain_blend.js.map +1 -0
- package/dist/material/skin.js +192 -32
- package/dist/material/skin.js.map +1 -1
- package/dist/material/spriteblueprint.js +16 -1
- package/dist/material/spriteblueprint.js.map +1 -1
- package/dist/material/subsurfaceprofile.js +86 -23
- package/dist/material/subsurfaceprofile.js.map +1 -1
- package/dist/material/water.js +2059 -72
- package/dist/material/water.js.map +1 -1
- package/dist/posteffect/bloom.js +167 -7
- package/dist/posteffect/bloom.js.map +1 -1
- package/dist/posteffect/coloradjust.js +2 -1
- package/dist/posteffect/coloradjust.js.map +1 -1
- package/dist/posteffect/compositor.js.map +1 -1
- package/dist/posteffect/fxaa.js +2 -1
- package/dist/posteffect/fxaa.js.map +1 -1
- package/dist/posteffect/grayscale.js +3 -1
- package/dist/posteffect/grayscale.js.map +1 -1
- package/dist/posteffect/motionblur.js +664 -56
- 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/sao.js +46 -44
- package/dist/posteffect/sao.js.map +1 -1
- package/dist/posteffect/skinsss.js +368 -69
- package/dist/posteffect/skinsss.js.map +1 -1
- package/dist/posteffect/ssgi.js +16 -9
- package/dist/posteffect/ssgi.js.map +1 -1
- package/dist/posteffect/ssr.js +3 -0
- package/dist/posteffect/ssr.js.map +1 -1
- package/dist/posteffect/sss.js +121 -36
- package/dist/posteffect/sss.js.map +1 -1
- package/dist/posteffect/taa.js.map +1 -1
- package/dist/posteffect/tonemap.js +44 -1
- package/dist/posteffect/tonemap.js.map +1 -1
- package/dist/render/abuffer_oit.js +8 -2
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/clipmap.js +156 -5
- package/dist/render/clipmap.js.map +1 -1
- package/dist/render/cull_visitor.js +20 -0
- package/dist/render/cull_visitor.js.map +1 -1
- package/dist/render/depthpass.js +36 -2
- package/dist/render/depthpass.js.map +1 -1
- package/dist/render/drawable_mixin.js +26 -1
- package/dist/render/drawable_mixin.js.map +1 -1
- package/dist/render/dualdepthpeeling_oit.js +3 -2
- package/dist/render/dualdepthpeeling_oit.js.map +1 -1
- package/dist/render/envlight.js +1 -1
- package/dist/render/envlight.js.map +1 -1
- package/dist/render/fbm_wavegenerator.js +6 -3
- package/dist/render/fbm_wavegenerator.js.map +1 -1
- package/dist/render/fft_wavegenerator.js +57 -15
- package/dist/render/fft_wavegenerator.js.map +1 -1
- package/dist/render/gerstner_wavegenerator.js +130 -20
- package/dist/render/gerstner_wavegenerator.js.map +1 -1
- package/dist/render/globalbindgroup_allocator.js +3 -0
- package/dist/render/globalbindgroup_allocator.js.map +1 -1
- package/dist/render/hzb.js +80 -22
- package/dist/render/hzb.js.map +1 -1
- package/dist/render/lightpass.js +6 -3
- package/dist/render/lightpass.js.map +1 -1
- package/dist/render/oit.js +29 -0
- package/dist/render/oit.js.map +1 -0
- package/dist/render/render_queue.js +39 -0
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/renderer.js +4 -0
- package/dist/render/renderer.js.map +1 -1
- package/dist/render/rendergraph/blackboard.js +1 -0
- package/dist/render/rendergraph/blackboard.js.map +1 -1
- package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
- package/dist/render/rendergraph/executor.js +2 -0
- package/dist/render/rendergraph/executor.js.map +1 -1
- package/dist/render/rendergraph/forward_plus_builder.js +379 -10
- 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/rendergraph.js.map +1 -1
- package/dist/render/rendergraph/texture_affinity_cache.js +1 -1
- package/dist/render/rendergraph/texture_affinity_cache.js.map +1 -1
- package/dist/render/rendergraph/types.js.map +1 -1
- package/dist/render/shadow_mask_pass.js +73 -8
- package/dist/render/shadow_mask_pass.js.map +1 -1
- package/dist/render/sky.js +166 -126
- package/dist/render/sky.js.map +1 -1
- package/dist/render/underwater.js +624 -0
- package/dist/render/underwater.js.map +1 -0
- package/dist/render/water_caustics.js +1380 -0
- package/dist/render/water_caustics.js.map +1 -0
- package/dist/render/weightedblended_oit.js +3 -2
- package/dist/render/weightedblended_oit.js.map +1 -1
- package/dist/scene/basesprite.js +8 -0
- package/dist/scene/basesprite.js.map +1 -1
- package/dist/scene/batchgroup.js +3 -0
- package/dist/scene/batchgroup.js.map +1 -1
- package/dist/scene/environment.js +4 -1
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/hair.js +963 -0
- package/dist/scene/hair.js.map +1 -0
- package/dist/scene/light.js +5 -1
- package/dist/scene/light.js.map +1 -1
- package/dist/scene/mesh.js +481 -47
- 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 +3 -0
- package/dist/scene/msdftext.js.map +1 -1
- package/dist/scene/msdftextsprite.js +3 -0
- package/dist/scene/msdftextsprite.js.map +1 -1
- package/dist/scene/particlesys.js +6 -0
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/scene.js +3 -0
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/scene_node.js +6 -1
- package/dist/scene/scene_node.js.map +1 -1
- package/dist/scene/terrain-cm/grass.js +3 -0
- package/dist/scene/terrain-cm/grass.js.map +1 -1
- package/dist/scene/terrain-cm/grassmaterial.js +3 -0
- package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +6 -0
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/scene/terrain-cm/texture_cache.js +309 -0
- package/dist/scene/terrain-cm/texture_cache.js.map +1 -0
- package/dist/scene/water.js +546 -4
- package/dist/scene/water.js.map +1 -1
- package/dist/shaders/atmosphere.js.map +1 -1
- package/dist/shaders/diffusion.js +54 -0
- package/dist/shaders/diffusion.js.map +1 -0
- package/dist/shaders/shadow.js +33 -21
- package/dist/shaders/shadow.js.map +1 -1
- package/dist/shaders/temporal.js +71 -33
- package/dist/shaders/temporal.js.map +1 -1
- package/dist/shaders/water.js +22 -19
- package/dist/shaders/water.js.map +1 -1
- package/dist/shaders/water_medium.js +56 -0
- package/dist/shaders/water_medium.js.map +1 -0
- package/dist/shadow/dom.js +546 -0
- package/dist/shadow/dom.js.map +1 -0
- package/dist/shadow/pcf_opt.js +3 -5
- package/dist/shadow/pcf_opt.js.map +1 -1
- package/dist/shadow/pcf_pd.js +1 -1
- package/dist/shadow/pcf_pd.js.map +1 -1
- package/dist/shadow/receiver_bias.js +41 -0
- package/dist/shadow/receiver_bias.js.map +1 -0
- package/dist/shadow/shader.js +20 -60
- package/dist/shadow/shader.js.map +1 -1
- package/dist/shadow/shadow_impl.js +89 -0
- package/dist/shadow/shadow_impl.js.map +1 -1
- package/dist/shadow/shadow_region.js +1 -1
- package/dist/shadow/shadow_region.js.map +1 -1
- package/dist/shadow/shadowmapper.js +150 -37
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shapes/shape.js +11 -2
- package/dist/shapes/shape.js.map +1 -1
- package/dist/shapes/sphere.js +50 -9
- package/dist/shapes/sphere.js.map +1 -1
- package/dist/utility/blueprint/common/constants.js +112 -2
- package/dist/utility/blueprint/common/constants.js.map +1 -1
- package/dist/utility/blueprint/material/func.js +142 -49
- package/dist/utility/blueprint/material/func.js.map +1 -1
- package/dist/utility/blueprint/material/ir.js +490 -25
- package/dist/utility/blueprint/material/ir.js.map +1 -1
- package/dist/utility/blueprint/material/texture.js +898 -4
- package/dist/utility/blueprint/material/texture.js.map +1 -1
- package/dist/utility/serialization/manager.js +434 -101
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +401 -5
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/batch.js +4 -0
- package/dist/utility/serialization/scene/batch.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +186 -26
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/common.js +26 -5
- package/dist/utility/serialization/scene/common.js.map +1 -1
- package/dist/utility/serialization/scene/hair.js +1141 -0
- package/dist/utility/serialization/scene/hair.js.map +1 -0
- package/dist/utility/serialization/scene/light.js +84 -4
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +1867 -166
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +231 -14
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +141 -7
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/particle.js +4 -0
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/primitive.js +18 -0
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +4 -0
- package/dist/utility/serialization/scene/sprite.js.map +1 -1
- package/dist/utility/serialization/scene/terrain.js +4 -0
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/text.js +4 -0
- package/dist/utility/serialization/scene/text.js.map +1 -1
- package/dist/utility/serialization/scene/water.js +1105 -21
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/utility/serialization/types.js.map +1 -1
- package/dist/utility/shprojector.js +9 -8
- package/dist/utility/shprojector.js.map +1 -1
- package/dist/values.js +49 -2
- package/dist/values.js.map +1 -1
- package/package.json +3 -3
- package/dist/render/rendergraph/frame_graph_context.js +0 -41
- package/dist/render/rendergraph/frame_graph_context.js.map +0 -1
- package/dist/shaders/ssgi.js +0 -63
- package/dist/shaders/ssgi.js.map +0 -1
- package/dist/shaders/ssgi_reprojection.js +0 -118
- package/dist/shaders/ssgi_reprojection.js.map +0 -1
package/dist/posteffect/sss.js
CHANGED
|
@@ -6,9 +6,12 @@ import '../material/unlit.js';
|
|
|
6
6
|
import '../material/particle.js';
|
|
7
7
|
import { SubsurfaceProfile } from '../material/subsurfaceprofile.js';
|
|
8
8
|
import '../material/skin.js';
|
|
9
|
+
import '../material/eye.js';
|
|
9
10
|
import '@zephyr3d/device';
|
|
10
11
|
import { LIGHT_TYPE_DIRECTIONAL, LIGHT_TYPE_POINT, LIGHT_TYPE_SPOT, LIGHT_TYPE_RECT } from '../values.js';
|
|
11
12
|
import '../material/meshmaterial.js';
|
|
13
|
+
import '../material/hair.js';
|
|
14
|
+
import '../material/hairstrand.js';
|
|
12
15
|
import '../material/grassmaterial.js';
|
|
13
16
|
import '../material/terrain-cm.js';
|
|
14
17
|
import '../material/pbrmr.js';
|
|
@@ -32,11 +35,12 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
32
35
|
* @internal
|
|
33
36
|
*/ class SSS extends AbstractPostEffect {
|
|
34
37
|
static _profileLUTWidth = 256;
|
|
35
|
-
static _profileLUTHeight =
|
|
38
|
+
static _profileLUTHeight = 8;
|
|
36
39
|
static _profileRadiusEncodeMax = 8;
|
|
37
40
|
static _profileWorldScaleEncodeMax = 4;
|
|
38
41
|
static _profileNormalScaleEncodeMax = 2;
|
|
39
42
|
static _profileExtinctionEncodeMax = 4;
|
|
43
|
+
static _profileSpecularRadiusEncodeMax = 4;
|
|
40
44
|
static _debugViewMap = {
|
|
41
45
|
none: 0,
|
|
42
46
|
scatter_mask: 1,
|
|
@@ -187,6 +191,7 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
187
191
|
bindGroup.setValue('targetSize', new Vector4(targetWidth, targetHeight, targetWidth, targetHeight));
|
|
188
192
|
bindGroup.setValue('sampleOffsets', this.createSampleOffsets(kernelRadius));
|
|
189
193
|
bindGroup.setValue('blurScale', ctx.camera.sssBlurScale);
|
|
194
|
+
bindGroup.setValue('sssStrength', ctx.camera.sssStrength);
|
|
190
195
|
bindGroup.setValue('blurStdDev', sssSettings.blurStdDev);
|
|
191
196
|
bindGroup.setValue('depthCutoff', sssSettings.blurDepthCutoff);
|
|
192
197
|
bindGroup.setValue('normalCutoff', sssSettings.normalCutoff);
|
|
@@ -368,6 +373,7 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
368
373
|
this.targetSize = pb.vec4().uniform(0);
|
|
369
374
|
this.sampleOffsets = pb.vec4[sampleCount + 1]().uniform(0);
|
|
370
375
|
this.blurScale = pb.float().uniform(0);
|
|
376
|
+
this.sssStrength = pb.float().uniform(0);
|
|
371
377
|
this.blurStdDev = pb.float().uniform(0);
|
|
372
378
|
this.depthCutoff = pb.float().uniform(0);
|
|
373
379
|
this.normalCutoff = pb.float().uniform(0);
|
|
@@ -487,7 +493,8 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
487
493
|
this.$l.profileScatterScaleNorm = pb.clamp(pb.div(this.profileScatterScale, SSS._profileWorldScaleEncodeMax), 0, 1);
|
|
488
494
|
this.$l.profileStrengthNorm = pb.clamp(pb.mul(this.profileStrengthScale, 0.5), 0, 1);
|
|
489
495
|
this.$l.depthThreshold = pb.div(pb.mul(this.depthCutoff, pb.add(0.45, pb.mul(this.widthStrength, 0.42)), pb.mix(0.88, 1.16, this.profileWorldScaleNorm)), pb.max(pb.sub(pb.log(pb.add(this.cameraNearFar.y, 1)), pb.log(pb.add(this.cameraNearFar.x, 1))), 1e-4));
|
|
490
|
-
this.$l.
|
|
496
|
+
this.$l.normalDetailSoftening = pb.mul(pb.clamp(this.sssStrength, 0, 1), pb.add(0.14, pb.mul(this.widthStrength, 0.1)));
|
|
497
|
+
this.$l.normalThreshold = pb.clamp(pb.add(pb.max(pb.sub(this.normalCutoff, pb.add(this.normalDetailSoftening, pb.mul(this.widthStrength, 0.12))), 0.48), pb.sub(pb.mul(this.profileNormalScale, 0.08), 0.08), pb.neg(pb.mul(this.profileBoundaryBleed, 0.04))), 0.44, 0.92);
|
|
491
498
|
this.$l.centerNormal = this.decodeNormal(this.uv);
|
|
492
499
|
this.$l.profileRadius = pb.mul(this.readProfileRadius(this.centerSlot), this.profileWorldScale, pb.mix(0.76, 1.44, this.profileScatterScaleNorm), pb.mix(0.92, 1.08, this.profileStrengthNorm));
|
|
493
500
|
this.$l.profileFalloff = this.readProfileFalloff(this.centerSlot);
|
|
@@ -683,15 +690,17 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
683
690
|
this.$l.raw = pb.textureSampleLevel(this.profileLUTTex, this.uv, 0);
|
|
684
691
|
this.$return(pb.vec4(pb.mul(this.raw.x, SSS._profileExtinctionEncodeMax), pb.mul(this.raw.y, SSS._profileWorldScaleEncodeMax), pb.mul(this.raw.z, 2), this.raw.w));
|
|
685
692
|
});
|
|
686
|
-
pb.func('
|
|
687
|
-
pb.
|
|
693
|
+
pb.func('readProfileSpecularSettings', [
|
|
694
|
+
pb.float('slot')
|
|
688
695
|
], function() {
|
|
689
|
-
this.$
|
|
696
|
+
this.$l.uv = pb.vec2(pb.div(pb.add(this.slot, 0.5), SSS._profileLUTWidth), SSS.profileRowV(7));
|
|
697
|
+
this.$l.raw = pb.textureSampleLevel(this.profileLUTTex, this.uv, 0);
|
|
698
|
+
this.$return(pb.vec2(this.raw.x, pb.mul(this.raw.y, SSS._profileSpecularRadiusEncodeMax)));
|
|
690
699
|
});
|
|
691
|
-
pb.func('
|
|
700
|
+
pb.func('readProfileSlot', [
|
|
692
701
|
pb.vec4('param')
|
|
693
702
|
], function() {
|
|
694
|
-
this.$return(pb.floor(pb.add(pb.mul(this.param.
|
|
703
|
+
this.$return(pb.floor(pb.add(pb.mul(this.param.r, 255), 0.5)));
|
|
695
704
|
});
|
|
696
705
|
pb.func('decodeNormal', [
|
|
697
706
|
pb.vec2('uv')
|
|
@@ -707,6 +716,26 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
707
716
|
], function() {
|
|
708
717
|
this.$return(ShaderHelper.sampleLinearDepth(this, this.depthTex, this.uv, 0));
|
|
709
718
|
});
|
|
719
|
+
pb.func('sampleCompatibleSpecular', [
|
|
720
|
+
pb.vec2('uv'),
|
|
721
|
+
pb.float('profileSlot'),
|
|
722
|
+
pb.float('centerLogDepth')
|
|
723
|
+
], function() {
|
|
724
|
+
this.$l.sampleUV = pb.clamp(this.uv, pb.vec2(0), pb.vec2(1));
|
|
725
|
+
this.$l.sampleParam = pb.textureSampleLevel(this.paramTex, this.sampleUV, 0);
|
|
726
|
+
this.$l.sampleSlot = this.readProfileSlot(this.sampleParam);
|
|
727
|
+
this.$l.sampleDepth01 = this.readDepth01(this.sampleUV);
|
|
728
|
+
this.$if(pb.or(pb.or(pb.lessThanEqual(this.sampleParam.a, 0.5), pb.notEqual(this.sampleSlot, this.profileSlot)), pb.greaterThanEqual(this.sampleDepth01, 1)), function() {
|
|
729
|
+
this.$return(pb.vec4(0));
|
|
730
|
+
});
|
|
731
|
+
this.$l.sampleLogDepth = pb.log(pb.add(pb.mul(this.sampleDepth01, this.cameraNearFar.y), 1));
|
|
732
|
+
this.$if(pb.greaterThan(pb.abs(pb.sub(this.sampleLogDepth, this.centerLogDepth)), 0.022), function() {
|
|
733
|
+
this.$return(pb.vec4(0));
|
|
734
|
+
});
|
|
735
|
+
this.$l.sampleScene = pb.textureSampleLevel(this.colorTex, this.sampleUV, 0).rgb;
|
|
736
|
+
this.$l.sampleDiffuse = pb.textureSampleLevel(this.diffuseTex, this.sampleUV, 0).rgb;
|
|
737
|
+
this.$return(pb.vec4(pb.max(pb.sub(this.sampleScene, this.sampleDiffuse), pb.vec3(0)), 1));
|
|
738
|
+
});
|
|
710
739
|
pb.func('estimateScreenThinnessComponents', [
|
|
711
740
|
pb.vec2('uv'),
|
|
712
741
|
pb.float('depth01'),
|
|
@@ -714,13 +743,27 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
714
743
|
pb.float('radiusScale')
|
|
715
744
|
], function() {
|
|
716
745
|
this.$l.pixelStep = pb.div(pb.add(pb.vec2(1.2), pb.mul(pb.vec2(2.4), this.radiusScale)), this.targetSize.xy);
|
|
746
|
+
// Depth differences are accumulated as a ratio to the center depth
|
|
747
|
+
// rather than raw. readDepth01 returns linear depth already divided
|
|
748
|
+
// by the far plane, so both terms carry the same normalization and
|
|
749
|
+
// it cancels: |dz|/z is a pure ratio, independent of the far plane,
|
|
750
|
+
// of the camera distance, and of the scale the model was built at.
|
|
751
|
+
//
|
|
752
|
+
// The raw difference this replaces was scaled by a fixed constant
|
|
753
|
+
// instead, which left sensitivity proportional to 1 / farPlane - an
|
|
754
|
+
// otherwise identical scene with far = 1000 got a tenth the response
|
|
755
|
+
// of one with far = 100. At ordinary far planes the interior
|
|
756
|
+
// collapsed to zero and only the silhouette survived, where the
|
|
757
|
+
// difference saturates no matter how it is scaled. That is what made
|
|
758
|
+
// automatic thin-region inference read as an outline.
|
|
759
|
+
this.$l.invCenterDepth = pb.div(1, pb.max(this.depth01, 1e-5));
|
|
717
760
|
this.$l.depthAccum = pb.float(0);
|
|
718
761
|
this.$l.normalAccum = pb.float(0);
|
|
719
762
|
this.$l.sampleCount = pb.float(0);
|
|
720
763
|
const sampleAt = (offsetX, offsetY)=>{
|
|
721
764
|
this.$l.sampleUV = pb.clamp(pb.add(this.uv, pb.mul(this.pixelStep, pb.vec2(offsetX, offsetY))), pb.vec2(0), pb.vec2(1));
|
|
722
765
|
this.$l.sampleDepth01 = this.readDepth01(this.sampleUV);
|
|
723
|
-
this.depthAccum = pb.add(this.depthAccum, pb.abs(pb.sub(this.sampleDepth01, this.depth01)));
|
|
766
|
+
this.depthAccum = pb.add(this.depthAccum, pb.mul(pb.abs(pb.sub(this.sampleDepth01, this.depth01)), this.invCenterDepth));
|
|
724
767
|
this.$if(pb.notEqual(this.hasNormalTex, 0), function() {
|
|
725
768
|
this.normalAccum = pb.add(this.normalAccum, pb.clamp(pb.sub(1, pb.dot(this.decodeNormal(this.sampleUV), this.normalWS)), 0, 1));
|
|
726
769
|
});
|
|
@@ -734,7 +777,21 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
734
777
|
sampleAt(-1, -1);
|
|
735
778
|
this.$l.depthMean = pb.div(this.depthAccum, pb.max(this.sampleCount, 1));
|
|
736
779
|
this.$l.normalMean = pb.div(this.normalAccum, pb.max(this.sampleCount, 1));
|
|
737
|
-
|
|
780
|
+
// Recalibrated for the relative gradient above; the old 52 applied to
|
|
781
|
+
// a raw normalized difference and is not comparable.
|
|
782
|
+
//
|
|
783
|
+
// For a surface turned by angle t from the view direction, the ratio
|
|
784
|
+
// over a k-pixel step is about tan(t) * k / (0.5 * height * P11), and
|
|
785
|
+
// the six-tap pattern averages roughly two thirds of that. At 1080p
|
|
786
|
+
// with a 40 degree vertical FOV this puts an ear rim or nostril wing
|
|
787
|
+
// (t around 80 degrees) near 0.5, keeps a flat cheek under 0.1, and
|
|
788
|
+
// still saturates on a silhouette.
|
|
789
|
+
//
|
|
790
|
+
// A residual dependence on vertical resolution and FOV remains,
|
|
791
|
+
// because pixelStep is expressed in pixels. That is bounded and
|
|
792
|
+
// predictable, unlike the far-plane scaling it replaces, so it is
|
|
793
|
+
// left alone rather than fixed by hand here.
|
|
794
|
+
this.$l.depthThin = pb.clamp(pb.mul(this.depthMean, pb.add(80, pb.mul(this.radiusScale, 28))), 0, 1);
|
|
738
795
|
this.$l.normalThin = pb.clamp(pb.mul(this.normalMean, pb.add(1.4, pb.mul(this.radiusScale, 0.5))), 0, 1);
|
|
739
796
|
this.$l.combinedThin = pb.clamp(pb.add(pb.mul(this.depthThin, 0.72), pb.mul(this.normalThin, 0.52)), 0, 1);
|
|
740
797
|
this.$return(pb.vec3(this.depthThin, this.normalThin, this.combinedThin));
|
|
@@ -838,10 +895,9 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
838
895
|
this.$l.scatterSoftnessAuthor = pb.clamp(pb.mul(pb.sub(this.param.a, 0.75), 4), 0, 1);
|
|
839
896
|
this.$l.roughnessInfo = pb.textureSampleLevel(this.roughnessTex, this.uv, 0);
|
|
840
897
|
this.$l.profileStrength = this.max3(this.profile.rgb);
|
|
898
|
+
this.$l.automaticTransmission = pb.lessThan(this.profile.a, 0);
|
|
841
899
|
this.$l.materialTransmissionMask = pb.clamp(this.profile.a, 0, 1);
|
|
842
|
-
this.debugTransmissionMask = this.materialTransmissionMask;
|
|
843
900
|
this.$l.profileSlot = this.readProfileSlot(this.param);
|
|
844
|
-
this.$l.profilePreset = this.readProfilePreset(this.param);
|
|
845
901
|
this.$l.depth01 = this.readDepth01(this.uv);
|
|
846
902
|
this.$l.result = this.baseColor.rgb;
|
|
847
903
|
// Transmission shadow. On the PCSS path the shadow uses implicit
|
|
@@ -871,6 +927,7 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
871
927
|
this.$l.profileSettingsA = this.readProfileSettingsA(this.profileSlot);
|
|
872
928
|
this.$l.profileTransmissionTint = this.readProfileTransmissionTint(this.profileSlot);
|
|
873
929
|
this.$l.profileSettingsB = this.readProfileSettingsB(this.profileSlot);
|
|
930
|
+
this.$l.profileSpecularSettings = this.readProfileSpecularSettings(this.profileSlot);
|
|
874
931
|
this.$l.profileWorldScale = pb.clamp(this.profileSettingsA.x, 0.05, SSS._profileWorldScaleEncodeMax);
|
|
875
932
|
this.$l.profileBoundaryBleed = pb.clamp(this.profileSettingsA.y, 0, 1);
|
|
876
933
|
this.$l.profileNormalScale = pb.clamp(this.profileSettingsA.z, 0, SSS._profileNormalScaleEncodeMax);
|
|
@@ -878,6 +935,8 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
878
935
|
this.$l.profileExtinctionScale = pb.clamp(this.profileSettingsB.x, 0, SSS._profileExtinctionEncodeMax);
|
|
879
936
|
this.$l.profileScatterScale = pb.clamp(this.profileSettingsB.y, 0.05, SSS._profileWorldScaleEncodeMax);
|
|
880
937
|
this.$l.profileStrengthScale = pb.clamp(this.profileSettingsB.z, 0.05, 2);
|
|
938
|
+
this.$l.profileSpecularSoftness = pb.clamp(this.profileSpecularSettings.x, 0, 1);
|
|
939
|
+
this.$l.profileSpecularRadius = pb.clamp(this.profileSpecularSettings.y, 0, SSS._profileSpecularRadiusEncodeMax);
|
|
881
940
|
this.$l.profileWorldScaleNorm = pb.clamp(pb.div(this.profileWorldScale, SSS._profileWorldScaleEncodeMax), 0, 1);
|
|
882
941
|
this.$l.profileScatterScaleNorm = pb.clamp(pb.div(this.profileScatterScale, SSS._profileWorldScaleEncodeMax), 0, 1);
|
|
883
942
|
this.$l.profileStrengthNorm = pb.clamp(pb.mul(this.profileStrengthScale, 0.5), 0, 1);
|
|
@@ -896,7 +955,6 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
896
955
|
this.$l.presetResponse = this.readProfilePresetResponse(this.profileSlot);
|
|
897
956
|
this.$l.presetFrontScatter = this.presetResponse.x;
|
|
898
957
|
this.$l.presetSoftness = this.presetResponse.y;
|
|
899
|
-
this.$l.presetEnergyBoost = this.presetResponse.z;
|
|
900
958
|
this.$l.presetTransmissionBoost = this.presetResponse.w;
|
|
901
959
|
this.$l.presetTint = pb.mul(this.profileTintBase, this.presetTintBias, pb.mix(pb.vec3(1), this.profileTransmissionTint, pb.mul(this.profileBoundaryBleed, 0.22)));
|
|
902
960
|
this.$l.tint = pb.div(pb.max(this.presetTint, pb.vec3(1e-4)), pb.max(this.max3(this.presetTint), 1e-4));
|
|
@@ -918,6 +976,11 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
918
976
|
this.$l.depthThinness = this.thinnessComponents.x;
|
|
919
977
|
this.$l.curvatureThinness = this.thinnessComponents.y;
|
|
920
978
|
this.$l.screenThinness = this.thinnessComponents.z;
|
|
979
|
+
this.$l.backLightFacing = pb.clamp(pb.dot(pb.neg(this.normalWS), this.sunDirWS), 0, 1);
|
|
980
|
+
this.$l.backLightGate = pb.pow(this.backLightFacing, pb.max(this.transmissionPower, 0.1));
|
|
981
|
+
this.$l.automaticThinMask = pb.mul(pb.smoothStep(0.24, 0.72, this.screenThinness), pb.mix(0.58, 1, this.backLightGate));
|
|
982
|
+
this.materialTransmissionMask = this.$choice(this.automaticTransmission, this.automaticThinMask, this.materialTransmissionMask);
|
|
983
|
+
this.debugTransmissionMask = this.materialTransmissionMask;
|
|
921
984
|
this.debugThinness = this.screenThinness;
|
|
922
985
|
this.debugThinnessLayers = pb.vec3(this.depthThinness, this.curvatureThinness, 0);
|
|
923
986
|
this.$l.wrappedFront = pb.smoothStep(pb.add(-0.32, pb.mul(this.profileSpread, 0.08)), pb.add(0.42, pb.mul(this.radiusResponse, 0.16)), pb.add(this.frontLit, pb.mul(this.radiusResponse, 0.18)));
|
|
@@ -933,7 +996,6 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
933
996
|
this.$l.edgeThinBoost = pb.clamp(pb.mul(this.screenThinness, pb.add(0.14, pb.mul(this.materialThicknessField, 0.22))), 0, 0.32);
|
|
934
997
|
this.$l.curvatureThinBoost = pb.clamp(pb.mul(this.curvatureThinness, pb.add(pb.add(0.08, pb.mul(this.materialThicknessField, 0.12)), pb.mul(pb.sub(this.profileNormalScale, 1), 0.08))), 0, 0.18);
|
|
935
998
|
this.$l.scatterMask = pb.clamp(pb.add(this.surfaceScatterMask, pb.add(pb.add(pb.mul(this.materialScatterBoost, 0.28), this.presetFrontScatter), pb.add(pb.mul(pb.clamp(pb.sub(1, pb.max(this.frontLit, 0)), 0, 1), pb.add(pb.mul(this.materialScatterBoost, 0.22), pb.mul(this.presetFrontScatter, 0.7))), pb.mul(this.screenThinness, pb.add(0.12, pb.mul(this.presetSoftness, 0.08), pb.mul(this.presetFrontScatter, 0.08))), pb.mul(this.materialTransmissionSoftness, 0.1)))), pb.add(pb.add(0.05, pb.mul(this.materialScatterBoost, 0.12)), pb.mul(this.presetFrontScatter, 0.3)), 1);
|
|
936
|
-
this.$l.scatterMix = pb.add(pb.add(0.54, pb.mul(this.radiusResponse, 0.94)), pb.add(pb.add(pb.mul(this.avgFalloff, 0.22), pb.mul(this.profileSpread, 0.08)), pb.add(pb.mul(this.materialScatterBoost, 0.3), this.presetSoftness)));
|
|
937
999
|
this.$l.scatterStrength = pb.clamp(pb.mul(pb.max(pb.mul(this.profileStrength, pb.mix(0.88, 1.24, this.profileStrengthNorm)), pb.mul(this.widthStrength, 0.45)), this.sssStrength, this.profileEnergyScale, pb.add(pb.add(0.62, pb.mul(this.avgFalloff, 0.56)), pb.add(pb.add(pb.mul(this.profileSpread, 0.28), pb.mul(this.screenThinness, 0.18)), pb.add(pb.add(pb.mul(this.materialScatterBoost, 0.42), pb.mul(this.presetSoftness, 0.5)), pb.mul(this.materialTransmissionSoftness, 0.22))))), 0, pb.add(pb.add(pb.add(1.05, pb.mul(this.materialScatterBoost, 1.1)), pb.add(pb.mul(this.presetSoftness, 0.8), pb.mul(this.profileEnergyScale, 0.24))), pb.mul(this.screenThinness, 0.22)));
|
|
938
1000
|
this.$l.blurred = pb.textureSampleLevel(this.blurTex, this.uv, 0).rgb;
|
|
939
1001
|
this.$l.roughness = pb.float(1);
|
|
@@ -953,26 +1015,44 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
953
1015
|
this.$l.skinTint = pb.normalize(pb.max(pb.mix(this.baseDiffuseSafe, pb.mul(this.baseDiffuseSafe, pb.mix(this.tint, this.profileTransmissionTint, pb.mul(this.profileBoundaryBleed, 0.2))), this.epidermalMix), pb.vec3(1e-4)));
|
|
954
1016
|
this.$l.deepTint = pb.normalize(pb.max(pb.mix(this.skinTint, pb.mul(this.tint, pb.mix(pb.vec3(1), this.profileTransmissionTint, pb.clamp(pb.add(pb.mul(this.profileBoundaryBleed, 0.35), pb.mul(pb.sub(1, pb.clamp(pb.div(this.profileExtinctionScale, SSS._profileExtinctionEncodeMax), 0, 1)), 0.28)), 0, 0.8))), this.deepMix), pb.vec3(1e-4)));
|
|
955
1017
|
this.$l.baseSpecular = pb.max(pb.sub(this.baseColor.rgb, this.baseDiffuseColor), pb.vec3(0));
|
|
956
|
-
this.$l.
|
|
1018
|
+
this.$l.softenedSpecular = this.baseSpecular;
|
|
1019
|
+
this.$if(pb.notEqual(this.hasDiffuseTex, 0), function() {
|
|
1020
|
+
// The wide SSS pass contains diffuse lighting only. Preserve broad
|
|
1021
|
+
// highlights, but diffuse the pixel-scale normal detail that would
|
|
1022
|
+
// otherwise be added back unchanged with the specular component.
|
|
1023
|
+
this.$l.specularRadius = pb.clamp(pb.mul(this.profileSpecularRadius, pb.mix(0.9, 1.1, this.radiusResponse)), 0, pb.mul(SSS._profileSpecularRadiusEncodeMax, 1.1));
|
|
1024
|
+
this.$l.specularTexel = pb.div(pb.vec2(this.specularRadius), this.targetSize.xy);
|
|
1025
|
+
this.$l.centerLogDepth = pb.log(pb.add(pb.mul(this.depth01, this.cameraNearFar.y), 1));
|
|
1026
|
+
this.$l.specularSum = this.baseSpecular;
|
|
1027
|
+
this.$l.specularWeight = pb.float(1);
|
|
1028
|
+
const sampleSpecularAt = (offsetX, offsetY)=>{
|
|
1029
|
+
this.$l.specularNeighbor = this.sampleCompatibleSpecular(pb.add(this.uv, pb.mul(this.specularTexel, pb.vec2(offsetX, offsetY))), this.profileSlot, this.centerLogDepth);
|
|
1030
|
+
this.specularSum = pb.add(this.specularSum, pb.mul(this.specularNeighbor.rgb, this.specularNeighbor.a, 0.72));
|
|
1031
|
+
this.specularWeight = pb.add(this.specularWeight, pb.mul(this.specularNeighbor.a, 0.72));
|
|
1032
|
+
};
|
|
1033
|
+
sampleSpecularAt(1, 0);
|
|
1034
|
+
sampleSpecularAt(-1, 0);
|
|
1035
|
+
sampleSpecularAt(0, 1);
|
|
1036
|
+
sampleSpecularAt(0, -1);
|
|
1037
|
+
this.$l.filteredSpecular = pb.div(this.specularSum, pb.max(this.specularWeight, 1));
|
|
1038
|
+
this.$l.specularSoftnessBase = pb.clamp(pb.mul(this.profileSpecularSoftness, this.profileStrength, this.sssStrength), 0, 0.95);
|
|
1039
|
+
this.$l.specularSoftness = pb.sub(1, pb.mul(pb.sub(1, this.specularSoftnessBase), pb.sub(1, this.specularSoftnessBase)));
|
|
1040
|
+
this.softenedSpecular = pb.mix(this.baseSpecular, this.filteredSpecular, this.specularSoftness);
|
|
1041
|
+
});
|
|
1042
|
+
this.$l.scatterBlendBase = pb.clamp(pb.mul(this.profileStrength, this.sssStrength, pb.add(0.28, pb.add(pb.mul(this.radiusResponse, 0.42), pb.mul(this.widthStrength, 0.3))), pb.mix(0.72, 1, this.scatterMask)), 0, 0.92);
|
|
1043
|
+
// Diffusion should visibly suppress high-frequency normal lighting.
|
|
1044
|
+
// A squared complement keeps low strengths controllable while making
|
|
1045
|
+
// a fully enabled skin profile approach the blurred diffuse result.
|
|
1046
|
+
this.$l.scatterBlend = pb.clamp(pb.sub(1, pb.mul(pb.sub(1, this.scatterBlendBase), pb.sub(1, this.scatterBlendBase))), 0, 0.97);
|
|
957
1047
|
this.$l.blurredLuma = pb.dot(this.blurred, pb.vec3(0.2126, 0.7152, 0.0722));
|
|
958
|
-
this.$l.profileBlurred =
|
|
959
|
-
this.$l.
|
|
960
|
-
this.profileBlurred = pb.mix(this.profileBlurred, this.warmBlur, pb.clamp(pb.add(pb.add(0.1, pb.mul(this.avgFalloff, 0.08)), pb.add(pb.mul(this.materialScatterBoost, 0.12), pb.mul(this.presetSoftness, 0.08))), 0.08, 0.32));
|
|
961
|
-
this.$l.blurredClamped = pb.min(this.profileBlurred, pb.add(this.baseDiffuseColor, pb.mul(this.deepTint, pb.mul(this.scatterMask, pb.add(pb.add(0.06, pb.mul(this.radiusResponse, 0.18)), pb.add(pb.mul(this.avgFalloff, 0.08), pb.add(pb.mul(this.materialScatterBoost, 0.2), pb.mul(this.presetEnergyBoost, 0.18))))))));
|
|
1048
|
+
this.$l.profileBlurred = this.blurred;
|
|
1049
|
+
this.$l.blurredClamped = this.profileBlurred;
|
|
962
1050
|
this.$l.scattered = pb.mix(this.baseDiffuseColor, this.blurredClamped, this.scatterBlend);
|
|
963
|
-
this.$l.terminatorLift = pb.mul(this.baseDiffuseColor, this.deepTint, this.scatterStrength, this.terminatorWrap, pb.add(pb.add(0.014, pb.mul(this.radiusResponse, 0.022)), pb.add(pb.mul(this.profileSpread, 0.012), pb.add(pb.mul(this.materialScatterBoost, 0.02), pb.mul(this.presetSoftness, 0.012)))), pb.sub(1, pb.mul(this.specMask, 0.45)));
|
|
964
1051
|
this.$l.multiScatterLift = pb.mul(pb.max(pb.sub(this.blurredClamped, this.baseDiffuseColor), pb.vec3(0)), this.scatterStrength, this.multiScatter, this.scatterMask, pb.add(0.08, pb.mul(this.radiusResponse, pb.add(pb.add(0.09, pb.mul(this.materialScatterBoost, 0.08)), pb.add(pb.mul(this.presetSoftness, 0.06), pb.add(pb.mul(pb.sub(this.profileScatterScale, 1), 0.04), pb.mul(this.profileDiffusionSoftness, 0.03)))))));
|
|
965
|
-
this.$l.
|
|
966
|
-
this.$l.veilColor = pb.mix(this.blurredClamped, pb.mul(this.blurredClamped, this.skinTint), 0.16);
|
|
967
|
-
this.$l.softVeil = pb.mul(this.veilColor, this.scatterStrength, this.scatterMask, pb.add(pb.add(pb.add(0.002, pb.mul(this.materialScatterBoost, 0.004)), pb.mul(this.presetSoftness, 0.004)), pb.mul(this.radiusResponse, pb.add(pb.add(0.007, pb.mul(this.avgFalloff, 0.007)), pb.add(pb.mul(this.profileSpread, 0.003), pb.add(pb.mul(this.materialScatterBoost, 0.006), pb.mul(this.presetSoftness, 0.004)))))), pb.sub(1, pb.mul(this.specMask, 0.55)));
|
|
968
|
-
this.$l.scatteredDiffuse = pb.add(this.scattered, pb.add(this.terminatorLift, pb.add(this.multiScatterLift, pb.add(this.subdermalFill, this.softVeil))));
|
|
969
|
-
this.$l.energyLimit = pb.add(this.baseDiffuseColor, pb.mul(this.deepTint, this.scatterStrength, this.scatterMask, pb.add(pb.add(pb.add(0.1, pb.mul(this.radiusResponse, 0.18)), pb.add(pb.mul(this.avgFalloff, 0.08), pb.mul(this.profileSpread, 0.04))), pb.add(pb.mul(this.materialScatterBoost, 0.28), this.presetEnergyBoost))));
|
|
970
|
-
this.$l.scatterBudget = pb.max(pb.sub(this.energyLimit, this.baseDiffuseColor), pb.vec3(0));
|
|
971
|
-
this.$l.scatterDelta = pb.max(pb.sub(this.scatteredDiffuse, this.baseDiffuseColor), pb.vec3(0));
|
|
972
|
-
this.$l.scatteredDiffuse = pb.add(this.baseDiffuseColor, pb.min(this.scatterDelta, this.scatterBudget));
|
|
1052
|
+
this.$l.scatteredDiffuse = pb.add(this.scattered, this.multiScatterLift);
|
|
973
1053
|
this.$l.transmissionBudget = pb.mul(this.deepTint, this.scatterStrength, this.materialTransmissionResponse, this.transmissionStrength, this.profileTransmissionScale, pb.add(pb.add(pb.add(0.12, pb.mul(this.radiusResponse, 0.2)), pb.mul(this.materialTransmissionSoftness, 0.2)), pb.add(pb.mul(this.avgFalloff, 0.12), pb.add(pb.mul(this.profileSpread, 0.12), pb.add(pb.mul(this.materialScatterBoost, 0.12), pb.mul(this.presetTransmissionBoost, 0.22))))), pb.mix(0.82, 1.18, this.profileScatterScaleNorm));
|
|
974
1054
|
this.$l.diffuseHeadroom = pb.mul(this.transmissionBudget, pb.add(pb.add(1.65, pb.mul(this.materialTransmissionResponse, 0.9)), pb.add(pb.add(pb.mul(this.materialTransmissionSoftness, 0.55), pb.mul(this.profileSpread, 0.2)), pb.mul(this.profileTransmissionScale, 0.22))));
|
|
975
|
-
this.result = pb.add(this.
|
|
1055
|
+
this.result = pb.add(this.softenedSpecular, this.scatteredDiffuse);
|
|
976
1056
|
this.$if(pb.greaterThan(this.transmissionStrength, 0), function() {
|
|
977
1057
|
this.$l.viewDirVS = pb.normalize(pb.neg(this.viewPos));
|
|
978
1058
|
this.$l.viewDirWS = pb.normalize(pb.mul(this.invViewMatrix, pb.vec4(this.viewDirVS, 0)).xyz);
|
|
@@ -984,8 +1064,9 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
984
1064
|
this.debugTransmissionShadow = this.transmissionShadow;
|
|
985
1065
|
this.debugProfileBoundary = pb.clamp(pb.vec3(this.profileBoundaryBleed, this.transmissionShadowSoftness, this.transmissionShadowFloor), pb.vec3(0), pb.vec3(1));
|
|
986
1066
|
this.debugProfileTransmission = pb.clamp(pb.vec3(pb.div(this.profileTransmissionScale, 1.35), this.materialTransmissionResponse, this.transmissionShadow), pb.vec3(0), pb.vec3(1));
|
|
987
|
-
|
|
988
|
-
this.$l.
|
|
1067
|
+
// Keep warm thin-shell lighting on the back-facing side of the surface.
|
|
1068
|
+
this.$l.backLit = pb.mul(this.backLightGate, this.transmissionLightAttenuation);
|
|
1069
|
+
this.$l.thicknessBackScatter = pb.clamp(pb.mul(this.backLit, pb.add(0.82, pb.mul(this.rim, 0.18))), 0, 1);
|
|
989
1070
|
this.$l.thinPotential = pb.clamp(pb.add(pb.add(pb.mul(this.materialThicknessField, 0.78), this.edgeThinBoost), pb.add(this.curvatureThinBoost, pb.mul(pb.sqrt(pb.max(pb.mul(this.depthThinness, this.curvatureThinness), 0)), pb.add(pb.add(0.08, pb.mul(this.profileSpread, 0.06)), pb.mul(pb.sub(this.profileDistribution, 0.5), 0.06))))), 0, 1);
|
|
990
1071
|
this.$l.transmissionFocus = pb.clamp(pb.mul(pb.add(pb.mul(this.materialThicknessField, 0.72), pb.mul(this.thinPotential, 0.38)), pb.add(pb.add(0.22, pb.mul(this.thicknessBackScatter, 0.72)), pb.mul(this.backLit, 0.08))), 0, 1);
|
|
991
1072
|
this.$l.thinRegion = pb.clamp(pb.add(pb.add(pb.mul(this.materialThicknessField, 0.86), pb.mul(this.transmissionFocus, 0.74)), pb.add(pb.add(pb.mul(this.edgeThinBoost, 0.9), pb.mul(this.curvatureThinBoost, 0.5)), pb.add(pb.mul(this.backLit, 0.1), pb.mul(this.profileSpread, 0.05)))), 0, 1);
|
|
@@ -1010,13 +1091,11 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
1010
1091
|
this.$l.transmittedDiffuseLuma = pb.dot(this.transmittedDiffuse, pb.vec3(0.2126, 0.7152, 0.0722));
|
|
1011
1092
|
this.$l.visibleTransmissionMask = pb.clamp(pb.add(pb.add(pb.mul(this.materialThicknessField, 0.72), pb.mul(this.thinRegion, 0.34)), pb.add(pb.mul(this.thicknessBackScatter, 0.28), pb.add(pb.mul(this.materialTransmissionSoftness, 0.08), pb.add(pb.mul(this.profileTransmissionScale, 0.12), pb.mul(this.profileDiffusionSoftness, 0.06))))), 0, 1);
|
|
1012
1093
|
this.$l.visibleTransmissionChroma = pb.clamp(pb.add(pb.add(0.66, pb.mul(this.visibleTransmissionMask, 0.32)), pb.add(pb.mul(this.thicknessBackScatter, 0.24), pb.mul(this.presetTransmissionBoost, 0.14))), 0.52, 1);
|
|
1013
|
-
this.$l.visibleTransmissionTint = pb.normalize(pb.max(pb.mix(this.warmTransmissionTint,
|
|
1094
|
+
this.$l.visibleTransmissionTint = pb.normalize(pb.max(pb.mix(this.warmTransmissionTint, this.profileTransmissionTint, pb.clamp(pb.add(pb.mul(this.visibleTransmissionMask, 0.24), pb.mul(this.thicknessBackScatter, 0.2)), 0, 0.6)), pb.vec3(1e-4)));
|
|
1014
1095
|
this.$l.visibleTransmissionWarm = pb.mix(this.transmittedDiffuse, pb.mul(this.visibleTransmissionTint, this.transmittedDiffuseLuma), this.visibleTransmissionChroma);
|
|
1015
|
-
this.$l.visibleTransmissionGain = pb.clamp(pb.add(pb.add(
|
|
1096
|
+
this.$l.visibleTransmissionGain = pb.clamp(pb.add(pb.add(0.78, pb.mul(this.visibleTransmissionMask, 0.72)), pb.add(pb.mul(this.thicknessBackScatter, 0.48), pb.add(pb.mul(this.materialTransmissionSoftness, 0.18), pb.mul(this.profileTransmissionScale, 0.24)))), 0.7, 2.4);
|
|
1016
1097
|
this.$l.visibleTransmissionHeadroom = pb.add(pb.mul(this.transmissionHeadroom, pb.add(pb.add(2.15, pb.mul(this.visibleTransmissionMask, 1.1)), pb.mul(this.thicknessBackScatter, 0.72))), pb.mul(this.visibleTransmissionTint, this.visibleTransmissionMask, this.transmittedDiffuseLuma, pb.add(pb.add(0.12, pb.mul(this.thicknessBackScatter, 0.18)), pb.mul(this.materialThicknessField, 0.14))));
|
|
1017
|
-
this.$l.visibleTransmission = pb.min(pb.mul(this.visibleTransmissionWarm, this.visibleTransmissionGain, this.transmissionShadow), this.visibleTransmissionHeadroom);
|
|
1018
|
-
this.$l.visibleTransmissionReveal = pb.clamp(pb.mul(this.visibleTransmissionMask, this.transmissionShadow, pb.add(pb.add(0.1, pb.mul(this.thicknessBackScatter, 0.25)), pb.mul(this.materialThicknessField, 0.12))), 0, 0.38);
|
|
1019
|
-
this.result = pb.mix(this.result, pb.mul(this.result, pb.vec3(0.84, 0.68, 0.64)), this.visibleTransmissionReveal);
|
|
1098
|
+
this.$l.visibleTransmission = pb.min(pb.mul(this.visibleTransmissionWarm, this.visibleTransmissionGain, this.transmissionShadow, this.backLightGate), this.visibleTransmissionHeadroom);
|
|
1020
1099
|
this.debugThinLighting = this.visibleTransmission;
|
|
1021
1100
|
this.result = pb.add(this.result, this.visibleTransmission);
|
|
1022
1101
|
});
|
|
@@ -1079,7 +1158,8 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
1079
1158
|
}
|
|
1080
1159
|
ensureProfileLUT(ctx) {
|
|
1081
1160
|
const device = ctx.device;
|
|
1082
|
-
if (!SSS._profileLUT || SSS._profileLUT.device !== device) {
|
|
1161
|
+
if (!SSS._profileLUT || SSS._profileLUT.device !== device || SSS._profileLUT.width !== SSS._profileLUTWidth || SSS._profileLUT.height !== SSS._profileLUTHeight) {
|
|
1162
|
+
SSS._profileLUT?.dispose();
|
|
1083
1163
|
SSS._profileLUT = device.createTexture2D('rgba8unorm', SSS._profileLUTWidth, SSS._profileLUTHeight, {
|
|
1084
1164
|
mipmapping: false
|
|
1085
1165
|
});
|
|
@@ -1131,6 +1211,11 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
1131
1211
|
data[settingsBOffset + 1] = encodeScaled(profile.scale, SSS._profileWorldScaleEncodeMax);
|
|
1132
1212
|
data[settingsBOffset + 2] = encodeUnit(profile.strength / 2);
|
|
1133
1213
|
data[settingsBOffset + 3] = 255;
|
|
1214
|
+
const specularSettingsOffset = (SSS._profileLUTWidth * 7 + slot) * 4;
|
|
1215
|
+
data[specularSettingsOffset + 0] = encodeUnit(profile.specularDetailSoftness);
|
|
1216
|
+
data[specularSettingsOffset + 1] = encodeScaled(profile.specularDetailRadius, SSS._profileSpecularRadiusEncodeMax);
|
|
1217
|
+
data[specularSettingsOffset + 2] = 0;
|
|
1218
|
+
data[specularSettingsOffset + 3] = 255;
|
|
1134
1219
|
}
|
|
1135
1220
|
SSS._profileLUT.update(data, 0, 0, SSS._profileLUTWidth, SSS._profileLUTHeight);
|
|
1136
1221
|
SSS._profileLUTVersion = SubsurfaceProfile.version;
|