@forgeax/engine-render 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +139 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/__tests__/gpu-driven-indirect-raster-evidence.d.ts.map +1 -1
- package/dist/assembly/factory.d.ts +7 -0
- package/dist/assembly/factory.d.ts.map +1 -1
- package/dist/assembly/material/assembly.d.ts.map +1 -1
- package/dist/authoring.d.ts +1 -0
- package/dist/authoring.d.ts.map +1 -1
- package/dist/authoring.mjs +1 -1
- package/dist/{chunk-QC4VW3XJ.mjs → chunk-HCOGPHKS.mjs} +17 -3
- package/dist/chunk-HCOGPHKS.mjs.map +1 -0
- package/dist/chunk-YEJIUW7D.mjs +1152 -0
- package/dist/chunk-YEJIUW7D.mjs.map +1 -0
- package/dist/components/__tests__/points-lines-admission.unit.test.d.ts +2 -0
- package/dist/components/__tests__/points-lines-admission.unit.test.d.ts.map +1 -0
- package/dist/components/__tests__/points-lines-schema.unit.test.d.ts +2 -0
- package/dist/components/__tests__/points-lines-schema.unit.test.d.ts.map +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/lines.d.ts +5 -0
- package/dist/components/lines.d.ts.map +1 -0
- package/dist/components/points.d.ts +15 -0
- package/dist/components/points.d.ts.map +1 -0
- package/dist/construct-renderer.mjs +952 -497
- package/dist/construct-renderer.mjs.map +1 -1
- package/dist/errors/render.d.ts +82 -1
- package/dist/errors/render.d.ts.map +1 -1
- package/dist/features/render-graph-raster.d.ts +5 -1
- package/dist/features/render-graph-raster.d.ts.map +1 -1
- package/dist/gpu-driven/production-raster.d.ts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +4 -2
- package/dist/index.mjs.map +1 -1
- package/dist/inspection-types.d.ts +3 -0
- package/dist/inspection-types.d.ts.map +1 -1
- package/dist/pbr-pipeline.d.ts +2 -0
- package/dist/pbr-pipeline.d.ts.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/points-lines/__tests__/bounds.unit.test.d.ts +2 -0
- package/dist/points-lines/__tests__/bounds.unit.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/cache-recovery.unit.test.d.ts +2 -0
- package/dist/points-lines/__tests__/cache-recovery.unit.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/inspection-lanes.integration.test.d.ts +2 -0
- package/dist/points-lines/__tests__/inspection-lanes.integration.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/inspection.unit.test.d.ts +2 -0
- package/dist/points-lines/__tests__/inspection.unit.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/lane-structural.integration.test.d.ts +2 -0
- package/dist/points-lines/__tests__/lane-structural.integration.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/points-lines.bench.d.ts +2 -0
- package/dist/points-lines/__tests__/points-lines.bench.d.ts.map +1 -0
- package/dist/points-lines/__tests__/raster-lane.integration.test.d.ts +2 -0
- package/dist/points-lines/__tests__/raster-lane.integration.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/snapshot.unit.test.d.ts +2 -0
- package/dist/points-lines/__tests__/snapshot.unit.test.d.ts.map +1 -0
- package/dist/points-lines/__tests__/view-ubo.unit.test.d.ts +2 -0
- package/dist/points-lines/__tests__/view-ubo.unit.test.d.ts.map +1 -0
- package/dist/points-lines/admission.d.ts +36 -0
- package/dist/points-lines/admission.d.ts.map +1 -0
- package/dist/points-lines/bounds.d.ts +8 -0
- package/dist/points-lines/bounds.d.ts.map +1 -0
- package/dist/points-lines/expansion-cache.d.ts +28 -0
- package/dist/points-lines/expansion-cache.d.ts.map +1 -0
- package/dist/points-lines/inspection.d.ts +53 -0
- package/dist/points-lines/inspection.d.ts.map +1 -0
- package/dist/points-lines/prepare.d.ts +67 -0
- package/dist/points-lines/prepare.d.ts.map +1 -0
- package/dist/points-lines/record.d.ts +60 -0
- package/dist/points-lines/record.d.ts.map +1 -0
- package/dist/points-lines/snapshot.d.ts +49 -0
- package/dist/points-lines/snapshot.d.ts.map +1 -0
- package/dist/record/frame-lighting.d.ts.map +1 -1
- package/dist/record/frame.d.ts +1 -1
- package/dist/record/frame.d.ts.map +1 -1
- package/dist/record/main-pass-geometry.d.ts +7 -0
- package/dist/record/main-pass-geometry.d.ts.map +1 -1
- package/dist/record/main-pass.d.ts.map +1 -1
- package/dist/record/render-context.d.ts +17 -0
- package/dist/record/render-context.d.ts.map +1 -1
- package/dist/record/shadow-pass.d.ts.map +1 -1
- package/dist/record/skybox-post-pass.d.ts.map +1 -1
- package/dist/record/typed-frame-graph.d.ts.map +1 -1
- package/dist/record/view-ubo.d.ts +6 -0
- package/dist/record/view-ubo.d.ts.map +1 -1
- package/dist/render-contract.d.ts +10 -2
- package/dist/render-contract.d.ts.map +1 -1
- package/dist/render-system-extract.d.ts +3 -0
- package/dist/render-system-extract.d.ts.map +1 -1
- package/dist/render-system.d.ts +4 -1
- package/dist/render-system.d.ts.map +1 -1
- package/dist/scene/render-scene-types.d.ts +3 -0
- package/dist/scene/render-scene-types.d.ts.map +1 -1
- package/dist/scene/render-scene.d.ts +7 -0
- package/dist/scene/render-scene.d.ts.map +1 -1
- package/package.json +19 -19
- package/src/__tests__/authoring-path.unit.test.ts +9 -0
- package/src/__tests__/gpu-driven-indirect-raster-evidence.ts +12 -2
- package/src/__tests__/material-cooked-projection.unit.test.ts +29 -7
- package/src/__tests__/material-static-dynamic-route.unit.test.ts +28 -28
- package/src/__tests__/render-error-code-owner.test-d.ts +6 -0
- package/src/__tests__/render-error-exhaustive.test-d.ts +19 -0
- package/src/__tests__/renderer-factory-material-contract.unit.test.ts +38 -0
- package/src/assembly/factory.ts +72 -3
- package/src/assembly/material/assembly.ts +2 -5
- package/src/authoring.ts +1 -0
- package/src/components/__tests__/points-lines-admission.unit.test.ts +219 -0
- package/src/components/__tests__/points-lines-schema.unit.test.ts +56 -0
- package/src/components/index.ts +7 -0
- package/src/components/lines.ts +18 -0
- package/src/components/points.ts +40 -0
- package/src/errors/render.ts +144 -1
- package/src/features/render-graph-raster.ts +22 -3
- package/src/gpu-driven/production-raster.ts +6 -1
- package/src/index.ts +17 -0
- package/src/inspection-types.ts +4 -0
- package/src/pbr-pipeline.ts +8 -1
- package/src/plugin.ts +4 -0
- package/src/points-lines/__tests__/bounds.unit.test.ts +21 -0
- package/src/points-lines/__tests__/cache-recovery.unit.test.ts +157 -0
- package/src/points-lines/__tests__/inspection-lanes.integration.test.ts +146 -0
- package/src/points-lines/__tests__/inspection.unit.test.ts +173 -0
- package/src/points-lines/__tests__/lane-structural.integration.test.ts +122 -0
- package/src/points-lines/__tests__/points-lines.bench.ts +400 -0
- package/src/points-lines/__tests__/raster-lane.integration.test.ts +44 -0
- package/src/points-lines/__tests__/snapshot.unit.test.ts +101 -0
- package/src/points-lines/__tests__/view-ubo.unit.test.ts +73 -0
- package/src/points-lines/admission.ts +238 -0
- package/src/points-lines/bounds.ts +23 -0
- package/src/points-lines/expansion-cache.ts +215 -0
- package/src/points-lines/inspection.ts +97 -0
- package/src/points-lines/prepare.ts +177 -0
- package/src/points-lines/record.ts +125 -0
- package/src/points-lines/snapshot.ts +130 -0
- package/src/record/frame-lighting.ts +14 -2
- package/src/record/frame.ts +12 -1
- package/src/record/main-pass-geometry.ts +92 -0
- package/src/record/main-pass-sprite-draws.ts +1 -1
- package/src/record/main-pass.ts +6 -3
- package/src/record/render-context.ts +20 -0
- package/src/record/shadow-pass.ts +16 -5
- package/src/record/skybox-post-pass.ts +2 -1
- package/src/record/typed-frame-graph.ts +17 -16
- package/src/record/view-ubo.ts +47 -0
- package/src/render-contract.ts +13 -2
- package/src/render-system-extract.ts +71 -8
- package/src/render-system.ts +304 -2
- package/src/scene/render-scene-types.ts +3 -0
- package/src/scene/render-scene.ts +57 -2
- package/dist/chunk-QC4VW3XJ.mjs.map +0 -1
- package/dist/chunk-SCRSAK5B.mjs +0 -480
- package/dist/chunk-SCRSAK5B.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -90,6 +90,15 @@ not expose a timing controller or a second membership-specific API.
|
|
|
90
90
|
|
|
91
91
|
## RenderFeature: the producer seam (first-read index)
|
|
92
92
|
|
|
93
|
+
### Material contract projection
|
|
94
|
+
|
|
95
|
+
Render consumes only the Pack-owned material publication projection. Its
|
|
96
|
+
inputs are runtime bool/value data, composed module slots, and the closed
|
|
97
|
+
compiler context; render never authors, cooks, writes DDC, or selects a
|
|
98
|
+
fallback material. The projection preserves `layoutIdentity`,
|
|
99
|
+
`programIdentity`, `cookIdentity`, and `materialPublicationIdentity` so a
|
|
100
|
+
stale draw can be traced to the first producer divergence.
|
|
101
|
+
|
|
93
102
|
The public route is one `RenderFeature<FrameData>` through the Standard
|
|
94
103
|
Pipeline and the active RenderGraph pass. In the examples below, `type FrameData`
|
|
95
104
|
is the producer-owned extracted value. A feature extracts one frame value,
|
|
@@ -131,6 +140,136 @@ uses the neutral engine material.
|
|
|
131
140
|
|
|
132
141
|
The render path is `MaterialAsset` -> extract snapshot -> prepare resources -> record the per-slot `coordinates` and values. The effective `parent` is already resolved before extract. If a material contract or reflection binding fails, preserve the structured error and repair the source contract or cooked module before drawing again; that is the recovery route. The render package owns consumption, not material import or cook policy.
|
|
133
142
|
|
|
143
|
+
## Points and Lines authoring (M1)
|
|
144
|
+
|
|
145
|
+
Points and Lines are first-class render components. Their geometry remains a
|
|
146
|
+
normal `MeshAsset`, and their material remains the engine-owned
|
|
147
|
+
`Materials.unlit` asset. The M1 path validates the complete candidate before
|
|
148
|
+
any render publication; it does not add a second mesh, material, CLI, RPC, or
|
|
149
|
+
manifest authority.
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
import { Lines, Materials, PointShapeValue, Points, admitPointsLines } from '@forgeax/engine-render';
|
|
153
|
+
import { World } from '@forgeax/engine-ecs';
|
|
154
|
+
import type { MeshAsset } from '@forgeax/engine-types';
|
|
155
|
+
|
|
156
|
+
const positions = new Float32Array([0, 0, 0, 1, 0, 0, 2, 0, 0]);
|
|
157
|
+
const pointMesh = {
|
|
158
|
+
kind: 'mesh',
|
|
159
|
+
vertices: positions,
|
|
160
|
+
attributes: { position: positions },
|
|
161
|
+
submeshes: [{
|
|
162
|
+
indexOffset: 0,
|
|
163
|
+
indexCount: 0,
|
|
164
|
+
vertexCount: 3,
|
|
165
|
+
topology: 'point-list',
|
|
166
|
+
materialSlot: 0,
|
|
167
|
+
}],
|
|
168
|
+
materialSlots: [{ slotName: 'default' }],
|
|
169
|
+
} satisfies MeshAsset;
|
|
170
|
+
const material = Materials.unlit([1, 0.5, 0.25, 1], { castShadow: false });
|
|
171
|
+
const world = new World();
|
|
172
|
+
const entity = world.spawn({
|
|
173
|
+
component: Points,
|
|
174
|
+
data: { sizePx: 4, shape: PointShapeValue.circle },
|
|
175
|
+
}).unwrap();
|
|
176
|
+
const admitted = admitPointsLines({
|
|
177
|
+
entity,
|
|
178
|
+
points: { sizePx: 4, shape: PointShapeValue.circle },
|
|
179
|
+
mesh: pointMesh,
|
|
180
|
+
material,
|
|
181
|
+
});
|
|
182
|
+
if (!admitted.ok) throw new Error(admitted.error.hint);
|
|
183
|
+
|
|
184
|
+
world.spawn({ component: Lines, data: { widthPx: 2 } }).unwrap();
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
The style vocabulary is deliberately small in M1:
|
|
188
|
+
|
|
189
|
+
| Component | Field | Default | Accepted values |
|
|
190
|
+
|:--|:--|--:|:--|
|
|
191
|
+
| `Points` | `sizePx` | `4` | finite number greater than `0` |
|
|
192
|
+
| `Points` | `shape` | `square` | `square` or `circle` |
|
|
193
|
+
| `Lines` | `widthPx` | `1` | finite number greater than `0` |
|
|
194
|
+
|
|
195
|
+
Admission consumes one style component, one ordinary mesh topology, and one
|
|
196
|
+
unlit forward material. Indexed and non-indexed `point-list` meshes are valid
|
|
197
|
+
for `Points`; indexed and non-indexed paired `line-list` meshes are valid for
|
|
198
|
+
`Lines`.
|
|
199
|
+
|
|
200
|
+
| Candidate | M1 result | Reason |
|
|
201
|
+
|:--|:--:|:--|
|
|
202
|
+
| `Points` + `point-list` + finite positive `sizePx` + unlit forward material | supported | `square` and `circle` are the only point shapes |
|
|
203
|
+
| `Lines` + paired `line-list` + finite positive `widthPx` + unlit forward material | supported | each pair is one line segment |
|
|
204
|
+
| `line-strip`, triangle topology, mixed submeshes, or an odd line-list tail | refused | topology cannot be inferred or admitted atomically |
|
|
205
|
+
| both `Points` and `Lines` on one candidate | refused | one entity has one style lane |
|
|
206
|
+
| `Materials.standard`, shadow-caster, deferred, or another shader module | refused | M1 accepts one engine-owned unlit forward pass |
|
|
207
|
+
| candidate count over `maxPoints` or `maxSegments` | refused | bounded admission prevents partial publication |
|
|
208
|
+
|
|
209
|
+
When admission refuses a candidate, consume the structured result rather than
|
|
210
|
+
parsing its message. The result exposes `.code`, `.expected`, `.hint`, and a
|
|
211
|
+
code-specific `.detail` containing the relevant entity, component, mesh,
|
|
212
|
+
material, submesh, lane, generation, or stage facts:
|
|
213
|
+
|
|
214
|
+
```ts
|
|
215
|
+
const result = admitPointsLines({ entity, points: {}, mesh: pointMesh, material });
|
|
216
|
+
if (!result.ok) {
|
|
217
|
+
console.error(result.error.code);
|
|
218
|
+
console.error(result.error.expected);
|
|
219
|
+
console.error(result.error.hint);
|
|
220
|
+
console.error(result.error.detail);
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
M1 intentionally refuses strip expansion, joins, caps, dashes, picking, and
|
|
225
|
+
visible point/line draw preparation. Those are later implementation lanes, not
|
|
226
|
+
implicit fallbacks in authoring code.
|
|
227
|
+
|
|
228
|
+
## Points and Lines runtime contract
|
|
229
|
+
|
|
230
|
+
The complete public closure is `MeshAsset` topology, one `Points` or `Lines`
|
|
231
|
+
component, `Materials.unlit`, and the Standard renderer. The owner retains the
|
|
232
|
+
source view, derives expanded geometry during prepare, and records the dedicated
|
|
233
|
+
points-lines pipeline in the active main geometry pass. Applications do not
|
|
234
|
+
create a second mesh, GPU buffer, shader module, cache, recovery ledger, or
|
|
235
|
+
backend branch.
|
|
236
|
+
|
|
237
|
+
| Surface | Supported contract | Refused or not claimed |
|
|
238
|
+
|:--|:--|:--|
|
|
239
|
+
| topology | indexed or non-indexed `point-list` and paired `line-list` | strips, triangles, mixed topology, and odd line tails |
|
|
240
|
+
| style | finite positive `Points.sizePx` and `Lines.widthPx`; circle or square points | negative, non-finite, or lane-conflicting values |
|
|
241
|
+
| material | engine-owned `Materials.unlit` forward material | standard/PBR, deferred, shadow-only, or custom runtime shader |
|
|
242
|
+
| capability lane | direct WebGPU runtime; clustered unlit preserves the same authoring contract | CPU and WebGL2 require their declared capability route; no pixel result is inferred from RhiNull |
|
|
243
|
+
| structural lane | RhiNull records retained projection, preparation, bindings, and draw shape | RhiNull is never hardware or pixel evidence |
|
|
244
|
+
|
|
245
|
+
Prepare and record remain one lifecycle. A failed result is an owner fact, not a
|
|
246
|
+
request to fall back to a generic mesh draw. Inspect the structured error and
|
|
247
|
+
repair the source or producer, then retry the same renderer:
|
|
248
|
+
|
|
249
|
+
```ts
|
|
250
|
+
const inspection = renderer.inspect();
|
|
251
|
+
const pointsLines = inspection.renderScene.pointsLines;
|
|
252
|
+
// Repair the named source or producer, then retry inspection and draw.
|
|
253
|
+
report(pointsLines);
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Inspection reports source bytes, derived bytes, vertex/index counts, cache
|
|
257
|
+
state, upload state, draw count, lane, and the retained `lastKnownGood` state.
|
|
258
|
+
Recovery is `inspect -> producer rebuild or cold-cook -> prepare -> record`.
|
|
259
|
+
It never publishes a partial expansion and never hides a stale-generation or
|
|
260
|
+
missing-resource error.
|
|
261
|
+
|
|
262
|
+
For visual evidence, use the topology probe and retain its raw screenshot,
|
|
263
|
+
readback, source/derived byte counts, draw count, and validation errors. A
|
|
264
|
+
focused direct-WebGPU probe is evidence for that lane only. The repository-wide
|
|
265
|
+
`pnpm test:browser` gate was explicitly skipped by human override in this
|
|
266
|
+
milestone and must not be reported as passed; the controlled Dawn attempt
|
|
267
|
+
timed out during environment build before Dawn Vitest ran.
|
|
268
|
+
|
|
269
|
+
The M5 boundary does not include strip joins, caps, dashes, picking, a new CLI
|
|
270
|
+
or RPC operation, application-local WGSL, a second Geometry factory, or a
|
|
271
|
+
separate cache/recovery authority.
|
|
272
|
+
|
|
134
273
|
> [!IMPORTANT]
|
|
135
274
|
> Owner: render vocabulary and the extract → prepare → record frame boundary. Runtime selects concrete services and calls this package; it does not re-own these tokens.
|
|
136
275
|
|