@zephyr3d/scene 0.9.21 → 0.9.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/animation/joint_dynamics/collision.js +1 -7
- package/dist/animation/joint_dynamics/collision.js.map +1 -1
- package/dist/animation/joint_dynamics/constraints.js +2 -17
- package/dist/animation/joint_dynamics/constraints.js.map +1 -1
- package/dist/animation/joint_dynamics/controller.js +2 -20
- package/dist/animation/joint_dynamics/controller.js.map +1 -1
- package/dist/animation/joint_dynamics/joint_dynamics_system.js +1 -3
- package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
- package/dist/animation/joint_dynamics/solver.js +14 -60
- package/dist/animation/joint_dynamics/solver.js.map +1 -1
- package/dist/animation/joint_dynamics/types.js +3 -3
- package/dist/animation/joint_dynamics/types.js.map +1 -1
- package/dist/app/app.js +23 -0
- package/dist/app/app.js.map +1 -1
- package/dist/app/scriptregistry.js +16 -53
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/assetmanager.js +2 -0
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/model.js +22 -0
- package/dist/asset/model.js.map +1 -1
- package/dist/blitter/bilateralblur.js +3 -1
- package/dist/blitter/bilateralblur.js.map +1 -1
- package/dist/blitter/blitter.js +3 -3
- package/dist/blitter/blitter.js.map +1 -1
- package/dist/camera/camera.js +398 -45
- package/dist/camera/camera.js.map +1 -1
- package/dist/camera/perspectivecamera.js +69 -2
- package/dist/camera/perspectivecamera.js.map +1 -1
- package/dist/index.d.ts +9100 -8712
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/material/blinn.js +1 -1
- package/dist/material/blinn.js.map +1 -1
- package/dist/material/lambert.js +3 -3
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/material.js +8 -5
- package/dist/material/material.js.map +1 -1
- package/dist/material/meshmaterial.js +17 -10
- 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 +21 -6
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
- package/dist/material/mixins/lit.js +33 -11
- package/dist/material/mixins/lit.js.map +1 -1
- package/dist/material/mixins/pbr/brdf.js +44 -12
- package/dist/material/mixins/pbr/brdf.js.map +1 -1
- package/dist/material/mixins/pbr/common.js +149 -14
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/material/mtoon.js +7 -4
- package/dist/material/mtoon.js.map +1 -1
- package/dist/material/pbrblueprint.js +5 -1
- package/dist/material/pbrblueprint.js.map +1 -1
- package/dist/material/pbrmr.js +1 -1
- package/dist/material/pbrmr.js.map +1 -1
- package/dist/material/pbrsg.js +1 -1
- package/dist/material/pbrsg.js.map +1 -1
- package/dist/material/shader/helper.js +186 -11
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/skin.js +2 -2
- package/dist/material/skin.js.map +1 -1
- package/dist/material/terrain-cm.js +5 -5
- package/dist/material/terrain-cm.js.map +1 -1
- package/dist/material/water.js +6 -4
- package/dist/material/water.js.map +1 -1
- package/dist/posteffect/bloom.js +54 -4
- package/dist/posteffect/bloom.js.map +1 -1
- package/dist/posteffect/compositor.js +41 -0
- package/dist/posteffect/compositor.js.map +1 -1
- package/dist/posteffect/posteffect.js +51 -0
- package/dist/posteffect/posteffect.js.map +1 -1
- package/dist/posteffect/sao.js +7 -6
- package/dist/posteffect/sao.js.map +1 -1
- package/dist/posteffect/skinsss.js +3 -3
- package/dist/posteffect/skinsss.js.map +1 -1
- package/dist/posteffect/ssgi.js +1196 -0
- package/dist/posteffect/ssgi.js.map +1 -0
- package/dist/posteffect/ssr.js +83 -45
- package/dist/posteffect/ssr.js.map +1 -1
- package/dist/posteffect/sss.js +137 -49
- package/dist/posteffect/sss.js.map +1 -1
- package/dist/posteffect/taa.js +5 -4
- package/dist/posteffect/taa.js.map +1 -1
- package/dist/posteffect/tonemap.js +15 -3
- package/dist/posteffect/tonemap.js.map +1 -1
- package/dist/render/abuffer_oit.js +2 -2
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/cluster_light.js +12 -6
- package/dist/render/cluster_light.js.map +1 -1
- package/dist/render/drawable_mixin.js +8 -5
- package/dist/render/drawable_mixin.js.map +1 -1
- package/dist/render/dualdepthpeeling_oit.js +10 -5
- package/dist/render/dualdepthpeeling_oit.js.map +1 -1
- package/dist/render/envlight.js +298 -5
- package/dist/render/envlight.js.map +1 -1
- package/dist/render/gpu_picking.js +7 -5
- package/dist/render/gpu_picking.js.map +1 -1
- package/dist/render/hzb.js +28 -19
- package/dist/render/hzb.js.map +1 -1
- package/dist/render/lightpass.js +18 -4
- package/dist/render/lightpass.js.map +1 -1
- package/dist/render/render_queue.js +37 -4
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/renderer.js +8 -3
- package/dist/render/renderer.js.map +1 -1
- package/dist/render/rendergraph/blackboard.js +20 -48
- package/dist/render/rendergraph/blackboard.js.map +1 -1
- package/dist/render/rendergraph/device_pool_allocator.js +18 -58
- package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
- package/dist/render/rendergraph/executor.js +89 -115
- package/dist/render/rendergraph/executor.js.map +1 -1
- package/dist/render/rendergraph/forward_plus_builder.js +1003 -715
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/render/rendergraph/frame_graph_context.js +41 -0
- package/dist/render/rendergraph/frame_graph_context.js.map +1 -0
- package/dist/render/rendergraph/frame_resource_requirements.js +14 -0
- package/dist/render/rendergraph/frame_resource_requirements.js.map +1 -0
- package/dist/render/rendergraph/history_resource_manager.js +74 -140
- package/dist/render/rendergraph/history_resource_manager.js.map +1 -1
- package/dist/render/rendergraph/history_resources.js +7 -5
- package/dist/render/rendergraph/history_resources.js.map +1 -1
- package/dist/render/rendergraph/render_context.js +19 -0
- package/dist/render/rendergraph/render_context.js.map +1 -0
- package/dist/render/rendergraph/render_pipeline.js +315 -0
- package/dist/render/rendergraph/render_pipeline.js.map +1 -0
- package/dist/render/rendergraph/rendergraph.js +158 -141
- package/dist/render/rendergraph/rendergraph.js.map +1 -1
- package/dist/render/rendergraph/scene_render_context.js +267 -0
- package/dist/render/rendergraph/scene_render_context.js.map +1 -0
- package/dist/render/rendergraph/texture_affinity_cache.js +19 -0
- package/dist/render/rendergraph/texture_affinity_cache.js.map +1 -0
- package/dist/render/rendergraph/types.js +19 -31
- package/dist/render/rendergraph/types.js.map +1 -1
- package/dist/render/renderpass.js +3 -3
- package/dist/render/renderpass.js.map +1 -1
- package/dist/render/shadow_mask_pass.js +10 -6
- package/dist/render/shadow_mask_pass.js.map +1 -1
- package/dist/render/sky.js +197 -35
- package/dist/render/sky.js.map +1 -1
- package/dist/render/weightedblended_oit.js +4 -3
- package/dist/render/weightedblended_oit.js.map +1 -1
- package/dist/scene/basesprite.js +2 -0
- package/dist/scene/basesprite.js.map +1 -1
- package/dist/scene/batchgroup.js +10 -0
- package/dist/scene/batchgroup.js.map +1 -1
- package/dist/scene/environment.js +61 -2
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/light.js +178 -10
- package/dist/scene/light.js.map +1 -1
- package/dist/scene/meshdrawable.js +89 -2
- package/dist/scene/meshdrawable.js.map +1 -1
- package/dist/scene/msdftext.js +2 -0
- package/dist/scene/msdftext.js.map +1 -1
- package/dist/scene/msdftextsprite.js +2 -0
- package/dist/scene/msdftextsprite.js.map +1 -1
- package/dist/scene/particlesys.js +2 -0
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/scene.js +34 -1
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/terrain-cm/grass.js +2 -1
- package/dist/scene/terrain-cm/grass.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +2 -0
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/scene/water.js +2 -0
- package/dist/scene/water.js.map +1 -1
- package/dist/shaders/atmosphere.js +5 -4
- package/dist/shaders/atmosphere.js.map +1 -1
- package/dist/shaders/fog.js +10 -3
- package/dist/shaders/fog.js.map +1 -1
- package/dist/shaders/shadow.js +96 -29
- package/dist/shaders/shadow.js.map +1 -1
- package/dist/shaders/ssgi.js +63 -0
- package/dist/shaders/ssgi.js.map +1 -0
- package/dist/shaders/ssgi_reprojection.js +118 -0
- package/dist/shaders/ssgi_reprojection.js.map +1 -0
- package/dist/shaders/ssr.js +322 -154
- package/dist/shaders/ssr.js.map +1 -1
- package/dist/shadow/esm.js +13 -8
- package/dist/shadow/esm.js.map +1 -1
- package/dist/shadow/pcf_opt.js +15 -12
- package/dist/shadow/pcf_opt.js.map +1 -1
- package/dist/shadow/pcf_pd.js +15 -12
- package/dist/shadow/pcf_pd.js.map +1 -1
- package/dist/shadow/pcss.js +17 -11
- package/dist/shadow/pcss.js.map +1 -1
- package/dist/shadow/shadow_impl.js +20 -2
- package/dist/shadow/shadow_impl.js.map +1 -1
- package/dist/shadow/shadowmapper.js +10 -3
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shadow/ssm.js +16 -13
- package/dist/shadow/ssm.js.map +1 -1
- package/dist/shadow/vsm.js +10 -8
- package/dist/shadow/vsm.js.map +1 -1
- package/dist/utility/physical.js +74 -0
- package/dist/utility/physical.js.map +1 -0
- package/dist/utility/rendermipmap.js +2 -2
- package/dist/utility/rendermipmap.js.map +1 -1
- package/dist/utility/serialization/manager.js +3 -1
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +3 -1
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/batch.js +3 -1
- package/dist/utility/serialization/scene/batch.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +598 -2
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/light.js +180 -9
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +43 -3
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +3 -1
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +3 -1
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/particle.js +3 -1
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/primitive.js +2 -0
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/scene.js +70 -0
- package/dist/utility/serialization/scene/scene.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +3 -1
- package/dist/utility/serialization/scene/sprite.js.map +1 -1
- package/dist/utility/serialization/scene/terrain.js +3 -1
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/text.js +3 -0
- package/dist/utility/serialization/scene/text.js.map +1 -1
- package/dist/utility/serialization/scene/water.js +3 -1
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/values.js +2 -3
- package/dist/values.js.map +1 -1
- package/package.json +3 -3
- package/dist/animation/joint_dynamics/convex_collider.js +0 -320
- package/dist/animation/joint_dynamics/convex_collider.js.map +0 -1
package/dist/posteffect/sss.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Vector2, Vector4, Matrix4x4 } from '@zephyr3d/base';
|
|
1
|
+
import { Vector2, Vector4, Matrix4x4, DEPTH_COMPARE_FARTHER, DEPTH_FARTHEST } from '@zephyr3d/base';
|
|
2
2
|
import { ShaderHelper } from '../material/shader/helper.js';
|
|
3
3
|
import '../material/lambert.js';
|
|
4
4
|
import '../material/blinn.js';
|
|
@@ -79,9 +79,32 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
79
79
|
}
|
|
80
80
|
return null;
|
|
81
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* Whether the combine pass should read the screen-space shadow mask for the
|
|
84
|
+
* combine light instead of recomputing its shadow. Enabled when the camera
|
|
85
|
+
* renders the mask and the combine light was actually written into it: the
|
|
86
|
+
* mask already holds the identical shadow — same shadow impl (PCSS/VSM/…),
|
|
87
|
+
* distance fade and shadowStrength — so this skips a full redundant per-pixel
|
|
88
|
+
* shadow evaluation. Shadow mode is irrelevant: the mask is rendered with the
|
|
89
|
+
* light's own impl. Falls back to the inline path when the light is not in the
|
|
90
|
+
* mask (e.g. it overflows {@link MAX_SHADOW_MASK_LIGHTS}).
|
|
91
|
+
*
|
|
92
|
+
* Only valid at execute time, after the ShadowMaps and ShadowMask passes have
|
|
93
|
+
* populated shadowMapInfo / maskOrdinal.
|
|
94
|
+
*/ useCombineShadowMask(ctx, shadowLight) {
|
|
95
|
+
if (!shadowLight || !ctx.screenSpaceShadowMask) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
const shadowMapParams = ctx.shadowMapInfo?.get(shadowLight);
|
|
99
|
+
return !!(shadowMapParams?.shadowMap && shadowMapParams.impl && shadowMapParams.maskOrdinal != null);
|
|
100
|
+
}
|
|
82
101
|
getCombineProgramKey(ctx, shadowLight) {
|
|
83
102
|
const shadowMapParams = shadowLight ? ctx.shadowMapInfo?.get(shadowLight) : null;
|
|
84
|
-
|
|
103
|
+
if (!shadowMapParams?.shaderHash) {
|
|
104
|
+
return 'default';
|
|
105
|
+
}
|
|
106
|
+
// The mask-sampling shader is independent of the PCSS impl hash.
|
|
107
|
+
return this.useCombineShadowMask(ctx, shadowLight) ? 'shadowMask' : `shadow:${shadowMapParams.shaderHash}`;
|
|
85
108
|
}
|
|
86
109
|
requireLinearDepthTexture() {
|
|
87
110
|
return true;
|
|
@@ -89,6 +112,17 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
89
112
|
requireDepthAttachment() {
|
|
90
113
|
return true;
|
|
91
114
|
}
|
|
115
|
+
requireSceneNormalTexture() {
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
requireShadowMask(ctx) {
|
|
119
|
+
// Runs at graph-build time, before shadowMapInfo is populated (that happens
|
|
120
|
+
// during the ShadowMaps pass execute), so it cannot inspect the combine
|
|
121
|
+
// light. Keep the mask alive whenever the camera renders it; combine()
|
|
122
|
+
// decides at execute time whether to sample it, and _setupFromApply only
|
|
123
|
+
// reads the handle when the mask was actually produced this frame.
|
|
124
|
+
return !!ctx.screenSpaceShadowMask;
|
|
125
|
+
}
|
|
92
126
|
apply(ctx, inputColorTexture, sceneDepthTexture, srgbOutput) {
|
|
93
127
|
const device = ctx.device;
|
|
94
128
|
const outputFramebuffer = device.getFramebuffer();
|
|
@@ -130,8 +164,8 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
130
164
|
}
|
|
131
165
|
blur(ctx, inputColorTexture, sceneDepthTexture, profileLUT, targetWidth, targetHeight, kernelRadius, horizontal, sssSettings) {
|
|
132
166
|
const device = ctx.device;
|
|
133
|
-
const sssNormalTexture = ctx.
|
|
134
|
-
const hasNormalTexture = !!ctx.
|
|
167
|
+
const sssNormalTexture = ctx.SceneNormalTexture ?? ctx.SSSParamTexture;
|
|
168
|
+
const hasNormalTexture = !!ctx.SceneNormalTexture;
|
|
135
169
|
const key = `${horizontal ? 'h' : 'v'}:${kernelRadius}`;
|
|
136
170
|
let program = SSS._blurPrograms[key];
|
|
137
171
|
if (!program) {
|
|
@@ -164,10 +198,10 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
164
198
|
}
|
|
165
199
|
combine(ctx, inputColorTexture, blurredTexture, sceneDepthTexture, profileLUT, srgbOutput) {
|
|
166
200
|
const device = ctx.device;
|
|
167
|
-
const sssRoughnessTexture = ctx.
|
|
168
|
-
const sssNormalTexture = ctx.
|
|
169
|
-
const hasRoughnessTexture = !!ctx.
|
|
170
|
-
const hasNormalTexture = !!ctx.
|
|
201
|
+
const sssRoughnessTexture = ctx.SceneRoughnessTexture ?? ctx.SSSParamTexture;
|
|
202
|
+
const sssNormalTexture = ctx.SceneNormalTexture ?? ctx.SSSParamTexture;
|
|
203
|
+
const hasRoughnessTexture = !!ctx.SceneRoughnessTexture;
|
|
204
|
+
const hasNormalTexture = !!ctx.SceneNormalTexture;
|
|
171
205
|
const shadowLight = this.getCombineShadowLight(ctx);
|
|
172
206
|
const programKey = this.getCombineProgramKey(ctx, shadowLight);
|
|
173
207
|
let program = SSS._combinePrograms[programKey];
|
|
@@ -187,7 +221,7 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
187
221
|
y: 0,
|
|
188
222
|
z: 1
|
|
189
223
|
};
|
|
190
|
-
const sunColorIntensity = mainTransmissionLight ? mainTransmissionLight
|
|
224
|
+
const sunColorIntensity = mainTransmissionLight ? ShaderHelper.getPreExposedColorIntensity(mainTransmissionLight, ctx) : {
|
|
191
225
|
x: 1,
|
|
192
226
|
y: 1,
|
|
193
227
|
z: 1,
|
|
@@ -257,37 +291,56 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
257
291
|
bindGroup.setValue('srgbOut', srgbOutput ? 1 : 0);
|
|
258
292
|
if (shadowLight) {
|
|
259
293
|
const shadowMapParams = ctx.shadowMapInfo.get(shadowLight);
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
294
|
+
if (this.useCombineShadowMask(ctx, shadowLight)) {
|
|
295
|
+
// Screen-space shadow mask path: bind the mask array and select this
|
|
296
|
+
// light's layer/channel from its recorded ordinal (layer = s>>2,
|
|
297
|
+
// channel = s&3). A missing mask falls back to the fully-lit dummy.
|
|
298
|
+
const ordinal = shadowMapParams.maskOrdinal ?? 0;
|
|
299
|
+
const layer = ordinal >> 2;
|
|
300
|
+
const channel = ordinal & 3;
|
|
301
|
+
bindGroup.setValue('shadowMaskLayer', layer);
|
|
302
|
+
bindGroup.setValue('shadowMaskChannel', new Float32Array([
|
|
303
|
+
channel === 0 ? 1 : 0,
|
|
304
|
+
channel === 1 ? 1 : 0,
|
|
305
|
+
channel === 2 ? 1 : 0,
|
|
306
|
+
channel === 3 ? 1 : 0
|
|
307
|
+
]));
|
|
308
|
+
bindGroup.setTexture('Z_UniformShadowMask', ctx.shadowMaskTexture ?? ShaderHelper.getDummyShadowMask(device), fetchSampler('clamp_nearest'));
|
|
309
|
+
} else {
|
|
310
|
+
const cameraPos = ctx.camera.getWorldPosition();
|
|
311
|
+
bindGroup.setValue('camera', {
|
|
312
|
+
position: new Vector4(cameraPos.x, cameraPos.y, cameraPos.z, 0),
|
|
313
|
+
params: new Vector4(ctx.camera.getNearPlane(), ctx.camera.getFarPlane(), 1, 1),
|
|
314
|
+
shadowDebugCascades: ctx.camera.shadowDebugCascades ? 1 : 0,
|
|
315
|
+
framestamp: ctx.device.frameInfo.frameCounter
|
|
316
|
+
});
|
|
317
|
+
bindGroup.setValue('light', {
|
|
318
|
+
sunDir: new Float32Array([
|
|
319
|
+
sunDir.x,
|
|
320
|
+
sunDir.y,
|
|
321
|
+
sunDir.z
|
|
322
|
+
]),
|
|
323
|
+
envLightStrength: ShaderHelper.getEnvLightLuminance(ctx),
|
|
324
|
+
envLightSpecularStrength: ctx.env?.light.specularStrength ?? 1,
|
|
325
|
+
shadowStrength: shadowLight.shadow.shadowStrength,
|
|
326
|
+
shadowCascades: shadowMapParams.numShadowCascades,
|
|
327
|
+
positionAndRange: shadowLight.positionAndRange,
|
|
328
|
+
directionAndCutoff: shadowLight.directionAndCutoff,
|
|
329
|
+
diffuseAndIntensity: ShaderHelper.getPreExposedColorIntensity(shadowLight, ctx),
|
|
330
|
+
extraParams: shadowLight.extraParams,
|
|
331
|
+
implParams: shadowMapParams.impl.getParams(),
|
|
332
|
+
cascadeDistances: shadowMapParams.cascadeDistances,
|
|
333
|
+
depthBiasValues: shadowMapParams.depthBiasValues[0],
|
|
334
|
+
shadowCameraParams: shadowMapParams.cameraParams,
|
|
335
|
+
depthBiasScales: shadowMapParams.depthBiasScales,
|
|
336
|
+
shadowMatrices: new Float32Array(shadowMapParams.shadowMatrices)
|
|
337
|
+
});
|
|
338
|
+
bindGroup.setTexture('Z_UniformShadowMap', shadowMapParams.shadowMap, shadowMapParams.shadowMapSampler);
|
|
339
|
+
}
|
|
287
340
|
}
|
|
288
341
|
device.setProgram(program);
|
|
289
342
|
device.setBindGroup(0, bindGroup);
|
|
290
|
-
this.drawFullscreenQuad(AbstractPostEffect.getDefaultRenderState(ctx,
|
|
343
|
+
this.drawFullscreenQuad(AbstractPostEffect.getDefaultRenderState(ctx, DEPTH_COMPARE_FARTHER));
|
|
291
344
|
}
|
|
292
345
|
createBlurProgram(ctx, kernelRadius, horizontal) {
|
|
293
346
|
const sampleCount = Math.max(1, Math.ceil(kernelRadius / 2));
|
|
@@ -297,7 +350,7 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
297
350
|
this.$inputs.pos = pb.vec2().attrib('position');
|
|
298
351
|
this.$outputs.uv = pb.vec2();
|
|
299
352
|
pb.main(function() {
|
|
300
|
-
this.$builtins.position = pb.vec4(this.$inputs.pos,
|
|
353
|
+
this.$builtins.position = pb.vec4(this.$inputs.pos, DEPTH_FARTHEST, 1);
|
|
301
354
|
this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));
|
|
302
355
|
this.$if(pb.notEqual(this.flip, 0), function() {
|
|
303
356
|
this.$builtins.position.y = pb.neg(this.$builtins.position.y);
|
|
@@ -490,13 +543,18 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
490
543
|
createCombineProgram(ctx, shadowLight) {
|
|
491
544
|
const shadowMapParams = shadowLight ? ctx.shadowMapInfo?.get(shadowLight) : null;
|
|
492
545
|
const shadowEnabled = !!(shadowLight && shadowMapParams?.shadowMap && shadowMapParams.impl);
|
|
546
|
+
// When the screen-space shadow mask is available for the combine light,
|
|
547
|
+
// sample it instead of recomputing PCSS (which also avoids the dpdx-in-
|
|
548
|
+
// non-uniform-control-flow constraint entirely on this path).
|
|
549
|
+
const useShadowMask = this.useCombineShadowMask(ctx, shadowLight);
|
|
550
|
+
const pcssEnabled = shadowEnabled && !useShadowMask;
|
|
493
551
|
const program = ctx.device.buildRenderProgram({
|
|
494
552
|
vertex (pb) {
|
|
495
553
|
this.flip = pb.int().uniform(0);
|
|
496
554
|
this.$inputs.pos = pb.vec2().attrib('position');
|
|
497
555
|
this.$outputs.uv = pb.vec2();
|
|
498
556
|
pb.main(function() {
|
|
499
|
-
this.$builtins.position = pb.vec4(this.$inputs.pos,
|
|
557
|
+
this.$builtins.position = pb.vec4(this.$inputs.pos, DEPTH_FARTHEST, 1);
|
|
500
558
|
this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));
|
|
501
559
|
this.$if(pb.notEqual(this.flip, 0), function() {
|
|
502
560
|
this.$builtins.position.y = pb.neg(this.$builtins.position.y);
|
|
@@ -504,11 +562,12 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
504
562
|
});
|
|
505
563
|
},
|
|
506
564
|
fragment (pb) {
|
|
507
|
-
if (
|
|
565
|
+
if (pcssEnabled) {
|
|
508
566
|
const cameraStruct = pb.defineStruct([
|
|
509
567
|
pb.vec4('position'),
|
|
510
568
|
pb.vec4('params'),
|
|
511
|
-
pb.float('shadowDebugCascades')
|
|
569
|
+
pb.float('shadowDebugCascades'),
|
|
570
|
+
pb.int('framestamp')
|
|
512
571
|
]);
|
|
513
572
|
const lightStruct = pb.defineStruct([
|
|
514
573
|
pb.vec3('sunDir'),
|
|
@@ -522,6 +581,7 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
522
581
|
pb.vec4('extraParams'),
|
|
523
582
|
pb.vec4('cascadeDistances'),
|
|
524
583
|
pb.vec4('depthBiasValues'),
|
|
584
|
+
pb.vec4('implParams'),
|
|
525
585
|
pb.vec4('shadowCameraParams'),
|
|
526
586
|
pb.vec4('depthBiasScales'),
|
|
527
587
|
pb.vec4[16]('shadowMatrices')
|
|
@@ -535,6 +595,14 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
535
595
|
}
|
|
536
596
|
this.Z_UniformShadowMap = shadowTex.uniform(0);
|
|
537
597
|
}
|
|
598
|
+
if (useShadowMask) {
|
|
599
|
+
// Screen-space shadow mask: one RGBA8 array layer per 4 lights. The
|
|
600
|
+
// combine light's visibility is one channel of one layer, selected via
|
|
601
|
+
// the layer index and a one-hot channel selector bound at draw time.
|
|
602
|
+
this.Z_UniformShadowMask = pb.tex2DArray().uniform(0);
|
|
603
|
+
this.shadowMaskLayer = pb.int().uniform(0);
|
|
604
|
+
this.shadowMaskChannel = pb.vec4().uniform(0);
|
|
605
|
+
}
|
|
538
606
|
this.colorTex = pb.tex2D().uniform(0);
|
|
539
607
|
this.diffuseTex = pb.tex2D().uniform(0);
|
|
540
608
|
this.blurTex = pb.tex2D().uniform(0);
|
|
@@ -676,8 +744,8 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
676
744
|
pb.float('linearDepth')
|
|
677
745
|
], function() {
|
|
678
746
|
this.$l.viewDepth = pb.max(pb.mul(this.linearDepth, this.cameraNearFar.y), 1e-5);
|
|
679
|
-
this.$l.nonLinearDepth =
|
|
680
|
-
this.$l.clipPos = pb.vec4(pb.sub(pb.mul(this.uv, 2), pb.vec2(1)),
|
|
747
|
+
this.$l.nonLinearDepth = ShaderHelper.linearDepthToNonLinear(this, this.viewDepth, this.cameraNearFar);
|
|
748
|
+
this.$l.clipPos = pb.vec4(pb.sub(pb.mul(this.uv, 2), pb.vec2(1)), ShaderHelper.deviceDepthToClipZ(this, pb.clamp(this.nonLinearDepth, 0, 1)), 1);
|
|
681
749
|
this.$l.viewPos = pb.mul(this.invProjMatrix, this.clipPos);
|
|
682
750
|
this.$return(pb.div(this.viewPos.xyz, pb.max(this.viewPos.w, 1e-5)));
|
|
683
751
|
});
|
|
@@ -708,7 +776,7 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
708
776
|
this.spotFactor = pb.smoothStep(this.dirCutoff.w, pb.mix(this.dirCutoff.w, 1, 0.5), this.spotFactor);
|
|
709
777
|
this.$return(pb.mul(this.spotFactor, this.falloff, this.falloff));
|
|
710
778
|
});
|
|
711
|
-
if (
|
|
779
|
+
if (pcssEnabled) {
|
|
712
780
|
pb.func('calculateTransmissionShadow', [
|
|
713
781
|
pb.vec3('worldPos'),
|
|
714
782
|
pb.float('depth01'),
|
|
@@ -776,6 +844,28 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
776
844
|
this.$l.profilePreset = this.readProfilePreset(this.param);
|
|
777
845
|
this.$l.depth01 = this.readDepth01(this.uv);
|
|
778
846
|
this.$l.result = this.baseColor.rgb;
|
|
847
|
+
// Transmission shadow. On the PCSS path the shadow uses implicit
|
|
848
|
+
// derivatives (dpdx) inside the impl; WGSL requires those in uniform
|
|
849
|
+
// control flow, so it is computed here rather than inside the
|
|
850
|
+
// profile-active branch below (a per-pixel, non-uniform branch). On the
|
|
851
|
+
// shadow-mask path the value is a single texture fetch (no PCSS).
|
|
852
|
+
this.$l.transmissionShadowRaw = pb.float(1);
|
|
853
|
+
this.$l.transmissionShadow = pb.float(1);
|
|
854
|
+
if (pcssEnabled) {
|
|
855
|
+
this.$l.shadowNormalWS = this.decodeNormal(this.uv);
|
|
856
|
+
this.$l.shadowViewPos = this.reconstructViewPos(this.uv, this.depth01);
|
|
857
|
+
this.$l.shadowWorldPos = pb.mul(this.invViewMatrix, pb.vec4(this.shadowViewPos, 1)).xyz;
|
|
858
|
+
this.$l.shadowSunDirWS = this.calculateMainLightDirection(this.shadowWorldPos, this.mainLightType, this.mainLightPosRange, this.mainLightDirCutoff, this.sunDir);
|
|
859
|
+
this.transmissionShadowRaw = this.calculateTransmissionShadow(this.shadowWorldPos, this.depth01, pb.clamp(pb.abs(pb.dot(this.shadowNormalWS, this.shadowSunDirWS)), 0, 1));
|
|
860
|
+
this.transmissionShadow = this.transmissionShadowRaw;
|
|
861
|
+
} else if (useShadowMask) {
|
|
862
|
+
// The mask already holds the identical shadow (same PCSS + distance
|
|
863
|
+
// fade + shadowStrength) rendered by the ShadowMaskPass; read the
|
|
864
|
+
// combine light's channel. Sample by screen UV, matching how the
|
|
865
|
+
// other screen-space inputs (color/depth) are sampled above.
|
|
866
|
+
this.transmissionShadowRaw = pb.dot(pb.textureArraySampleLevel(this.Z_UniformShadowMask, this.uv, this.shadowMaskLayer, 0), this.shadowMaskChannel);
|
|
867
|
+
this.transmissionShadow = this.transmissionShadowRaw;
|
|
868
|
+
}
|
|
779
869
|
this.$if(pb.and(pb.and(pb.and(pb.greaterThan(this.profileStrength, 1e-4), pb.greaterThan(this.profileSlot, 0)), this.profileActive), pb.lessThan(this.depth01, 1)), function() {
|
|
780
870
|
this.$l.widthStrength = pb.clamp(this.param.g, 0, 0.999);
|
|
781
871
|
this.$l.profileSettingsA = this.readProfileSettingsA(this.profileSlot);
|
|
@@ -819,11 +909,9 @@ import { AbstractPostEffect, PostEffectLayer } from './posteffect.js';
|
|
|
819
909
|
this.$l.sunDirWS = this.calculateMainLightDirection(this.worldPos, this.mainLightType, this.mainLightPosRange, this.mainLightDirCutoff, this.sunDir);
|
|
820
910
|
this.$l.mainLightAttenuation = this.calculateMainLightAttenuation(this.worldPos, this.mainLightType, this.mainLightPosRange, this.mainLightDirCutoff);
|
|
821
911
|
this.$l.frontLit = pb.mul(pb.dot(this.normalWS, this.sunDirWS), this.mainLightAttenuation);
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
this.transmissionShadowRaw = this.calculateTransmissionShadow(this.worldPos, this.depth01, pb.clamp(pb.abs(pb.dot(this.normalWS, this.sunDirWS)), 0, 1));
|
|
826
|
-
}
|
|
912
|
+
// transmissionShadowRaw/transmissionShadow were computed in uniform
|
|
913
|
+
// control flow at the top of main (PCSS sampling uses dpdx, which
|
|
914
|
+
// WGSL forbids inside this non-uniform branch); reuse them here.
|
|
827
915
|
this.transmissionShadow = this.transmissionShadowRaw;
|
|
828
916
|
this.$l.transmissionLightAttenuation = pb.mul(this.mainLightAttenuation, this.transmissionShadow);
|
|
829
917
|
this.$l.thinnessComponents = this.estimateScreenThinnessComponents(this.uv, this.depth01, this.normalWS, this.radiusResponse);
|