murow 0.1.1 → 0.1.3
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 +1 -1
- package/dist/cjs/core/clock/clock.js +1 -0
- package/dist/cjs/core/clock/index.js +1 -0
- package/dist/cjs/core/hitbox/hitbox-library.js +1 -0
- package/dist/cjs/core/hitbox/hitbox.js +1 -0
- package/dist/cjs/core/hitbox/index.js +1 -0
- package/dist/cjs/core/hitbox/test.js +1 -0
- package/dist/cjs/core/index.js +1 -1
- package/dist/cjs/core/prediction/prediction.js +1 -1
- package/dist/cjs/core/ray/ray-3d.js +1 -1
- package/dist/cjs/core/raycast/hit-buffer.js +1 -0
- package/dist/cjs/core/raycast/index.js +1 -0
- package/dist/cjs/core/raycast/raycaster.js +1 -0
- package/dist/cjs/core/slot-map/index.js +1 -0
- package/dist/cjs/core/slot-map/slot-map.js +1 -0
- package/dist/cjs/core/state-machine/index.js +1 -0
- package/dist/cjs/core/state-machine/state-machine.js +1 -0
- package/dist/cjs/core/timeline/index.js +1 -0
- package/dist/cjs/core/timeline/timeline.js +1 -0
- package/dist/cjs/game/loop/loop.js +1 -1
- package/dist/cjs/game/loop/ticker-schedule.js +1 -0
- package/dist/cjs/renderer/index.js +1 -1
- package/dist/cjs/renderer/prefab-bucket/concrete.js +1 -1
- package/dist/cjs/renderer/prefab-bucket/index.js +1 -1
- package/dist/cjs/renderer/prefab-bucket/parsers.js +1 -1
- package/dist/cjs/renderer/prefab-bucket/specs.js +1 -1
- package/dist/cjs/renderer/raycast/index.js +1 -0
- package/dist/cjs/renderer/raycast/raycast.js +1 -0
- package/dist/esm/core/clock/clock.js +1 -0
- package/dist/esm/core/clock/index.js +1 -0
- package/dist/esm/core/hitbox/hitbox-library.js +1 -0
- package/dist/esm/core/hitbox/hitbox.js +1 -0
- package/dist/esm/core/hitbox/index.js +1 -0
- package/dist/esm/core/hitbox/test.js +1 -0
- package/dist/esm/core/index.js +1 -1
- package/dist/esm/core/prediction/prediction.js +1 -1
- package/dist/esm/core/ray/ray-3d.js +1 -1
- package/dist/esm/core/raycast/hit-buffer.js +1 -0
- package/dist/esm/core/raycast/index.js +1 -0
- package/dist/esm/core/raycast/raycaster.js +1 -0
- package/dist/esm/core/slot-map/index.js +1 -0
- package/dist/esm/core/slot-map/slot-map.js +1 -0
- package/dist/esm/core/state-machine/index.js +1 -0
- package/dist/esm/core/state-machine/state-machine.js +1 -0
- package/dist/esm/core/timeline/index.js +1 -0
- package/dist/esm/core/timeline/timeline.js +1 -0
- package/dist/esm/game/loop/loop.js +1 -1
- package/dist/esm/game/loop/ticker-schedule.js +1 -0
- package/dist/esm/renderer/index.js +1 -1
- package/dist/esm/renderer/prefab-bucket/concrete.js +1 -1
- package/dist/esm/renderer/prefab-bucket/index.js +1 -1
- package/dist/esm/renderer/prefab-bucket/parsers.js +1 -1
- package/dist/esm/renderer/raycast/index.js +1 -0
- package/dist/esm/renderer/raycast/raycast.js +1 -0
- package/dist/netcode/cjs/index.js +144 -140
- package/dist/netcode/esm/index.js +144 -140
- package/dist/netcode/types/client/game-client.d.ts +17 -3
- package/dist/netcode/types/client/strategies/snapshot-interpolation.d.ts +33 -0
- package/dist/netcode/types/codec/delta-codec.d.ts +1 -1
- package/dist/netcode/types/components/sync-spec.d.ts +6 -0
- package/dist/types/core/clock/clock.d.ts +37 -0
- package/dist/types/core/clock/index.d.ts +1 -0
- package/dist/types/core/hitbox/hitbox-library.d.ts +29 -0
- package/dist/types/core/hitbox/hitbox.d.ts +50 -0
- package/dist/types/core/hitbox/index.d.ts +3 -0
- package/dist/types/core/hitbox/test.d.ts +44 -0
- package/dist/types/core/index.d.ts +6 -0
- package/dist/types/core/prediction/prediction.d.ts +35 -58
- package/dist/types/core/ray/ray-3d.d.ts +21 -1
- package/dist/types/core/raycast/hit-buffer.d.ts +43 -0
- package/dist/types/core/raycast/index.d.ts +2 -0
- package/dist/types/core/raycast/raycaster.d.ts +54 -0
- package/dist/types/core/slot-map/index.d.ts +1 -0
- package/dist/types/core/slot-map/slot-map.d.ts +109 -0
- package/dist/types/core/state-machine/index.d.ts +1 -0
- package/dist/types/core/state-machine/state-machine.d.ts +114 -0
- package/dist/types/core/timeline/index.d.ts +1 -0
- package/dist/types/core/timeline/timeline.d.ts +34 -0
- package/dist/types/game/loop/loop.d.ts +30 -0
- package/dist/types/game/loop/ticker-schedule.d.ts +52 -0
- package/dist/types/renderer/index.d.ts +1 -0
- package/dist/types/renderer/prefab-bucket/concrete.d.ts +16 -6
- package/dist/types/renderer/prefab-bucket/index.d.ts +11 -7
- package/dist/types/renderer/prefab-bucket/specs.d.ts +10 -0
- package/dist/types/renderer/raycast/index.d.ts +1 -0
- package/dist/types/renderer/raycast/raycast.d.ts +24 -0
- package/dist/types/renderer/types.d.ts +1 -0
- package/dist/webgpu/cjs/index.js +1777 -587
- package/dist/webgpu/esm/index.js +1769 -573
- package/dist/webgpu/types/2d/raycast.d.ts +45 -0
- package/dist/webgpu/types/2d/renderer.d.ts +11 -0
- package/dist/webgpu/types/2d/sprite-accessor.d.ts +3 -1
- package/dist/webgpu/types/3d/hitbox.d.ts +32 -0
- package/dist/webgpu/types/3d/lights.d.ts +113 -0
- package/dist/webgpu/types/3d/lights.test.d.ts +1 -0
- package/dist/webgpu/types/3d/raycast.d.ts +44 -0
- package/dist/webgpu/types/3d/renderer.d.ts +50 -1
- package/dist/webgpu/types/3d/shader.d.ts +88 -5
- package/dist/webgpu/types/core/types.d.ts +55 -0
- package/dist/webgpu/types/geometry/geometry-builder.d.ts +1 -4
- package/dist/webgpu/types/index.d.ts +1 -0
- package/dist/webgpu/types/shaders/utils.d.ts +24 -0
- package/package.json +1 -1
- package/dist/netcode/types/client/interpolation-buffer.d.ts +0 -37
- /package/dist/netcode/types/client/{interpolation-buffer.test.d.ts → strategies/snapshot-interpolation.test.d.ts} +0 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { InputSnapshot } from 'murow/core/input';
|
|
2
|
+
import { HitBuffer } from 'murow/core/raycast';
|
|
3
|
+
import { Raycast, RaycastMemo, type RaycastHit, type RaycastOptions } from 'murow/renderer';
|
|
4
|
+
import type { SpriteHandle } from 'murow/renderer';
|
|
5
|
+
import type { WebGPU2DRenderer } from './renderer';
|
|
6
|
+
type Point = [number, number];
|
|
7
|
+
type Hit = RaycastHit<SpriteHandle, Point>;
|
|
8
|
+
type Opts = RaycastOptions<SpriteHandle>;
|
|
9
|
+
export type RaycastState2D = HitBuffer<SpriteHandle, Point>;
|
|
10
|
+
export declare class WebGPURaycast2D extends Raycast<SpriteHandle, Point> {
|
|
11
|
+
private renderer;
|
|
12
|
+
readonly state: RaycastState2D;
|
|
13
|
+
private resultBuffer;
|
|
14
|
+
private memos;
|
|
15
|
+
constructor(renderer: WebGPU2DRenderer);
|
|
16
|
+
update(input: InputSnapshot): void;
|
|
17
|
+
/**
|
|
18
|
+
* Topmost sprite under the cursor, or null. The returned object is
|
|
19
|
+
* pool-backed and valid only until the next `update()` -- copy what
|
|
20
|
+
* you need, or use `memo` for results that persist across frames.
|
|
21
|
+
*/
|
|
22
|
+
hit(opts?: Opts): Hit | null;
|
|
23
|
+
/**
|
|
24
|
+
* Every sprite under the cursor, topmost first. The array and its
|
|
25
|
+
* entries are reused and overwritten by the next `update()`.
|
|
26
|
+
*/
|
|
27
|
+
hitAll(opts?: Opts): readonly Hit[];
|
|
28
|
+
memo(opts: Opts): WebGPURaycastMemo2D;
|
|
29
|
+
clearMemos(): void;
|
|
30
|
+
}
|
|
31
|
+
export declare class WebGPURaycastMemo2D extends RaycastMemo<SpriteHandle, Point> {
|
|
32
|
+
private state;
|
|
33
|
+
private opts;
|
|
34
|
+
private onDispose;
|
|
35
|
+
private dirty;
|
|
36
|
+
private detached;
|
|
37
|
+
private cached;
|
|
38
|
+
constructor(state: RaycastState2D, opts: Opts, onDispose: () => void);
|
|
39
|
+
get hits(): readonly Hit[];
|
|
40
|
+
get first(): Hit | null;
|
|
41
|
+
dispose(): void;
|
|
42
|
+
_invalidate(): void;
|
|
43
|
+
_detach(): void;
|
|
44
|
+
}
|
|
45
|
+
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Base2DRenderer } from 'murow/renderer';
|
|
2
2
|
import type { Renderer2DOptions, SpriteHandle, SpriteOptions, SpritesheetHandle, SpritesheetSource } from 'murow/renderer';
|
|
3
|
+
import { WebGPURaycast2D, type RaycastState2D } from './raycast';
|
|
3
4
|
import { Camera2D } from '../camera/camera-2d';
|
|
4
5
|
import { type ParsedSpritesheet } from 'murow/renderer';
|
|
5
6
|
import { GeometryBuilder, type GeometryOptions } from '../geometry/geometry-builder';
|
|
@@ -49,7 +50,11 @@ export declare class WebGPU2DRenderer extends Base2DRenderer {
|
|
|
49
50
|
private sheets;
|
|
50
51
|
private nextSheetId;
|
|
51
52
|
readonly camera: Camera2D;
|
|
53
|
+
readonly raycast: WebGPURaycast2D;
|
|
52
54
|
private uniformData;
|
|
55
|
+
private spriteHandles;
|
|
56
|
+
private spriteHitboxes;
|
|
57
|
+
private nextSpriteId;
|
|
53
58
|
private resizeObserver;
|
|
54
59
|
private resizeCallbacks;
|
|
55
60
|
private readonly _prefabs;
|
|
@@ -78,6 +83,12 @@ export declare class WebGPU2DRenderer extends Base2DRenderer {
|
|
|
78
83
|
sheet: SpritesheetHandle | Prefab2D;
|
|
79
84
|
}): SpriteHandle;
|
|
80
85
|
removeSprite(sprite: SpriteHandle): void;
|
|
86
|
+
/**
|
|
87
|
+
* Point-test every sprite against the unprojected cursor and push the
|
|
88
|
+
* hits into the buffer. Sort key is `-layer` so the topmost sprite is
|
|
89
|
+
* "nearest". A declared hitbox overrides the default rendered quad.
|
|
90
|
+
*/
|
|
91
|
+
_collectRaycastHitsInto(screenX: number, screenY: number, rc: RaycastState2D): void;
|
|
81
92
|
storePreviousState(): void;
|
|
82
93
|
createGeometry(name: string, options: GeometryOptions): GeometryBuilder;
|
|
83
94
|
createCompute(name: string, options: ComputeOptions): ComputeBuilder;
|
|
@@ -4,10 +4,12 @@ export declare class SpriteAccessor implements SpriteHandle {
|
|
|
4
4
|
private staticData;
|
|
5
5
|
private dynamicBase;
|
|
6
6
|
private staticBase;
|
|
7
|
+
private _id;
|
|
7
8
|
private _slot;
|
|
8
9
|
private _sheetId;
|
|
9
10
|
private _onStaticDirty;
|
|
10
|
-
constructor(dynamicData: Float32Array, staticData: Float32Array, slot: number, sheetId: number, onStaticDirty: () => void);
|
|
11
|
+
constructor(dynamicData: Float32Array, staticData: Float32Array, id: number, slot: number, sheetId: number, onStaticDirty: () => void);
|
|
12
|
+
get id(): number;
|
|
11
13
|
get slot(): number;
|
|
12
14
|
get sheetId(): number;
|
|
13
15
|
get x(): number;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type HitboxPart } from 'murow/core/hitbox';
|
|
2
|
+
/**
|
|
3
|
+
* Line-list wireframe renderer for instance hitboxes. Owns its pipeline,
|
|
4
|
+
* the three unit-shape vertex buffers, and a dynamic-offset uniform buffer
|
|
5
|
+
* (one MVP + color per entry). The caller walks instances and feeds each
|
|
6
|
+
* hitbox into `emit`; `flush` issues the per-entry draws.
|
|
7
|
+
*/
|
|
8
|
+
export declare class HitboxDebugRenderer {
|
|
9
|
+
private device;
|
|
10
|
+
private pipeline;
|
|
11
|
+
private bindGroup;
|
|
12
|
+
private uniformBuffer;
|
|
13
|
+
private sphereBuffer;
|
|
14
|
+
private sphereVertexCount;
|
|
15
|
+
private boxBuffer;
|
|
16
|
+
private boxVertexCount;
|
|
17
|
+
private cylinderBuffer;
|
|
18
|
+
private cylinderVertexCount;
|
|
19
|
+
private stage;
|
|
20
|
+
private entries;
|
|
21
|
+
private vp;
|
|
22
|
+
init(device: GPUDevice, format: GPUTextureFormat): void;
|
|
23
|
+
begin(vp: Float32Array): void;
|
|
24
|
+
emit(hb: HitboxPart<'3d'>, hovered: boolean, px: number, py: number, pz: number, sx: number, sy: number, sz: number): void;
|
|
25
|
+
flush(pass: GPURenderPassEncoder): void;
|
|
26
|
+
/**
|
|
27
|
+
* The model matrix is pure scale-then-translate, so `MVP = VP * M`
|
|
28
|
+
* collapses to scaling VP's first three columns by the extents and
|
|
29
|
+
* replacing the fourth with `VP * (center, 1)` -- no matrix multiply.
|
|
30
|
+
*/
|
|
31
|
+
private collect;
|
|
32
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A dynamic point or spot light. Directional/ambient terms are global and set
|
|
3
|
+
* via `setDirectionalLight` / `setAmbient`, not added here.
|
|
4
|
+
*/
|
|
5
|
+
export type LightSpec = {
|
|
6
|
+
type: 'point';
|
|
7
|
+
position: readonly [x: number, y: number, z: number];
|
|
8
|
+
/** Light color RGB. Defaults to `[1, 1, 1]`. */
|
|
9
|
+
color?: readonly [r: number, g: number, b: number];
|
|
10
|
+
/** Brightness multiplier. Defaults to `1`. */
|
|
11
|
+
intensity?: number;
|
|
12
|
+
/** World-unit radius past which the light contributes nothing. Defaults to `10`. */
|
|
13
|
+
range?: number;
|
|
14
|
+
} | {
|
|
15
|
+
type: 'spot';
|
|
16
|
+
position: readonly [x: number, y: number, z: number];
|
|
17
|
+
/** Direction the cone points along. */
|
|
18
|
+
direction: readonly [x: number, y: number, z: number];
|
|
19
|
+
color?: readonly [r: number, g: number, b: number];
|
|
20
|
+
intensity?: number;
|
|
21
|
+
range?: number;
|
|
22
|
+
/** Cone half-angle in radians (the outer edge). Defaults to `0.5`. */
|
|
23
|
+
angle?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Edge softness, 0..1. `0` = hard edge at `angle`; `1` = the cone fades
|
|
26
|
+
* all the way from its center. The feathered band is `angle * smoothness`
|
|
27
|
+
* wide, measured inward from the edge. Defaults to `0.5`.
|
|
28
|
+
*/
|
|
29
|
+
smoothness?: number;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Live handle to a dynamic light. All properties are readable and mutable every
|
|
33
|
+
* frame — unlike a mesh instance's spawn-frozen color. `destroy()` frees the slot.
|
|
34
|
+
*
|
|
35
|
+
* The `position` / `direction` / `color` getters return a per-handle reused
|
|
36
|
+
* tuple (mutated on each read), matching `MeshInstanceHandle`. Copy the values
|
|
37
|
+
* out if you need to retain them past the next read on the same handle.
|
|
38
|
+
*/
|
|
39
|
+
export interface LightHandle {
|
|
40
|
+
readonly slot: number;
|
|
41
|
+
setPosition(x: number, y: number, z: number): void;
|
|
42
|
+
setDirection(x: number, y: number, z: number): void;
|
|
43
|
+
/** Snap to a position without interpolating from the previous one (use after a discontinuous move). */
|
|
44
|
+
teleport(x: number, y: number, z: number): void;
|
|
45
|
+
setColor(r: number, g: number, b: number): void;
|
|
46
|
+
readonly position: readonly [number, number, number];
|
|
47
|
+
readonly direction: readonly [number, number, number];
|
|
48
|
+
readonly color: readonly [number, number, number];
|
|
49
|
+
intensity: number;
|
|
50
|
+
range: number;
|
|
51
|
+
/** Cone half-angle in radians (spot only; `0` for point lights). Readable + settable. */
|
|
52
|
+
angle: number;
|
|
53
|
+
/** Edge softness 0..1 (spot only). `0` = hard edge, `1` = fades from center. Readable + settable. */
|
|
54
|
+
smoothness: number;
|
|
55
|
+
/** Whether the light contributes this frame. Toggling does not free the slot. */
|
|
56
|
+
enabled: boolean;
|
|
57
|
+
destroy(): void;
|
|
58
|
+
}
|
|
59
|
+
export declare class LightSystem {
|
|
60
|
+
private readonly maxLights;
|
|
61
|
+
private readonly data;
|
|
62
|
+
private readonly slots;
|
|
63
|
+
private readonly enabled;
|
|
64
|
+
private readonly handles;
|
|
65
|
+
/** Dense scratch buffer of enabled lights, packed each frame for upload. */
|
|
66
|
+
private readonly uploadData;
|
|
67
|
+
/** CPU-side spot cone params per slot (the GPU only needs the derived cosines). */
|
|
68
|
+
private readonly angle;
|
|
69
|
+
private readonly smoothness;
|
|
70
|
+
private dirDir;
|
|
71
|
+
private dirColor;
|
|
72
|
+
private dirIntensity;
|
|
73
|
+
private ambient;
|
|
74
|
+
constructor(maxLights: number);
|
|
75
|
+
/** Add a dynamic point or spot light. Throws past `maxLights`. */
|
|
76
|
+
add(spec: LightSpec): LightHandle;
|
|
77
|
+
/**
|
|
78
|
+
* Set the global directional light (the "sun"). `direction` points from the
|
|
79
|
+
* surface toward the light. Defaults to `(0.3, 0.8, 0.5)`, white, intensity 1.
|
|
80
|
+
*/
|
|
81
|
+
setDirectional(direction: readonly [number, number, number], color?: readonly [number, number, number], intensity?: number): void;
|
|
82
|
+
/** Set the global ambient term. Defaults to `(0.3, 0.3, 0.3)`. */
|
|
83
|
+
setAmbient(color: readonly [number, number, number]): void;
|
|
84
|
+
/** Number of live dynamic lights. */
|
|
85
|
+
get count(): number;
|
|
86
|
+
/**
|
|
87
|
+
* Pack enabled lights into a dense run for upload. Disabled lights are
|
|
88
|
+
* skipped so the shader loop only walks contributing lights. Returns the
|
|
89
|
+
* shared scratch buffer, the light count, and the byte length to upload
|
|
90
|
+
* (so the caller never needs the record layout).
|
|
91
|
+
*/
|
|
92
|
+
pack(): {
|
|
93
|
+
data: Float32Array;
|
|
94
|
+
count: number;
|
|
95
|
+
byteLength: number;
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Stamp the directional + ambient terms and the light count into the
|
|
99
|
+
* renderer's uniform array, starting at `offset` (the float index after the
|
|
100
|
+
* VP matrix + alpha). Layout: lightDir(3), dirColor(3), dirIntensity(1),
|
|
101
|
+
* ambient(3), then lightCount as a u32 reinterpret at `offset + 10`.
|
|
102
|
+
*/
|
|
103
|
+
writeUniforms(uniformData: Float32Array, offset: number, count: number): void;
|
|
104
|
+
/**
|
|
105
|
+
* Snapshot every live light's current position/direction into its prev
|
|
106
|
+
* slot. Called from the renderer's `storePreviousState()` in `pre-tick`, so
|
|
107
|
+
* the shader can `mix(prev, curr, alpha)` and moving lights interpolate at
|
|
108
|
+
* render rate instead of snapping at the tick boundary.
|
|
109
|
+
*/
|
|
110
|
+
storePrevious(): void;
|
|
111
|
+
/** Write a light spec into its CPU slot. Prev is seeded to curr (no spawn lerp). */
|
|
112
|
+
private writeSlot;
|
|
113
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { InputSnapshot } from 'murow/core/input';
|
|
2
|
+
import { HitBuffer } from 'murow/core/raycast';
|
|
3
|
+
import { Raycast, RaycastMemo, type RaycastHit, type RaycastOptions } from 'murow/renderer';
|
|
4
|
+
import type { MeshInstanceHandle, WebGPU3DRenderer } from './renderer';
|
|
5
|
+
type Point = [number, number, number];
|
|
6
|
+
type Hit = RaycastHit<MeshInstanceHandle, Point>;
|
|
7
|
+
type Opts = RaycastOptions<MeshInstanceHandle>;
|
|
8
|
+
export type RaycastState = HitBuffer<MeshInstanceHandle, Point>;
|
|
9
|
+
export declare class WebGPURaycast3D extends Raycast<MeshInstanceHandle, Point> {
|
|
10
|
+
private renderer;
|
|
11
|
+
readonly state: RaycastState;
|
|
12
|
+
private resultBuffer;
|
|
13
|
+
private memos;
|
|
14
|
+
constructor(renderer: WebGPU3DRenderer);
|
|
15
|
+
update(input: InputSnapshot): void;
|
|
16
|
+
/**
|
|
17
|
+
* Nearest hit, or null. The returned object is pool-backed and valid
|
|
18
|
+
* only until the next `update()` -- copy what you need, or use `memo`
|
|
19
|
+
* for results that persist across frames.
|
|
20
|
+
*/
|
|
21
|
+
hit(opts?: Opts): Hit | null;
|
|
22
|
+
/**
|
|
23
|
+
* All hits, nearest first. The array and its entries are reused across
|
|
24
|
+
* calls and overwritten by the next `update()`; do not retain them.
|
|
25
|
+
*/
|
|
26
|
+
hitAll(opts?: Opts): readonly Hit[];
|
|
27
|
+
memo(opts: Opts): WebGPURaycastMemo3D;
|
|
28
|
+
clearMemos(): void;
|
|
29
|
+
}
|
|
30
|
+
export declare class WebGPURaycastMemo3D extends RaycastMemo<MeshInstanceHandle, Point> {
|
|
31
|
+
private state;
|
|
32
|
+
private opts;
|
|
33
|
+
private onDispose;
|
|
34
|
+
private dirty;
|
|
35
|
+
private detached;
|
|
36
|
+
private cached;
|
|
37
|
+
constructor(state: RaycastState, opts: Opts, onDispose: () => void);
|
|
38
|
+
get hits(): readonly Hit[];
|
|
39
|
+
get first(): Hit | null;
|
|
40
|
+
dispose(): void;
|
|
41
|
+
_invalidate(): void;
|
|
42
|
+
_detach(): void;
|
|
43
|
+
}
|
|
44
|
+
export {};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { Base3DRenderer } from 'murow/renderer';
|
|
2
2
|
import type { Renderer3DOptions } from 'murow/renderer';
|
|
3
3
|
import { ComputeBuilder, type ComputeOptions } from '../compute/compute-builder';
|
|
4
|
+
import { type LightSpec, type LightHandle } from './lights';
|
|
4
5
|
import { Camera3D } from '../camera/camera-3d';
|
|
5
|
-
import { type ParsedGltf, type PrefabBucket3D, type Prefab3D, type PlayOptions } from 'murow/renderer';
|
|
6
|
+
import { type ParsedGltf, type PrefabBucket3D, type Prefab3D, type PlayOptions, Raycast as RaycastBase, RaycastMemo as RaycastMemoBase, type RaycastHit as RaycastHitBase, type RaycastOptions as RaycastOptionsBase } from 'murow/renderer';
|
|
7
|
+
import { WebGPURaycast3D, type RaycastState } from './raycast';
|
|
6
8
|
export interface ModelData {
|
|
7
9
|
positions: Float32Array;
|
|
8
10
|
normals?: Float32Array;
|
|
@@ -17,6 +19,7 @@ export interface ModelHandle {
|
|
|
17
19
|
readonly skinned: boolean;
|
|
18
20
|
}
|
|
19
21
|
export interface MeshInstanceHandle {
|
|
22
|
+
readonly id: number;
|
|
20
23
|
readonly slot: number;
|
|
21
24
|
readonly modelId: number;
|
|
22
25
|
readonly skinned: boolean;
|
|
@@ -59,6 +62,7 @@ export interface GltfModel {
|
|
|
59
62
|
}
|
|
60
63
|
/** Handle to a spawned instance (single primitive or multi-part glTF). */
|
|
61
64
|
export interface InstanceHandle {
|
|
65
|
+
readonly id: number;
|
|
62
66
|
setPosition(x: number, y: number, z: number): void;
|
|
63
67
|
setRotation(x: number, y: number, z: number): void;
|
|
64
68
|
setScale(x: number, y: number, z: number): void;
|
|
@@ -103,6 +107,10 @@ export interface MeshInstanceOptions {
|
|
|
103
107
|
/** Tint color RGB. Defaults to `[1, 1, 1]`. */
|
|
104
108
|
color?: readonly [r: number, g: number, b: number];
|
|
105
109
|
}
|
|
110
|
+
export type RaycastHit = RaycastHitBase<MeshInstanceHandle, [number, number, number]>;
|
|
111
|
+
export type RaycastOptions = RaycastOptionsBase<MeshInstanceHandle>;
|
|
112
|
+
export type Raycast = RaycastBase<MeshInstanceHandle, [number, number, number]>;
|
|
113
|
+
export type RaycastMemo = RaycastMemoBase<MeshInstanceHandle, [number, number, number]>;
|
|
106
114
|
export interface WebGPU3DRendererOptions extends Renderer3DOptions {
|
|
107
115
|
maxSkinnedInstances?: number;
|
|
108
116
|
maxBonesPerSkin?: number;
|
|
@@ -140,6 +148,8 @@ export declare class WebGPU3DRenderer extends Base3DRenderer {
|
|
|
140
148
|
private batcher;
|
|
141
149
|
private staticDirty;
|
|
142
150
|
private instanceModelIds;
|
|
151
|
+
private instanceHandles;
|
|
152
|
+
private nextInstanceId;
|
|
143
153
|
private dynamicBuffer;
|
|
144
154
|
private staticBuffer;
|
|
145
155
|
private uniformBuffer;
|
|
@@ -184,6 +194,7 @@ export declare class WebGPU3DRenderer extends Base3DRenderer {
|
|
|
184
194
|
private skinnedInstanceModelIds;
|
|
185
195
|
private skinnedInstanceBoneOffsets;
|
|
186
196
|
private skinnedAnimStates;
|
|
197
|
+
private skinnedInstanceHandles;
|
|
187
198
|
private nextBoneOffset;
|
|
188
199
|
/** Reusable bone-offset blocks per skinIndex. Pushed on remove, popped on add. Indexed by skinIndex (low cardinality), so a Map of lists is fine. */
|
|
189
200
|
private freedBoneOffsets;
|
|
@@ -199,10 +210,18 @@ export declare class WebGPU3DRenderer extends Base3DRenderer {
|
|
|
199
210
|
private rawSkinnedUniformBuffer;
|
|
200
211
|
private rawSkinnedSlotIndexBuffer;
|
|
201
212
|
private frustumPlanes;
|
|
213
|
+
private lights;
|
|
214
|
+
private lightBuffer;
|
|
215
|
+
private rawLightBuffer;
|
|
202
216
|
readonly camera: Camera3D;
|
|
217
|
+
readonly raycast: WebGPURaycast3D;
|
|
203
218
|
private uniformData;
|
|
204
219
|
private lastRenderTime;
|
|
205
220
|
private readonly _prefabs;
|
|
221
|
+
debug: {
|
|
222
|
+
hitboxes: boolean;
|
|
223
|
+
};
|
|
224
|
+
private hitboxDebug;
|
|
206
225
|
constructor(canvas: HTMLCanvasElement, options: WebGPU3DRendererOptions);
|
|
207
226
|
init(): Promise<void>;
|
|
208
227
|
/**
|
|
@@ -243,6 +262,25 @@ export declare class WebGPU3DRenderer extends Base3DRenderer {
|
|
|
243
262
|
* separate set of GPU buffers. Read-only.
|
|
244
263
|
*/
|
|
245
264
|
get maxSkinned(): number;
|
|
265
|
+
/**
|
|
266
|
+
* Add a dynamic point or spot light. Returns a live handle whose position,
|
|
267
|
+
* color, intensity, range, and enabled state can all be changed every frame.
|
|
268
|
+
* Up to `MAX_LIGHTS` (64) lights may be live at once; throws past that.
|
|
269
|
+
*
|
|
270
|
+
* The global directional + ambient terms are separate — see
|
|
271
|
+
* `setDirectionalLight` / `setAmbient`.
|
|
272
|
+
*/
|
|
273
|
+
addLight(spec: LightSpec): LightHandle;
|
|
274
|
+
/**
|
|
275
|
+
* Set the global directional light (the "sun"). `direction` points from the
|
|
276
|
+
* surface toward the light. Defaults to `(0.3, 0.8, 0.5)`, white, intensity 1
|
|
277
|
+
* — the engine's classic fixed look.
|
|
278
|
+
*/
|
|
279
|
+
setDirectionalLight(direction: readonly [number, number, number], color?: readonly [number, number, number], intensity?: number): void;
|
|
280
|
+
/** Set the global ambient term. Defaults to `(0.3, 0.3, 0.3)`. */
|
|
281
|
+
setAmbient(color: readonly [number, number, number]): void;
|
|
282
|
+
/** Number of live dynamic lights. */
|
|
283
|
+
get lightCount(): number;
|
|
246
284
|
/**
|
|
247
285
|
* Create a flat grid mesh on the XZ plane at Y=0.
|
|
248
286
|
*
|
|
@@ -357,7 +395,18 @@ export declare class WebGPU3DRenderer extends Base3DRenderer {
|
|
|
357
395
|
*/
|
|
358
396
|
removeInstance(handle: InstanceHandle): void;
|
|
359
397
|
storePreviousState(): void;
|
|
398
|
+
/** Resolve an instance's declared hitbox name to its Hitbox via the bucket's library. */
|
|
399
|
+
private resolveHitbox;
|
|
400
|
+
/**
|
|
401
|
+
* Pick test for a single instance. Returns the ray-`t` and the struck
|
|
402
|
+
* part name, or `null`. Uses the prefab's declared hitbox when
|
|
403
|
+
* available; falls back to the model's axis-aligned bounding box.
|
|
404
|
+
*/
|
|
405
|
+
private testInstanceRay;
|
|
406
|
+
/** Push every instance the screen ray hits within [near, far] into the hit buffer. Unsorted. */
|
|
407
|
+
_collectRaycastHitsInto(screenX: number, screenY: number, rc: RaycastState): void;
|
|
360
408
|
render(alpha: number): void;
|
|
409
|
+
private drawDebugHitboxes;
|
|
361
410
|
/**
|
|
362
411
|
* Extract 6 frustum planes from a column-major VP matrix.
|
|
363
412
|
* Each plane is [a, b, c, d] where ax + by + cz + d >= 0 means inside.
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import * as d from 'typegpu/data';
|
|
2
|
+
/** Max point/spot lights the mesh shaders' storage buffer holds. */
|
|
3
|
+
export declare const MAX_LIGHTS = 64;
|
|
2
4
|
export declare function createMeshLayout(maxInstances: number): import("typegpu").TgpuBindGroupLayout<{
|
|
3
5
|
uniforms: {
|
|
4
6
|
uniform: d.WgslStruct<{
|
|
@@ -7,6 +9,14 @@ export declare function createMeshLayout(maxInstances: number): import("typegpu"
|
|
|
7
9
|
lightDirX: d.F32;
|
|
8
10
|
lightDirY: d.F32;
|
|
9
11
|
lightDirZ: d.F32;
|
|
12
|
+
lightDirR: d.F32;
|
|
13
|
+
lightDirG: d.F32;
|
|
14
|
+
lightDirB: d.F32;
|
|
15
|
+
lightDirIntensity: d.F32;
|
|
16
|
+
ambientR: d.F32;
|
|
17
|
+
ambientG: d.F32;
|
|
18
|
+
ambientB: d.F32;
|
|
19
|
+
lightCount: d.U32;
|
|
10
20
|
}>;
|
|
11
21
|
};
|
|
12
22
|
dynamicInstances: {
|
|
@@ -38,6 +48,32 @@ export declare function createMeshLayout(maxInstances: number): import("typegpu"
|
|
|
38
48
|
slotIndices: {
|
|
39
49
|
storage: d.WgslArray<d.U32>;
|
|
40
50
|
};
|
|
51
|
+
lights: {
|
|
52
|
+
storage: d.WgslArray<d.WgslStruct<{
|
|
53
|
+
kind: d.F32;
|
|
54
|
+
currPosX: d.F32;
|
|
55
|
+
currPosY: d.F32;
|
|
56
|
+
currPosZ: d.F32;
|
|
57
|
+
prevPosX: d.F32;
|
|
58
|
+
prevPosY: d.F32;
|
|
59
|
+
prevPosZ: d.F32;
|
|
60
|
+
currDirX: d.F32;
|
|
61
|
+
currDirY: d.F32;
|
|
62
|
+
currDirZ: d.F32;
|
|
63
|
+
prevDirX: d.F32;
|
|
64
|
+
prevDirY: d.F32;
|
|
65
|
+
prevDirZ: d.F32;
|
|
66
|
+
colorR: d.F32;
|
|
67
|
+
colorG: d.F32;
|
|
68
|
+
colorB: d.F32;
|
|
69
|
+
intensity: d.F32;
|
|
70
|
+
range: d.F32;
|
|
71
|
+
innerCos: d.F32;
|
|
72
|
+
outerCos: d.F32;
|
|
73
|
+
castsShadow: d.F32;
|
|
74
|
+
shadowMapIndex: d.F32;
|
|
75
|
+
}>>;
|
|
76
|
+
};
|
|
41
77
|
}>;
|
|
42
78
|
export type MeshDataLayout = ReturnType<typeof createMeshLayout>;
|
|
43
79
|
export declare function createMeshVertex(meshLayout: MeshDataLayout): import("typegpu").TgpuVertexFn<{
|
|
@@ -46,10 +82,12 @@ export declare function createMeshVertex(meshLayout: MeshDataLayout): import("ty
|
|
|
46
82
|
}, {
|
|
47
83
|
vNormal: d.Vec3f;
|
|
48
84
|
vColor: d.Vec3f;
|
|
85
|
+
vWorldPos: d.Vec3f;
|
|
49
86
|
}>;
|
|
50
|
-
export declare function createMeshFragment(meshLayout: MeshDataLayout): import("typegpu").TgpuFragmentFn<{
|
|
87
|
+
export declare function createMeshFragment(meshLayout: MeshDataLayout | SkinnedMeshDataLayout): import("typegpu").TgpuFragmentFn<{
|
|
51
88
|
vNormal: d.Vec3f;
|
|
52
89
|
vColor: d.Vec3f;
|
|
90
|
+
vWorldPos: d.Vec3f;
|
|
53
91
|
}, d.Vec4f>;
|
|
54
92
|
export declare function createTextureBindGroupLayout(): import("typegpu").TgpuBindGroupLayout<{
|
|
55
93
|
modelTexture: import("typegpu").TgpuLayoutTexture<d.WgslTexture2d<d.F32>>;
|
|
@@ -66,11 +104,13 @@ export declare function createTexturedMeshVertex(meshLayout: MeshDataLayout): im
|
|
|
66
104
|
vNormal: d.Vec3f;
|
|
67
105
|
vColor: d.Vec3f;
|
|
68
106
|
vUV: d.Vec2f;
|
|
107
|
+
vWorldPos: d.Vec3f;
|
|
69
108
|
}>;
|
|
70
|
-
export declare function createTexturedMeshFragment(meshLayout: MeshDataLayout, texLayout: TextureBindGroupLayout): import("typegpu").TgpuFragmentFn<{
|
|
109
|
+
export declare function createTexturedMeshFragment(meshLayout: MeshDataLayout | SkinnedMeshDataLayout, texLayout: TextureBindGroupLayout): import("typegpu").TgpuFragmentFn<{
|
|
71
110
|
vNormal: d.Vec3f;
|
|
72
111
|
vColor: d.Vec3f;
|
|
73
112
|
vUV: d.Vec2f;
|
|
113
|
+
vWorldPos: d.Vec3f;
|
|
74
114
|
}, d.Vec4f>;
|
|
75
115
|
export declare function createSkinnedMeshLayout(maxInstances: number, maxBones: number): import("typegpu").TgpuBindGroupLayout<{
|
|
76
116
|
uniforms: {
|
|
@@ -80,6 +120,14 @@ export declare function createSkinnedMeshLayout(maxInstances: number, maxBones:
|
|
|
80
120
|
lightDirX: d.F32;
|
|
81
121
|
lightDirY: d.F32;
|
|
82
122
|
lightDirZ: d.F32;
|
|
123
|
+
lightDirR: d.F32;
|
|
124
|
+
lightDirG: d.F32;
|
|
125
|
+
lightDirB: d.F32;
|
|
126
|
+
lightDirIntensity: d.F32;
|
|
127
|
+
ambientR: d.F32;
|
|
128
|
+
ambientG: d.F32;
|
|
129
|
+
ambientB: d.F32;
|
|
130
|
+
lightCount: d.U32;
|
|
83
131
|
}>;
|
|
84
132
|
};
|
|
85
133
|
dynamicInstances: {
|
|
@@ -115,6 +163,32 @@ export declare function createSkinnedMeshLayout(maxInstances: number, maxBones:
|
|
|
115
163
|
boneMatrices: {
|
|
116
164
|
storage: d.WgslArray<d.Mat4x4f>;
|
|
117
165
|
};
|
|
166
|
+
lights: {
|
|
167
|
+
storage: d.WgslArray<d.WgslStruct<{
|
|
168
|
+
kind: d.F32;
|
|
169
|
+
currPosX: d.F32;
|
|
170
|
+
currPosY: d.F32;
|
|
171
|
+
currPosZ: d.F32;
|
|
172
|
+
prevPosX: d.F32;
|
|
173
|
+
prevPosY: d.F32;
|
|
174
|
+
prevPosZ: d.F32;
|
|
175
|
+
currDirX: d.F32;
|
|
176
|
+
currDirY: d.F32;
|
|
177
|
+
currDirZ: d.F32;
|
|
178
|
+
prevDirX: d.F32;
|
|
179
|
+
prevDirY: d.F32;
|
|
180
|
+
prevDirZ: d.F32;
|
|
181
|
+
colorR: d.F32;
|
|
182
|
+
colorG: d.F32;
|
|
183
|
+
colorB: d.F32;
|
|
184
|
+
intensity: d.F32;
|
|
185
|
+
range: d.F32;
|
|
186
|
+
innerCos: d.F32;
|
|
187
|
+
outerCos: d.F32;
|
|
188
|
+
castsShadow: d.F32;
|
|
189
|
+
shadowMapIndex: d.F32;
|
|
190
|
+
}>>;
|
|
191
|
+
};
|
|
118
192
|
}>;
|
|
119
193
|
export type SkinnedMeshDataLayout = ReturnType<typeof createSkinnedMeshLayout>;
|
|
120
194
|
export declare function createSkinnedMeshVertex(layout: SkinnedMeshDataLayout): import("typegpu").TgpuVertexFn<{
|
|
@@ -127,10 +201,19 @@ export declare function createSkinnedMeshVertex(layout: SkinnedMeshDataLayout):
|
|
|
127
201
|
vNormal: d.Vec3f;
|
|
128
202
|
vColor: d.Vec3f;
|
|
129
203
|
vUV: d.Vec2f;
|
|
204
|
+
vWorldPos: d.Vec3f;
|
|
130
205
|
}>;
|
|
131
206
|
/**
|
|
132
|
-
* Fragment shader for skinned meshes
|
|
133
|
-
*
|
|
207
|
+
* Fragment shader for untextured skinned meshes. The skinned vertex shader
|
|
208
|
+
* always emits `vUV` (location 2) because it is shared with the textured path,
|
|
209
|
+
* so this fragment must declare `vUV` in its `in` too, otherwise `vWorldPos`
|
|
210
|
+
* lands on location 2 and collides with the vertex's `vUV` (vec2 vs vec3). The
|
|
211
|
+
* UV is simply unused here. Lighting matches createMeshFragment.
|
|
134
212
|
*/
|
|
135
|
-
export
|
|
213
|
+
export declare function createSkinnedMeshFragment(meshLayout: SkinnedMeshDataLayout): import("typegpu").TgpuFragmentFn<{
|
|
214
|
+
vNormal: d.Vec3f;
|
|
215
|
+
vColor: d.Vec3f;
|
|
216
|
+
vUV: d.Vec2f;
|
|
217
|
+
vWorldPos: d.Vec3f;
|
|
218
|
+
}, d.Vec4f>;
|
|
136
219
|
export { createTexturedMeshFragment as createSkinnedTexturedMeshFragment };
|
|
@@ -104,7 +104,62 @@ export declare const MeshUniforms: d.WgslStruct<{
|
|
|
104
104
|
lightDirX: d.F32;
|
|
105
105
|
lightDirY: d.F32;
|
|
106
106
|
lightDirZ: d.F32;
|
|
107
|
+
lightDirR: d.F32;
|
|
108
|
+
lightDirG: d.F32;
|
|
109
|
+
lightDirB: d.F32;
|
|
110
|
+
lightDirIntensity: d.F32;
|
|
111
|
+
ambientR: d.F32;
|
|
112
|
+
ambientG: d.F32;
|
|
113
|
+
ambientB: d.F32;
|
|
114
|
+
lightCount: d.U32;
|
|
107
115
|
}>;
|
|
116
|
+
/** viewProjection occupies floats [0, 16). */
|
|
117
|
+
export declare const MESH_UNIFORM_ALPHA_OFFSET = 16;
|
|
118
|
+
/** The directional/ambient/count block starts right after `alpha`. */
|
|
119
|
+
export declare const MESH_UNIFORM_LIGHT_OFFSET = 17;
|
|
120
|
+
/** Total f32 slots in MeshUniforms (mat4x4 16 + alpha 1 + 10 light terms + count 1). */
|
|
121
|
+
export declare const MESH_UNIFORM_FLOATS = 28;
|
|
122
|
+
/**
|
|
123
|
+
* Point/spot light record. One entry per slot in the renderer's light storage
|
|
124
|
+
* buffer; the fragment shader loops `[0, lightCount)`. Kept f32-contiguous (no
|
|
125
|
+
* vec types) to match the flat Float32Array the renderer uploads.
|
|
126
|
+
*
|
|
127
|
+
* Position and direction carry `prev` + `curr` snapshots so the fragment shader
|
|
128
|
+
* can `mix(prev, curr, alpha)`, moving lights interpolate at render rate, the
|
|
129
|
+
* same as mesh instances, instead of snapping at the tick boundary.
|
|
130
|
+
*
|
|
131
|
+
* `kind`: 1 = point, 2 = spot (0/directional is the global term in MeshUniforms).
|
|
132
|
+
* `castsShadow` / `shadowMapIndex` are reserved for shadow-map support: the
|
|
133
|
+
* fragment loop already multiplies each light by a shadow factor (currently
|
|
134
|
+
* 1.0), so a shadow pass can populate these without reshaping the buffer.
|
|
135
|
+
*/
|
|
136
|
+
export declare const Light: d.WgslStruct<{
|
|
137
|
+
kind: d.F32;
|
|
138
|
+
currPosX: d.F32;
|
|
139
|
+
currPosY: d.F32;
|
|
140
|
+
currPosZ: d.F32;
|
|
141
|
+
prevPosX: d.F32;
|
|
142
|
+
prevPosY: d.F32;
|
|
143
|
+
prevPosZ: d.F32;
|
|
144
|
+
currDirX: d.F32;
|
|
145
|
+
currDirY: d.F32;
|
|
146
|
+
currDirZ: d.F32;
|
|
147
|
+
prevDirX: d.F32;
|
|
148
|
+
prevDirY: d.F32;
|
|
149
|
+
prevDirZ: d.F32;
|
|
150
|
+
colorR: d.F32;
|
|
151
|
+
colorG: d.F32;
|
|
152
|
+
colorB: d.F32;
|
|
153
|
+
intensity: d.F32;
|
|
154
|
+
range: d.F32;
|
|
155
|
+
innerCos: d.F32;
|
|
156
|
+
outerCos: d.F32;
|
|
157
|
+
castsShadow: d.F32;
|
|
158
|
+
shadowMapIndex: d.F32;
|
|
159
|
+
}>;
|
|
160
|
+
export declare const LIGHT_FLOATS = 22;
|
|
161
|
+
export declare const LIGHT_KIND_POINT = 1;
|
|
162
|
+
export declare const LIGHT_KIND_SPOT = 2;
|
|
108
163
|
/** Per-instance animation state, uploaded from CPU each frame. */
|
|
109
164
|
export declare const InstanceAnimStateGPU: d.WgslStruct<{
|
|
110
165
|
clipId: d.I32;
|
|
@@ -40,7 +40,7 @@ export declare class CustomGeometry<TDynamic extends Record<string, AnyWgslData>
|
|
|
40
40
|
readonly maxInstances: number;
|
|
41
41
|
readonly geometryData: GeometryData;
|
|
42
42
|
private root;
|
|
43
|
-
private
|
|
43
|
+
private slots;
|
|
44
44
|
private layoutConfig;
|
|
45
45
|
private dynamicFieldNames;
|
|
46
46
|
private staticFieldNames;
|
|
@@ -54,9 +54,6 @@ export declare class CustomGeometry<TDynamic extends Record<string, AnyWgslData>
|
|
|
54
54
|
private _uniformDirty;
|
|
55
55
|
private _isComputeSourced;
|
|
56
56
|
private _drawCount;
|
|
57
|
-
private activeSlots;
|
|
58
|
-
private activeCount;
|
|
59
|
-
private slotToActive;
|
|
60
57
|
private _ctx;
|
|
61
58
|
private dynamicBuffer;
|
|
62
59
|
private staticBuffer;
|
|
@@ -17,6 +17,7 @@ export { AnimationController } from './2d/animation';
|
|
|
17
17
|
export type { AnimationClip, AnimationState, AnimationClipConfig } from './2d/animation';
|
|
18
18
|
export { WebGPU3DRenderer } from './3d/renderer';
|
|
19
19
|
export type { ModelData, ModelHandle, GltfModel, InstanceHandle, MeshInstanceHandle, MeshInstanceOptions, } from './3d/renderer';
|
|
20
|
+
export type { LightSpec, LightHandle } from './3d/lights';
|
|
20
21
|
export { MorphAnimation } from './3d/morph-animation';
|
|
21
22
|
export type { MorphClip, MorphState, MorphClipConfig } from './3d/morph-animation';
|
|
22
23
|
export { Camera2D } from './camera/camera-2d';
|
|
@@ -26,3 +26,27 @@ export declare const scaleRotate2d: import("typegpu").TgpuFn<(scale: d.Vec2f, an
|
|
|
26
26
|
* Inverse lerp — given a value in [min, max], returns its t in [0, 1].
|
|
27
27
|
*/
|
|
28
28
|
export declare const inverseLerp: import("typegpu").TgpuFn<(min: d.F32, max: d.F32, value: d.F32) => d.F32>;
|
|
29
|
+
/**
|
|
30
|
+
* Diffuse contribution of one point/spot light at a surface point. Returns the
|
|
31
|
+
* light's color scaled by Lambert term, distance attenuation, spot cone, and a
|
|
32
|
+
* shadow factor. The shadow factor is currently fixed at 1.0; a shadow-map pass
|
|
33
|
+
* replaces it by sampling the light's shadow map without changing this loop.
|
|
34
|
+
*
|
|
35
|
+
* Takes the light's fields as vectors (rather than the `Light` struct) so the
|
|
36
|
+
* signature is portable across the mesh and skinned fragment shaders, which
|
|
37
|
+
* each read the struct from their own bind-group storage buffer:
|
|
38
|
+
* `pos` light position (point/spot)
|
|
39
|
+
* `axis` spot direction (unused for point lights)
|
|
40
|
+
* `color` light rgb
|
|
41
|
+
* `params` (intensity, range, innerCos, outerCos); a point light passes
|
|
42
|
+
* innerCos = 1, outerCos = -1 so the cone term is always 1.
|
|
43
|
+
* `normal` surface normal (world space, normalized)
|
|
44
|
+
* `worldPos` surface position (world space)
|
|
45
|
+
*/
|
|
46
|
+
export declare const lightContribution: import("typegpu").TgpuFn<(pos: d.Vec3f, axis: d.Vec3f, color: d.Vec3f, params: d.Vec4f, normal: d.Vec3f, worldPos: d.Vec3f) => d.Vec3f>;
|
|
47
|
+
/**
|
|
48
|
+
* Reinhard tone map: rolls accumulated light smoothly toward white instead of
|
|
49
|
+
* hard-clipping at 1.0. Without it, summed lights flat-top to white and any
|
|
50
|
+
* gradient (e.g. a feathered spot edge) collapses into a thin visible ring.
|
|
51
|
+
*/
|
|
52
|
+
export declare const tonemap: import("typegpu").TgpuFn<(c: d.Vec3f) => d.Vec3f>;
|