@forgeax/engine-render 0.1.31 → 0.1.32
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 +68 -1
- package/dist/assembly/webgpu-ready.d.ts +2 -1
- package/dist/assembly/webgpu-ready.d.ts.map +1 -1
- package/dist/assembly/webgpu-renderer.d.ts.map +1 -1
- package/dist/{chunk-C3DDSXYK.mjs → chunk-4NNZQCL3.mjs} +110 -35
- package/dist/chunk-4NNZQCL3.mjs.map +1 -0
- package/dist/{chunk-JRBDO2KB.mjs → chunk-6TFBXLRJ.mjs} +19 -7
- package/dist/chunk-6TFBXLRJ.mjs.map +1 -0
- package/dist/{chunk-FUUO4UND.mjs → chunk-DRR7D3KX.mjs} +3 -3
- package/dist/chunk-DRR7D3KX.mjs.map +1 -0
- package/dist/{chunk-S5UE2T5P.mjs → chunk-GWCEMDVR.mjs} +380 -4
- package/dist/chunk-GWCEMDVR.mjs.map +1 -0
- package/dist/{chunk-MDQJPY3T.mjs → chunk-JCIRYQ4V.mjs} +3 -3
- package/dist/{chunk-MDQJPY3T.mjs.map → chunk-JCIRYQ4V.mjs.map} +1 -1
- package/dist/{chunk-PSEQ6QPH.mjs → chunk-JRIPCMYC.mjs} +17 -10
- package/dist/chunk-JRIPCMYC.mjs.map +1 -0
- package/dist/{chunk-7MQ3XBSP.mjs → chunk-LULCA3OF.mjs} +4 -4
- package/dist/{chunk-7MQ3XBSP.mjs.map → chunk-LULCA3OF.mjs.map} +1 -1
- package/dist/{chunk-NO4WZCAH.mjs → chunk-S665NJNF.mjs} +3 -3
- package/dist/{chunk-NO4WZCAH.mjs.map → chunk-S665NJNF.mjs.map} +1 -1
- package/dist/components/depth-of-field.d.ts +28 -0
- package/dist/components/depth-of-field.d.ts.map +1 -0
- package/dist/components/directional-light.d.ts +2 -1
- package/dist/components/directional-light.d.ts.map +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/construct-renderer.mjs +898 -328
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/extract/camera.d.ts.map +1 -1
- package/dist/features/depth-of-field/depth-of-field-assembly.d.ts +19 -0
- package/dist/features/depth-of-field/depth-of-field-assembly.d.ts.map +1 -0
- package/dist/features/depth-of-field/depth-of-field-feature.d.ts +43 -0
- package/dist/features/depth-of-field/depth-of-field-feature.d.ts.map +1 -0
- package/dist/features/depth-of-field/depth-of-field-inspection.d.ts +34 -0
- package/dist/features/depth-of-field/depth-of-field-inspection.d.ts.map +1 -0
- package/dist/features/depth-of-field/depth-of-field-params.d.ts +83 -0
- package/dist/features/depth-of-field/depth-of-field-params.d.ts.map +1 -0
- package/dist/features/types.d.ts +19 -1
- package/dist/features/types.d.ts.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +6 -5
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +35 -0
- package/dist/inspection-types.d.ts.map +1 -1
- package/dist/instances.d.ts +7 -0
- package/dist/instances.d.ts.map +1 -1
- package/dist/internal.mjs +6 -6
- package/dist/mesh-material-bindings.d.ts +3 -0
- package/dist/mesh-material-bindings.d.ts.map +1 -1
- package/dist/pipeline/standard-output/graph.d.ts.map +1 -1
- package/dist/pipeline/standard-output/types.d.ts +4 -2
- package/dist/pipeline/standard-output/types.d.ts.map +1 -1
- package/dist/pipeline/standard-post.d.ts.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/record/frame-snapshot.d.ts +21 -1
- package/dist/record/frame-snapshot.d.ts.map +1 -1
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts +7 -0
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/recovery/render-system-candidate.d.ts.map +1 -1
- package/dist/render-contract.d.ts +8 -1
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-graph-primitives.d.ts +2 -0
- package/dist/render-graph-primitives.d.ts.map +1 -1
- package/dist/render-pipeline.d.ts +13 -1
- package/dist/render-pipeline.d.ts.map +1 -1
- package/dist/render-system-extract-tail.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +18 -4
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system.d.ts +2 -1
- package/dist/render-system.d.ts.map +1 -1
- package/dist/temporal/index.mjs +5 -5
- package/dist/typed-render-graph-primitives.d.ts.map +1 -1
- package/package.json +21 -21
- package/src/__tests__/gpu-driven-baseline.characterization.test.ts +12 -0
- package/src/__tests__/gpu-driven-production.integration.test.ts +27 -1
- package/src/__tests__/instances-store.unit.test.ts +15 -0
- package/src/__tests__/prepared-gpu-driven-pbr.integration.test.ts +28 -0
- package/src/assembly/webgpu-ready.ts +5 -5
- package/src/assembly/webgpu-renderer.ts +14 -14
- package/src/components/depth-of-field.ts +45 -0
- package/src/components/directional-light.ts +2 -1
- package/src/components/index.ts +1 -0
- package/src/extract/camera.ts +22 -2
- package/src/features/depth-of-field/__tests__/depth-of-field-params.unit.test.ts +943 -0
- package/src/features/depth-of-field/depth-of-field-assembly.ts +100 -0
- package/src/features/depth-of-field/depth-of-field-feature.ts +295 -0
- package/src/features/depth-of-field/depth-of-field-inspection.ts +237 -0
- package/src/features/depth-of-field/depth-of-field-params.ts +556 -0
- package/src/features/host.ts +1 -1
- package/src/features/types.ts +18 -1
- package/src/index.ts +32 -0
- package/src/inspection-types.ts +38 -0
- package/src/instances.ts +19 -5
- package/src/mesh-material-bindings.ts +4 -0
- package/src/pipeline/standard-output/graph.ts +3 -0
- package/src/pipeline/standard-output/types.ts +4 -1
- package/src/pipeline/standard-post.ts +21 -2
- package/src/plugin.ts +2 -0
- package/src/record/frame-snapshot.ts +26 -1
- package/src/record/frame.ts +39 -6
- package/src/record/main-pass.ts +1 -5
- package/src/record/typed-frame-graph.ts +106 -6
- package/src/recovery/render-system-candidate.ts +6 -0
- package/src/render-contract.ts +11 -0
- package/src/render-graph-primitives.ts +8 -1
- package/src/render-pipeline.ts +17 -1
- package/src/render-system-extract-tail.ts +87 -13
- package/src/render-system-extract.ts +103 -25
- package/src/render-system.ts +78 -0
- package/src/typed-render-graph-primitives.ts +3 -0
- package/dist/chunk-C3DDSXYK.mjs.map +0 -1
- package/dist/chunk-FUUO4UND.mjs.map +0 -1
- package/dist/chunk-JRBDO2KB.mjs.map +0 -1
- package/dist/chunk-PSEQ6QPH.mjs.map +0 -1
- package/dist/chunk-S5UE2T5P.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -101,6 +101,14 @@ plan. Register it at construction with
|
|
|
101
101
|
`createRenderer(canvas, { features: [feature] })`. A feature never receives a
|
|
102
102
|
device, queue, encoder, staging builder, or submit callback.
|
|
103
103
|
|
|
104
|
+
After a frame reaches queue submission, the optional `onFrameSubmitted` callback
|
|
105
|
+
receives a bounded `RenderFeatureSubmission` projection. Its `passes` contain
|
|
106
|
+
only work admitted after prepared-resource resolution, so producer diagnostics
|
|
107
|
+
can distinguish submitted compute dispatches and graphics draws from a plan
|
|
108
|
+
that was still pending. This is a receipt of admitted commands, not a GPU
|
|
109
|
+
readback or proof that an indirect draw produced non-zero instances; producers
|
|
110
|
+
that need those facts must use their existing readback or tape evidence.
|
|
111
|
+
|
|
104
112
|
## RenderFeature: the producer seam (first-read index)
|
|
105
113
|
|
|
106
114
|
The public route is one `RenderFeature<FrameData>` through the active RenderGraph
|
|
@@ -157,6 +165,13 @@ surface receiver position along its world-space normal before projection (defaul
|
|
|
157
165
|
Normal offset and depth bias are independent: increasing the CSM depth span must
|
|
158
166
|
not magnify the world-space normal offset. Both PCF and PCSS project the offset
|
|
159
167
|
receiver; volumetric samples have no surface normal and use only depth bias.
|
|
168
|
+
Surface receivers also get a per-cascade depth correction derived from the
|
|
169
|
+
world size of a shadow texel, the filter footprint, and the receiver's depth
|
|
170
|
+
slope along the light's two image axes. The existing normal offset counts
|
|
171
|
+
toward this coverage; only the missing amount is added to `depthBias`, after
|
|
172
|
+
conversion through that cascade's light-space depth span. PCSS derives its
|
|
173
|
+
blocker-search and comparison coverage separately from their actual radii.
|
|
174
|
+
This does not change either author field's units or add shadow texture taps.
|
|
160
175
|
Cascade projections include their incoming blend band, and PCSS depth spans
|
|
161
176
|
match the actual projection, including toward-light caster reach. The normal
|
|
162
177
|
position offset follows the approach in
|
|
@@ -1093,6 +1108,8 @@ renderer.instances.update(collection.collectionId, {
|
|
|
1093
1108
|
renderer.instances.replace(collection.collectionId, identityMatrices(instanceCount + 1));
|
|
1094
1109
|
const current = renderer.instances.inspect(collection.collectionId).unwrap();
|
|
1095
1110
|
const detached = renderer.instances.snapshot(collection.collectionId).unwrap();
|
|
1111
|
+
// A read-only observation does not advance the renderer upload cursor.
|
|
1112
|
+
const observed = renderer.instances.peek(collection.collectionId).unwrap();
|
|
1096
1113
|
renderer.instances.release(collection.collectionId);
|
|
1097
1114
|
```
|
|
1098
1115
|
|
|
@@ -1101,7 +1118,9 @@ storage, `replace` publishes a complete new revision (and grows capacity when
|
|
|
1101
1118
|
needed), `update` validates a bounded matrix interval and records its dirty
|
|
1102
1119
|
range, `inspect` returns identity/count/capacity/revision, `snapshot` returns a
|
|
1103
1120
|
detached matrix copy plus dirty ranges for extraction, and `release` makes the
|
|
1104
|
-
collection id terminal.
|
|
1121
|
+
collection id terminal. `peek` returns the same detached matrices without
|
|
1122
|
+
advancing the renderer upload cursor, so read-only inspection cannot hide a
|
|
1123
|
+
later dirty range. A caller never provides a GPU buffer or maintains
|
|
1105
1124
|
backend-specific chunks. `detached.transforms` is an observation, not mutable
|
|
1106
1125
|
renderer state.
|
|
1107
1126
|
|
|
@@ -2303,3 +2322,51 @@ froxel depth, including the clipped final segment. It does not rotate density
|
|
|
2303
2322
|
samples with frame number: static authored air must not create temporal noise.
|
|
2304
2323
|
Shadow visibility uses matching froxel centers without per-frame XY jitter or
|
|
2305
2324
|
stochastic byte dithering. Shared PCF shadow filtering remains in effect.
|
|
2325
|
+
|
|
2326
|
+
## Camera Depth of Field
|
|
2327
|
+
|
|
2328
|
+
`DepthOfField` is the built-in Standard camera effect for ordinary meshes. Add it
|
|
2329
|
+
only to the active perspective camera; component removal or
|
|
2330
|
+
`maxRadiusPixels: 0` declares the exact zero-work path. The side and quality
|
|
2331
|
+
fields use the closed numeric values exported by this package:
|
|
2332
|
+
|
|
2333
|
+
```ts
|
|
2334
|
+
import {
|
|
2335
|
+
DepthOfField,
|
|
2336
|
+
DepthOfFieldQualityValue,
|
|
2337
|
+
DepthOfFieldSideValue,
|
|
2338
|
+
} from '@forgeax/engine-render';
|
|
2339
|
+
|
|
2340
|
+
world.addComponent(camera, {
|
|
2341
|
+
component: DepthOfField,
|
|
2342
|
+
data: {
|
|
2343
|
+
focusDistance: 8,
|
|
2344
|
+
fStop: 1.4,
|
|
2345
|
+
sensorHeight: 0.024,
|
|
2346
|
+
maxRadiusPixels: 16,
|
|
2347
|
+
quality: DepthOfFieldQualityValue.medium,
|
|
2348
|
+
blurSide: DepthOfFieldSideValue.both,
|
|
2349
|
+
},
|
|
2350
|
+
});
|
|
2351
|
+
```
|
|
2352
|
+
|
|
2353
|
+
The near, far and both presets share one signed thin-lens CoC. `quality` changes
|
|
2354
|
+
sampling density only, so it does not change the optical radius. The graph uses
|
|
2355
|
+
the Standard `RenderExtent`: full-resolution CoC/composite targets follow the
|
|
2356
|
+
current internal or output domain, and half-resolution targets use
|
|
2357
|
+
`max(1, ceil(axis / 2))`. Current temporal-v1 depth validity and the resolved
|
|
2358
|
+
multisampled depth binding remain the source of truth.
|
|
2359
|
+
|
|
2360
|
+
After a real `draw()` submission, read `renderer.inspect().depthOfField` for the
|
|
2361
|
+
requested component values, effective submitted values, graph/device
|
|
2362
|
+
generations, extents, pass count and descriptor-derived bytes. `lastKnownGood`
|
|
2363
|
+
and `effective` stay bound to the accepted submission; a failed candidate keeps
|
|
2364
|
+
the prior accepted projection and reports its failure reason for recovery.
|
|
2365
|
+
When the active camera has no `DepthOfField` component, the inspection remains
|
|
2366
|
+
available with `status: 'off'` and zero DoF graph facts. Invalid fields and an
|
|
2367
|
+
orthographic camera stay on the normal camera snapshot path with structured
|
|
2368
|
+
`error.code`, `error.expected`, `error.hint`, and `error.detail`; they report
|
|
2369
|
+
`status: 'invalid'` or `status: 'unsupported'` without admitting a DoF graph.
|
|
2370
|
+
The Engine Preview/game capability lab uses this same component on its ordinary
|
|
2371
|
+
mesh camera, and its settings control toggles component presence through the
|
|
2372
|
+
normal World path.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { RenderPipeline, Result, RhiDevice, ShaderModule } from '@forgeax/engine-rhi';
|
|
2
2
|
import { RhiError } from '@forgeax/engine-rhi';
|
|
3
3
|
import { type ShaderCatalog } from '@forgeax/engine-shader';
|
|
4
|
+
import { prewarmDepthOfField } from '../features/depth-of-field/depth-of-field-assembly';
|
|
4
5
|
export type { MaterialShaderManifestEntry } from '@forgeax/engine-shader';
|
|
5
6
|
import type { GpuResidencyCache } from '../device/gpu-residency';
|
|
6
7
|
import type { DeviceScope, RhiErrorListenerRegistry } from '../lifecycle';
|
|
@@ -49,7 +50,7 @@ requiredFullscreenPostProcesses: readonly {
|
|
|
49
50
|
registerBuiltinFxaa: (source: string) => void, registerBuiltinTemporalPostProcesses: (entries: {
|
|
50
51
|
readonly motionBlur?: string;
|
|
51
52
|
readonly taaResolve?: string;
|
|
52
|
-
}) => void,
|
|
53
|
+
}) => void, registerBuiltinDepthOfField: Parameters<typeof prewarmDepthOfField>[2],
|
|
53
54
|
/** Install manifest-owned volume utility sources only after all four modules compile. */
|
|
54
55
|
setVolumetricFogShaderSources: (sources: VolumetricFogShaderSources) => void,
|
|
55
56
|
/** Install manifest-owned SSR utility sources only after all five modules compile. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webgpu-ready.d.ts","sourceRoot":"","sources":["../../src/assembly/webgpu-ready.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAKV,cAAc,EACd,MAAM,EACN,SAAS,EAET,YAAY,EACb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAM,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"webgpu-ready.d.ts","sourceRoot":"","sources":["../../src/assembly/webgpu-ready.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAKV,cAAc,EACd,MAAM,EACN,SAAS,EAET,YAAY,EACb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAM,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAG9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,oDAAoD,CAAC;AAIzF,YAAY,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAE1E,OAAO,KAAK,EAAE,iBAAiB,EAAkB,MAAM,yBAAyB,CAAC;AAwBjF,OAAO,KAAK,EAAE,WAAW,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAE1E,OAAO,EAGL,KAAK,sBAAsB,EAG5B,MAAM,iBAAiB,CAAC;AAmBzB,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EAErB,KAAK,0BAA0B,EAChC,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,aAAa,EAEnB,MAAM,kBAAkB,CAAC;AAQ1B,OAAO,EAIL,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAEnB,MAAM,kBAAkB,CAAC;AAmB1B;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,WAAW,EAC1B,SAAS,EAAE,MAAM,aAAa,EAC9B,QAAQ,EAAE,iBAAiB,EAC3B,uBAAuB,EACnB,CAAC,CACC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,KAC/C,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC,GAC7C,SAAS,EACb,aAAa,EAAE,wBAAwB;AACvC;;;;GAIG;AACH,uBAAuB,EAAE,SAAS,MAAM,EAAE,EAC1C,2BAA2B,EAAE,MAAM;AACnC,8EAA8E;AAC9E,+BAA+B,EAAE,SAAS;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,EAAE,EAUH,mBAAmB,EAAE,CACnB,IAAI,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,kBAAkB,EACjD,KAAK,EAAE,aAAa,KACjB,IAAI,EAQT,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,KAAK,IAAI,EAQ/D,+BAA+B,EAAE,CAC/B,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,cAAc,EACnB,cAAc,EAAE,sBAAsB,KACnC,IAAI,EAST,sBAAsB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI;AAChD,sEAAsE;AACtE,mBAAmB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,EAC7C,oCAAoC,EAAE,CAAC,OAAO,EAAE;IAC9C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B,KAAK,IAAI,EACV,2BAA2B,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC;AACtE,yFAAyF;AACzF,6BAA6B,EAAE,CAAC,OAAO,EAAE,0BAA0B,KAAK,IAAI;AAC5E,sFAAsF;AACtF,mBAAmB,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI;AACxD,wFAAwF;AACxF,0BAA0B,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,IAAI,GACrE,OAAO,CAAC,aAAa,CAAC,CAuxHxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webgpu-renderer.d.ts","sourceRoot":"","sources":["../../src/assembly/webgpu-renderer.ts"],"names":[],"mappings":"AAyCA,YAAY,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"webgpu-renderer.d.ts","sourceRoot":"","sources":["../../src/assembly/webgpu-renderer.ts"],"names":[],"mappings":"AAyCA,YAAY,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAyE1E,OAAO,KAAK,EAUV,eAAe,EAQhB,MAAM,oBAAoB,CAAC;AAgB5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAkEzD,YAAY,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAUlF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAUhE,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,YAAY,EACV,UAAU,EACV,6BAA6B,EAC7B,iCAAiC,GAClC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,2BAA2B,EAC3B,oCAAoC,EACpC,iCAAiC,EACjC,uCAAuC,EACvC,oCAAoC,EACpC,+BAA+B,EAC/B,+BAA+B,EAC/B,wCAAwC,EACxC,uBAAuB,EACvB,8BAA8B,EAC9B,wCAAwC,GACzC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,EAC1B,4BAA4B,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,0BAA0B,EAC/B,KAAK,kBAAkB,EACvB,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EACL,gCAAgC,EAChC,4BAA4B,EAC5B,0BAA0B,EAC1B,yBAAyB,EACzB,4CAA4C,GAC7C,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACzF,OAAO,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAI7E,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,iBAAiB,GAAG,eAAe,EAC3C,OAAO,EAAE,eAAe,GAAG,SAAS,EACpC,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,cAAc,GAAG,SAAS,GAClC,OAAO,CAAC,aAAa,CAAC,CAExB"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { GlyphText } from './chunk-ILQ5MEZF.mjs';
|
|
2
|
-
import { MeshRenderer, MeshFilter, DirectionalLight, validateDirectionalLightData, PointLight, computeInvRangeSquared, SpotLight, degToCos, RectAreaLight, validateRectAreaLightData, directionalShadowQualityFromF32, PointLightShadow, Skylight, LightProbe, validateLightProbeData, SkyboxBackground, Atmosphere, Instances, Layer, Points, Lines, SortKey, resolveMeshMaterialBindings, pointShapeFromU32, PostProcessParams, buildCubeCameraFaceViews, CubeCamera, cubeCameraUpdateIntentFromF32, ReflectionProbe, reflectionProbeUpdateIntentFromF32, tonemapToU32, resolveVisibility, Fog, VolumetricFog, resolveSelectedVolumetricLight, extractVolumetricFog, MotionBlur, DynamicResolution, ScreenSpaceReflection, Camera, CAMERA_EXPOSURE_MODE_MANUAL, cameraExposureFromColumns, antialiasFromF32, validateDynamicResolutionCamera, bloomEnabledFromF32, tonemapFromF32
|
|
2
|
+
import { MeshRenderer, MeshFilter, DirectionalLight, validateDirectionalLightData, PointLight, computeInvRangeSquared, SpotLight, degToCos, RectAreaLight, validateRectAreaLightData, directionalShadowQualityFromF32, PointLightShadow, Skylight, LightProbe, validateLightProbeData, SkyboxBackground, Atmosphere, Instances, Layer, Points, Lines, SortKey, resolveMeshMaterialBindings, pointShapeFromU32, PostProcessParams, buildCubeCameraFaceViews, CubeCamera, cubeCameraUpdateIntentFromF32, ReflectionProbe, reflectionProbeUpdateIntentFromF32, tonemapToU32, resolveVisibility, Fog, VolumetricFog, resolveSelectedVolumetricLight, extractVolumetricFog, MotionBlur, DynamicResolution, ScreenSpaceReflection, DepthOfField, Camera, cameraProjectionFromF32, resolveDepthOfFieldParams, depthOfFieldRequestFailure, CAMERA_EXPOSURE_MODE_MANUAL, cameraExposureFromColumns, antialiasFromF32, validateDynamicResolutionCamera, bloomEnabledFromF32, tonemapFromF32 } from './chunk-GWCEMDVR.mjs';
|
|
3
3
|
import { SpriteRegionOverride, SpriteInstances, selectActiveCameraIndex, getActiveCamera } from './chunk-PA5DRJNI.mjs';
|
|
4
|
-
import { PROBE_BLEND_RECORD_CAPACITY, GPU_BUFFER_USAGE_MAP_READ, GPU_BUFFER_USAGE_VERTEX, GPU_BUFFER_USAGE_COPY_DST, gpuDrivenShadowDrawKey, IES_SLICE_CAPACITY, COOKIE_SLICE_CAPACITY, isStandardPbrSkinMaterialShader, buildGpuDrivenDraws, worldEntityKey, gpuDrivenSourceDrawItemIndex, selectPasses, resolveRenderTargetMaterialSource, isCanonicalStandardPbrMaterialShader, PROBE_BLEND_RECORD_BYTE_SIZE, GPU_BUFFER_USAGE_UNIFORM, GPU_BUFFER_USAGE_QUERY_RESOLVE, GPU_BUFFER_USAGE_COPY_SRC, COOKIE_SLICE_SIZE, isStandardPbrMaterialShader } from './chunk-
|
|
5
|
-
import { STANDARD_OUTPUT_TRANSFORM_FEATURE_ID, SHADOW_ATLAS_DEFAULT_LAYERS,
|
|
4
|
+
import { PROBE_BLEND_RECORD_CAPACITY, GPU_BUFFER_USAGE_MAP_READ, GPU_BUFFER_USAGE_VERTEX, GPU_BUFFER_USAGE_COPY_DST, gpuDrivenShadowDrawKey, IES_SLICE_CAPACITY, COOKIE_SLICE_CAPACITY, isStandardPbrSkinMaterialShader, buildGpuDrivenDraws, worldEntityKey, gpuDrivenSourceDrawItemIndex, selectPasses, resolveRenderTargetMaterialSource, isCanonicalStandardPbrMaterialShader, PROBE_BLEND_RECORD_BYTE_SIZE, GPU_BUFFER_USAGE_UNIFORM, GPU_BUFFER_USAGE_QUERY_RESOLVE, GPU_BUFFER_USAGE_COPY_SRC, COOKIE_SLICE_SIZE, isStandardPbrMaterialShader } from './chunk-DRR7D3KX.mjs';
|
|
5
|
+
import { STANDARD_OUTPUT_TRANSFORM_FEATURE_ID, SHADOW_ATLAS_DEFAULT_LAYERS, MaterialSkinAttrMissingError, SkinMaterialMismatchError, InstanceCollectionError, ShadowInvalidConfigError, EnvironmentSourceConflictError, FogCardinalityError, GPU_TEXTURE_USAGE_COPY_SRC, GPU_TEXTURE_USAGE_COPY_DST, GPU_TEXTURE_USAGE_TEXTURE_BINDING, GPU_TEXTURE_USAGE_STORAGE_BINDING, GPU_TEXTURE_USAGE_RENDER_ATTACHMENT, AtmosphereInvalidParameterError } from './chunk-6TFBXLRJ.mjs';
|
|
6
6
|
import { R_MIN, ok, err, TextError, toShared, handleSlot, AssetError, ASSET_ERROR_HINTS, materialValuesToLinearRuntime, derive, unpackSlot, materialGuidText } from '@forgeax/engine-types';
|
|
7
7
|
import { err as err$1, ok as ok$1, RhiError } from '@forgeax/engine-rhi';
|
|
8
8
|
import { resolveAssetHandle, walkMaterialPassesOverSharedRefs, selectMaterialPassProgram, materialParametersToParamSchema as materialParametersToParamSchema$1 } from '@forgeax/engine-assets-runtime';
|
|
@@ -1984,6 +1984,14 @@ function buildShadowFrusta(lights) {
|
|
|
1984
1984
|
function skinPaletteIdentity(world, entity) {
|
|
1985
1985
|
return `skin:${world.identity}:${entity}`;
|
|
1986
1986
|
}
|
|
1987
|
+
function materialProgramSelectionRequiresSkin(selection) {
|
|
1988
|
+
if (selection.abi?.skinPaletteAddress !== void 0) return true;
|
|
1989
|
+
const semantics = new Set((selection.abi?.vertexInputs ?? []).map((input) => input.semantic));
|
|
1990
|
+
return semantics.has("skinIndex") && semantics.has("skinWeight");
|
|
1991
|
+
}
|
|
1992
|
+
function isMissingMaterialProgram(error) {
|
|
1993
|
+
return error !== null && typeof error === "object" && error.code === "material-specialization-not-cooked";
|
|
1994
|
+
}
|
|
1987
1995
|
function extractFrames(worlds, owner, assets, pipelineState, materialSnapshotCachesByWorld, options = {}) {
|
|
1988
1996
|
const cameraOwner = typeof owner === "number" ? owner : owner.cameraOwner;
|
|
1989
1997
|
const resourceOwner = typeof owner === "number" ? owner : owner.resourceOwner;
|
|
@@ -3198,6 +3206,7 @@ function extractFrame(world, context) {
|
|
|
3198
3206
|
const handleRaw = materialHandles[0] ?? 0;
|
|
3199
3207
|
const cachedMaterial = handleRaw !== 0 && !hasSpriteRegionOverride && !hasSkin ? materialSnapshotCache.get(handleRaw) : void 0;
|
|
3200
3208
|
let materialSnap;
|
|
3209
|
+
let materialProgramSelections;
|
|
3201
3210
|
if (cachedMaterial !== void 0) {
|
|
3202
3211
|
materialSnap = cachedMaterial.snapshot;
|
|
3203
3212
|
if (isRenderable) {
|
|
@@ -3293,10 +3302,41 @@ function extractFrame(world, context) {
|
|
|
3293
3302
|
...context.materialContext,
|
|
3294
3303
|
geometry: hasSkin ? "skinned" : context.materialContext.geometry
|
|
3295
3304
|
};
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3305
|
+
try {
|
|
3306
|
+
materialProgramSelections = materialProgramSelectionsForMaterial(
|
|
3307
|
+
asset,
|
|
3308
|
+
assets,
|
|
3309
|
+
materialContext
|
|
3310
|
+
);
|
|
3311
|
+
} catch (error) {
|
|
3312
|
+
if (isMissingMaterialProgram(error) && materialContext?.geometry === "mesh") {
|
|
3313
|
+
try {
|
|
3314
|
+
const skinnedSelections = materialProgramSelectionsForMaterial(asset, assets, {
|
|
3315
|
+
...materialContext,
|
|
3316
|
+
geometry: "skinned"
|
|
3317
|
+
});
|
|
3318
|
+
if (skinnedSelections?.some(materialProgramSelectionRequiresSkin) === true && gpuDrivenMesh !== void 0) {
|
|
3319
|
+
const hasSkinIndex = gpuDrivenMesh.attributes.skinIndex !== void 0;
|
|
3320
|
+
const hasSkinWeight = gpuDrivenMesh.attributes.skinWeight !== void 0;
|
|
3321
|
+
if (!hasSkinIndex || !hasSkinWeight) {
|
|
3322
|
+
const missing = !hasSkinIndex && !hasSkinWeight ? "both" : !hasSkinIndex ? "skinIndex" : "skinWeight";
|
|
3323
|
+
worldInternal._routeError(new MaterialSkinAttrMissingError(entity, missing), {
|
|
3324
|
+
severity: Severity.Error,
|
|
3325
|
+
systemName: "RenderSystem.extract (material-skin-attr-missing)"
|
|
3326
|
+
});
|
|
3327
|
+
continue;
|
|
3328
|
+
}
|
|
3329
|
+
}
|
|
3330
|
+
} catch {
|
|
3331
|
+
}
|
|
3332
|
+
}
|
|
3333
|
+
throw error;
|
|
3334
|
+
}
|
|
3335
|
+
const materialProgramKeys = materialProgramSelections === void 0 ? void 0 : Object.fromEntries(
|
|
3336
|
+
materialProgramSelections.map(({ pass, specializationKey }) => [
|
|
3337
|
+
pass,
|
|
3338
|
+
specializationKey
|
|
3339
|
+
])
|
|
3300
3340
|
);
|
|
3301
3341
|
const materialSceneIndexProgramKeys = materialSceneIndexProgramKeysForMaterial(
|
|
3302
3342
|
asset,
|
|
@@ -3341,7 +3381,7 @@ function extractFrame(world, context) {
|
|
|
3341
3381
|
);
|
|
3342
3382
|
{
|
|
3343
3383
|
const hasSkinSkel = hasSkin && skinSkeletonView !== void 0 && skinSkeletonView !== void 0 && skinSkeletonView !== 0;
|
|
3344
|
-
const isPbrSkinMaterial = isStandardPbrSkinMaterialShader(firstPassShader);
|
|
3384
|
+
const isPbrSkinMaterial = materialProgramSelections?.some(materialProgramSelectionRequiresSkin) === true || isStandardPbrSkinMaterialShader(firstPassShader);
|
|
3345
3385
|
if (hasSkinSkel && !isPbrSkinMaterial) {
|
|
3346
3386
|
worldInternal._routeError(new SkinMaterialMismatchError(entity, firstPassShader), {
|
|
3347
3387
|
severity: Severity.Error,
|
|
@@ -3707,7 +3747,7 @@ function extractFrame(world, context) {
|
|
|
3707
3747
|
}
|
|
3708
3748
|
if (skinSlice === void 0 && hasSkin) {
|
|
3709
3749
|
releaseSkinIdentity();
|
|
3710
|
-
if (materialSnap.materialShaderId === "forgeax::pbr-skin") {
|
|
3750
|
+
if (materialSnap.materialShaderId === "forgeax::pbr-skin" || materialProgramSelections?.some(materialProgramSelectionRequiresSkin) === true) {
|
|
3711
3751
|
pendingDispatch.length = 0;
|
|
3712
3752
|
continue;
|
|
3713
3753
|
}
|
|
@@ -4310,6 +4350,30 @@ function runtimeMaterialShaderId(module, passName) {
|
|
|
4310
4350
|
function materialProgramKeysForMaterial(material, assets, context) {
|
|
4311
4351
|
return materialProgramKeysForAddress(material, assets, context, "direct");
|
|
4312
4352
|
}
|
|
4353
|
+
function materialProgramSelectionsForMaterial(material, assets, context, address = "direct") {
|
|
4354
|
+
const projection = assets.getMaterialProjectionForPayload(material);
|
|
4355
|
+
if (projection === void 0) return void 0;
|
|
4356
|
+
if (context === void 0)
|
|
4357
|
+
throw new Error("Published material selection requires renderer-owned compiler context");
|
|
4358
|
+
return projection.passes.map((pass) => {
|
|
4359
|
+
const mode = String(
|
|
4360
|
+
pass.renderState?.tags?.LightMode ?? pass.name
|
|
4361
|
+
);
|
|
4362
|
+
const passKind = /shadow/i.test(mode) ? "shadow" : /depth/i.test(mode) ? "depth" : "forward";
|
|
4363
|
+
const selectedContext = {
|
|
4364
|
+
...context,
|
|
4365
|
+
pass: passKind,
|
|
4366
|
+
pipeline: /deferred|gbuffer/i.test(mode) ? "deferred" : context.pipeline
|
|
4367
|
+
};
|
|
4368
|
+
const selected = selectMaterialPassProgram(projection, pass.name, selectedContext, address);
|
|
4369
|
+
return {
|
|
4370
|
+
pass: pass.name,
|
|
4371
|
+
context: selectedContext,
|
|
4372
|
+
specializationKey: selected.specializationKey,
|
|
4373
|
+
...selected.abi === void 0 ? {} : { abi: selected.abi }
|
|
4374
|
+
};
|
|
4375
|
+
});
|
|
4376
|
+
}
|
|
4313
4377
|
function materialSceneIndexProgramKeysForMaterial(material, assets, context) {
|
|
4314
4378
|
const projection = assets.getMaterialProjectionForPayload(material);
|
|
4315
4379
|
if (projection === void 0) return void 0;
|
|
@@ -4335,35 +4399,19 @@ function materialSceneIndexProgramKeysForMaterial(material, assets, context) {
|
|
|
4335
4399
|
);
|
|
4336
4400
|
entries[pass.name] = { specializationKey: selected.specializationKey, pass: passKind };
|
|
4337
4401
|
} catch (error) {
|
|
4338
|
-
if (!
|
|
4402
|
+
if (!isMissingMaterialProgram2(error)) throw error;
|
|
4339
4403
|
}
|
|
4340
4404
|
}
|
|
4341
4405
|
return Object.keys(entries).length === 0 ? void 0 : entries;
|
|
4342
4406
|
}
|
|
4343
|
-
function
|
|
4407
|
+
function isMissingMaterialProgram2(error) {
|
|
4344
4408
|
return error !== null && typeof error === "object" && error.code === "material-specialization-not-cooked";
|
|
4345
4409
|
}
|
|
4346
4410
|
function materialProgramKeysForAddress(material, assets, context, address) {
|
|
4347
|
-
const
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
const entries = [];
|
|
4352
|
-
for (const pass of projection.passes) {
|
|
4353
|
-
const mode = String(
|
|
4354
|
-
pass.renderState?.tags?.LightMode ?? pass.name
|
|
4355
|
-
);
|
|
4356
|
-
const selectedContext = {
|
|
4357
|
-
...context,
|
|
4358
|
-
pass: /shadow/i.test(mode) ? "shadow" : /depth/i.test(mode) ? "depth" : "forward",
|
|
4359
|
-
pipeline: /deferred|gbuffer/i.test(mode) ? "deferred" : context.pipeline
|
|
4360
|
-
};
|
|
4361
|
-
entries.push([
|
|
4362
|
-
pass.name,
|
|
4363
|
-
selectMaterialPassProgram(projection, pass.name, selectedContext, address).specializationKey
|
|
4364
|
-
]);
|
|
4365
|
-
}
|
|
4366
|
-
return entries.length === 0 ? void 0 : Object.fromEntries(entries);
|
|
4411
|
+
const selections = materialProgramSelectionsForMaterial(material, assets, context, address);
|
|
4412
|
+
return selections === void 0 ? void 0 : Object.fromEntries(
|
|
4413
|
+
selections.map(({ pass, specializationKey }) => [pass, specializationKey])
|
|
4414
|
+
);
|
|
4367
4415
|
}
|
|
4368
4416
|
function runtimeMaterialShaderIdForMaterial(passes, programs) {
|
|
4369
4417
|
const pass = passes.find(
|
|
@@ -4965,6 +5013,22 @@ function computeDirectionalCsm(direction, config, cameraData) {
|
|
|
4965
5013
|
if ((ls[2] ?? 0) < minZ) minZ = ls[2] ?? 0;
|
|
4966
5014
|
if ((ls[2] ?? 0) > maxZ) maxZ = ls[2] ?? 0;
|
|
4967
5015
|
}
|
|
5016
|
+
const texelX = (maxX - minX) / config.mapSize;
|
|
5017
|
+
const texelY = (maxY - minY) / config.mapSize;
|
|
5018
|
+
if (Number.isFinite(texelX) && texelX > 0) {
|
|
5019
|
+
const centerX = (minX + maxX) * 0.5;
|
|
5020
|
+
const snappedCenterX = Math.round(centerX / texelX) * texelX;
|
|
5021
|
+
const halfWidth = (maxX - minX) * 0.5 + texelX * 0.5;
|
|
5022
|
+
minX = snappedCenterX - halfWidth;
|
|
5023
|
+
maxX = snappedCenterX + halfWidth;
|
|
5024
|
+
}
|
|
5025
|
+
if (Number.isFinite(texelY) && texelY > 0) {
|
|
5026
|
+
const centerY = (minY + maxY) * 0.5;
|
|
5027
|
+
const snappedCenterY = Math.round(centerY / texelY) * texelY;
|
|
5028
|
+
const halfHeight = (maxY - minY) * 0.5 + texelY * 0.5;
|
|
5029
|
+
minY = snappedCenterY - halfHeight;
|
|
5030
|
+
maxY = snappedCenterY + halfHeight;
|
|
5031
|
+
}
|
|
4968
5032
|
const nearZ = Math.max(maxZ, lightSpaceMaxZFull);
|
|
4969
5033
|
const orthoProj = mat4.create();
|
|
4970
5034
|
mat4.orthographic(orthoProj, minX, maxX, maxY, minY, -nearZ, -minZ);
|
|
@@ -5008,14 +5072,23 @@ function collectCameraSnapshots(world) {
|
|
|
5008
5072
|
const cameras = [];
|
|
5009
5073
|
const cameraQuery = world.query({
|
|
5010
5074
|
read: [Camera],
|
|
5011
|
-
optional: [MotionBlur, DynamicResolution, ScreenSpaceReflection],
|
|
5075
|
+
optional: [MotionBlur, DynamicResolution, ScreenSpaceReflection, DepthOfField],
|
|
5012
5076
|
with: [Transform, GlobalTransform]
|
|
5013
5077
|
}).unwrap();
|
|
5014
5078
|
for (const row of cameraQuery) {
|
|
5015
5079
|
const cam = row.get(Camera);
|
|
5016
5080
|
const motionBlur = row.get(MotionBlur);
|
|
5081
|
+
const depthOfField = row.get(DepthOfField);
|
|
5017
5082
|
const dynamicResolution = row.get(DynamicResolution);
|
|
5018
5083
|
const screenSpaceReflection = row.get(ScreenSpaceReflection);
|
|
5084
|
+
const projection = cameraProjectionFromF32(cam.projection);
|
|
5085
|
+
const depthOfFieldResult = resolveDepthOfFieldParams(depthOfField, {
|
|
5086
|
+
projection,
|
|
5087
|
+
fov: cam.fov,
|
|
5088
|
+
near: cam.near,
|
|
5089
|
+
far: cam.far
|
|
5090
|
+
});
|
|
5091
|
+
const depthOfFieldError = depthOfFieldResult.ok ? void 0 : depthOfFieldRequestFailure(depthOfFieldResult.error);
|
|
5019
5092
|
const entity = row.entity;
|
|
5020
5093
|
const view = worldInternal._getArrayView(entity, GlobalTransform, "world");
|
|
5021
5094
|
if (view === void 0) continue;
|
|
@@ -5042,7 +5115,7 @@ function collectCameraSnapshots(world) {
|
|
|
5042
5115
|
aspect: cam.aspect,
|
|
5043
5116
|
near: cam.near,
|
|
5044
5117
|
far: cam.far,
|
|
5045
|
-
projection
|
|
5118
|
+
projection,
|
|
5046
5119
|
orthoLeft: cam.left,
|
|
5047
5120
|
orthoRight: cam.right,
|
|
5048
5121
|
orthoBottom: cam.bottom,
|
|
@@ -5063,6 +5136,8 @@ function collectCameraSnapshots(world) {
|
|
|
5063
5136
|
cam.clearColor[2] ?? 0,
|
|
5064
5137
|
cam.clearColor[3] ?? 1
|
|
5065
5138
|
],
|
|
5139
|
+
...depthOfFieldResult.ok && depthOfFieldResult.value !== void 0 ? { depthOfField: depthOfFieldResult.value } : {},
|
|
5140
|
+
...depthOfFieldError === void 0 ? {} : { depthOfFieldError },
|
|
5066
5141
|
...motionBlur === void 0 ? {} : {
|
|
5067
5142
|
motionBlur: {
|
|
5068
5143
|
shutterAngle: motionBlur.shutterAngle,
|
|
@@ -5904,5 +5979,5 @@ var ProbeBlendSceneProjection = class {
|
|
|
5904
5979
|
};
|
|
5905
5980
|
|
|
5906
5981
|
export { InstanceBoundsCache, OcclusionRenderRuntime, PROBE_MAX_CONTRIBUTORS, ProbeBlendSceneProjection, SKYLIGHT_RECOVERY_FALLBACK, SSR_HISTORY_FORMAT, SsrHistoryOwner, admitProbeContributors, blendLightProbes, buildRectAreaWorldFrame, buildShadowFrusta, createCookieProjectionMatrixData, createExtendedLightingState, createSsrHistoryOwner, createSsrSpatialResources, estimateSsrSpatialMemory, extractFrames, fingerprintNumericArray, glyphTextLayoutSystem, primitiveKey, primitiveKeyId, projectExtendedLightingInspection, promoteExtendedLightingCandidate, recordExtendedLightingFailure, rectAreaFacesPoint, scaledProbeWeight, setOcclusionRuntimeTestHooks, viewKey, viewKeyId };
|
|
5907
|
-
//# sourceMappingURL=chunk-
|
|
5908
|
-
//# sourceMappingURL=chunk-
|
|
5982
|
+
//# sourceMappingURL=chunk-4NNZQCL3.mjs.map
|
|
5983
|
+
//# sourceMappingURL=chunk-4NNZQCL3.mjs.map
|