gaesup-world 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/gi/components/GiVolume/index.d.cts +4 -2
- package/dist/core/gi/components/GiVolume/index.d.ts +4 -2
- package/dist/core/gi/components/GiVolume/runtime.d.cts +6 -1
- package/dist/core/gi/components/GiVolume/runtime.d.ts +6 -1
- package/dist/core/gi/components/GiVolume/types.d.cts +8 -2
- package/dist/core/gi/components/GiVolume/types.d.ts +8 -2
- package/dist/core/gi/components/GiVolume/workerClient.d.cts +31 -0
- package/dist/core/gi/components/GiVolume/workerClient.d.ts +31 -0
- package/dist/core/gi/core/probeAtlas.d.cts +28 -0
- package/dist/core/gi/core/probeAtlas.d.ts +28 -0
- package/dist/core/gi/core/probeCascade.d.cts +6 -0
- package/dist/core/gi/core/probeCascade.d.ts +6 -0
- package/dist/core/gi/core/probeSchedule.d.cts +14 -0
- package/dist/core/gi/core/probeSchedule.d.ts +14 -0
- package/dist/core/gi/core/probeVolume.d.cts +4 -0
- package/dist/core/gi/core/probeVolume.d.ts +4 -0
- package/dist/core/gi/hooks/useBuildingVoxelBoxes.d.cts +4 -0
- package/dist/core/gi/hooks/useBuildingVoxelBoxes.d.ts +4 -0
- package/dist/core/gi/index.d.cts +1 -1
- package/dist/core/gi/index.d.ts +1 -1
- package/dist/core/gi/types.d.cts +5 -0
- package/dist/core/gi/types.d.ts +5 -0
- package/dist/core/gi/utils/buildingVoxelBoxes.d.cts +4 -2
- package/dist/core/gi/utils/buildingVoxelBoxes.d.ts +4 -2
- package/dist/core/gi/utils/modelBounds.d.cts +40 -0
- package/dist/core/gi/utils/modelBounds.d.ts +40 -0
- package/dist/core/gi/utils/objectProxies.d.cts +8 -0
- package/dist/core/gi/utils/objectProxies.d.ts +8 -0
- package/dist/core/gi/worker/giWorker.d.cts +1 -0
- package/dist/core/gi/worker/giWorker.d.ts +1 -0
- package/dist/core/gi/worker/host.d.cts +33 -0
- package/dist/core/gi/worker/host.d.ts +33 -0
- package/dist/core/gi/worker/protocol.d.cts +38 -0
- package/dist/core/gi/worker/protocol.d.ts +38 -0
- package/dist/core/rendering/tsl/gi.d.cts +1 -0
- package/dist/core/rendering/tsl/gi.d.ts +1 -0
- package/dist/core/rendering/tsl/types.d.cts +6 -1
- package/dist/core/rendering/tsl/types.d.ts +6 -1
- package/dist/gi-BXxzSzsV.js +95 -0
- package/dist/gi-DhHrlQsb.cjs +1 -0
- package/dist/index.cjs +2 -2
- package/dist/index.js +1631 -1156
- package/dist/probeAtlas-B9u5Z8MN.js +51 -0
- package/dist/probeAtlas-CfwUzN9s.cjs +1 -0
- package/package.json +3 -3
- package/dist/gi-CrIKhZ7T.cjs +0 -1
- package/dist/gi-D2-0A-M9.js +0 -78
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { GiVolumeProps } from './types.cjs';
|
|
2
2
|
/**
|
|
3
3
|
* 복셀 박스를 추적해 프로브 래디언스 캐시를 갱신하고 GPU 텍스처로 올린다.
|
|
4
|
-
* 프로브
|
|
4
|
+
* 프로브 추적은 기본으로 Web Worker에서 돌아 프레임이 기다리지 않는다. 워커를 쓸 수 없거나 멈추면 메인 스레드에서
|
|
5
|
+
* 같은 계산을 한다. 두 경우 모두 wasm/gaesup_gi.wasm을 받을 수 있으면 WASM 커널, 없으면 같은 결과의 JS로 갱신한다.
|
|
6
|
+
* 수렴한 캐시는 갱신 속도를 4분의 1로 낮추고(probeSchedule.ts), 장면이나 빛이 바뀌면 다시 올린다.
|
|
5
7
|
* WebGPURenderer에서만 셰이더 모듈이 로드되며, 로드에 실패하면 children은 GI 없이 그대로 렌더링된다.
|
|
6
8
|
* children은 useGi()로 받은 값의 applyToMaterial로 MeshStandardNodeMaterial에 간접광을 연결한다.
|
|
7
9
|
*/
|
|
8
|
-
export declare function GiVolume({ boxes, environment, fineBounds, voxelSize, probeSpacing, raysPerProbe, probesPerFrame, padding, blend, uploadIntervalMs, children, }: GiVolumeProps): import("react").JSX.Element;
|
|
10
|
+
export declare function GiVolume({ boxes, environment, fineBounds, voxelSize, probeSpacing, raysPerProbe, probesPerFrame, padding, blend, uploadIntervalMs, worker, children, }: GiVolumeProps): import("react").JSX.Element;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { GiVolumeProps } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* 복셀 박스를 추적해 프로브 래디언스 캐시를 갱신하고 GPU 텍스처로 올린다.
|
|
4
|
-
* 프로브
|
|
4
|
+
* 프로브 추적은 기본으로 Web Worker에서 돌아 프레임이 기다리지 않는다. 워커를 쓸 수 없거나 멈추면 메인 스레드에서
|
|
5
|
+
* 같은 계산을 한다. 두 경우 모두 wasm/gaesup_gi.wasm을 받을 수 있으면 WASM 커널, 없으면 같은 결과의 JS로 갱신한다.
|
|
6
|
+
* 수렴한 캐시는 갱신 속도를 4분의 1로 낮추고(probeSchedule.ts), 장면이나 빛이 바뀌면 다시 올린다.
|
|
5
7
|
* WebGPURenderer에서만 셰이더 모듈이 로드되며, 로드에 실패하면 children은 GI 없이 그대로 렌더링된다.
|
|
6
8
|
* children은 useGi()로 받은 값의 applyToMaterial로 MeshStandardNodeMaterial에 간접광을 연결한다.
|
|
7
9
|
*/
|
|
8
|
-
export declare function GiVolume({ boxes, environment, fineBounds, voxelSize, probeSpacing, raysPerProbe, probesPerFrame, padding, blend, uploadIntervalMs, children, }: GiVolumeProps): import("react").JSX.Element;
|
|
10
|
+
export declare function GiVolume({ boxes, environment, fineBounds, voxelSize, probeSpacing, raysPerProbe, probesPerFrame, padding, blend, uploadIntervalMs, worker, children, }: GiVolumeProps): import("react").JSX.Element;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { GiRuntime, GiRuntimeParams } from './types.cjs';
|
|
2
|
-
import type { Aabb, GiEnvironment, VoxelSourceBox } from '../../types.cjs';
|
|
2
|
+
import type { Aabb, GiEnvironment, ProbeAtlasUpload, VoxelSourceBox } from '../../types.cjs';
|
|
3
3
|
export declare function boundsKey(bounds: Aabb | null): string;
|
|
4
4
|
/**
|
|
5
5
|
* 박스 목록으로 GI 런타임을 만든다. 그리드 명세와 프로브 배치가 이전과 같으면 그리드만 다시 채우고
|
|
@@ -12,3 +12,8 @@ export declare function createGiRuntime(previous: GiRuntime | null, boxes: reado
|
|
|
12
12
|
* 아무것도 하지 않으며 캐스케이드는 JS 경로로 계속 갱신된다.
|
|
13
13
|
*/
|
|
14
14
|
export declare function attachGiWasm(runtime: GiRuntime, module: WebAssembly.Module): Promise<boolean>;
|
|
15
|
+
/**
|
|
16
|
+
* Packs every level of the runtime's cascade into half-float atlases for GiIrradiance.updateAtlas, reusing arrays the
|
|
17
|
+
* renderer handed back (hand them back through `spareAtlases`).
|
|
18
|
+
*/
|
|
19
|
+
export declare function packRuntimeAtlases(runtime: GiRuntime): ProbeAtlasUpload[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { GiRuntime, GiRuntimeParams } from './types.js';
|
|
2
|
-
import type { Aabb, GiEnvironment, VoxelSourceBox } from '../../types.js';
|
|
2
|
+
import type { Aabb, GiEnvironment, ProbeAtlasUpload, VoxelSourceBox } from '../../types.js';
|
|
3
3
|
export declare function boundsKey(bounds: Aabb | null): string;
|
|
4
4
|
/**
|
|
5
5
|
* 박스 목록으로 GI 런타임을 만든다. 그리드 명세와 프로브 배치가 이전과 같으면 그리드만 다시 채우고
|
|
@@ -12,3 +12,8 @@ export declare function createGiRuntime(previous: GiRuntime | null, boxes: reado
|
|
|
12
12
|
* 아무것도 하지 않으며 캐스케이드는 JS 경로로 계속 갱신된다.
|
|
13
13
|
*/
|
|
14
14
|
export declare function attachGiWasm(runtime: GiRuntime, module: WebAssembly.Module): Promise<boolean>;
|
|
15
|
+
/**
|
|
16
|
+
* Packs every level of the runtime's cascade into half-float atlases for GiIrradiance.updateAtlas, reusing arrays the
|
|
17
|
+
* renderer handed back (hand them back through `spareAtlases`).
|
|
18
|
+
*/
|
|
19
|
+
export declare function packRuntimeAtlases(runtime: GiRuntime): ProbeAtlasUpload[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
import type { ProbeCascade } from '../../core/probeCascade.cjs';
|
|
3
|
-
import type { Aabb, GiEnvironment,
|
|
3
|
+
import type { Aabb, GiEnvironment, VoxelGrid, VoxelSourceBox } from '../../types.cjs';
|
|
4
4
|
export type GiVolumeProps = {
|
|
5
5
|
boxes: readonly VoxelSourceBox[];
|
|
6
6
|
environment: GiEnvironment;
|
|
@@ -12,6 +12,11 @@ export type GiVolumeProps = {
|
|
|
12
12
|
padding?: number;
|
|
13
13
|
blend?: number;
|
|
14
14
|
uploadIntervalMs?: number;
|
|
15
|
+
/**
|
|
16
|
+
* Trace probes in a Web Worker so the frame never waits for them (default). Where a worker cannot start (no Worker,
|
|
17
|
+
* a content security policy without blob: workers) or it fails, the probes update on the main thread as before.
|
|
18
|
+
*/
|
|
19
|
+
worker?: boolean;
|
|
15
20
|
children?: ReactNode;
|
|
16
21
|
};
|
|
17
22
|
export type GiRuntimeParams = {
|
|
@@ -26,6 +31,7 @@ export type GiRuntime = {
|
|
|
26
31
|
signature: string;
|
|
27
32
|
grid: VoxelGrid;
|
|
28
33
|
cascade: ProbeCascade;
|
|
29
|
-
|
|
34
|
+
/** Atlas arrays the renderer has let go of, packed again for the next upload. */
|
|
35
|
+
spareAtlases: Uint16Array[];
|
|
30
36
|
uploadedVersion: number;
|
|
31
37
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
import type { ProbeCascade } from '../../core/probeCascade.js';
|
|
3
|
-
import type { Aabb, GiEnvironment,
|
|
3
|
+
import type { Aabb, GiEnvironment, VoxelGrid, VoxelSourceBox } from '../../types.js';
|
|
4
4
|
export type GiVolumeProps = {
|
|
5
5
|
boxes: readonly VoxelSourceBox[];
|
|
6
6
|
environment: GiEnvironment;
|
|
@@ -12,6 +12,11 @@ export type GiVolumeProps = {
|
|
|
12
12
|
padding?: number;
|
|
13
13
|
blend?: number;
|
|
14
14
|
uploadIntervalMs?: number;
|
|
15
|
+
/**
|
|
16
|
+
* Trace probes in a Web Worker so the frame never waits for them (default). Where a worker cannot start (no Worker,
|
|
17
|
+
* a content security policy without blob: workers) or it fails, the probes update on the main thread as before.
|
|
18
|
+
*/
|
|
19
|
+
worker?: boolean;
|
|
15
20
|
children?: ReactNode;
|
|
16
21
|
};
|
|
17
22
|
export type GiRuntimeParams = {
|
|
@@ -26,6 +31,7 @@ export type GiRuntime = {
|
|
|
26
31
|
signature: string;
|
|
27
32
|
grid: VoxelGrid;
|
|
28
33
|
cascade: ProbeCascade;
|
|
29
|
-
|
|
34
|
+
/** Atlas arrays the renderer has let go of, packed again for the next upload. */
|
|
35
|
+
spareAtlases: Uint16Array[];
|
|
30
36
|
uploadedVersion: number;
|
|
31
37
|
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { GiRuntimeParams } from './types.cjs';
|
|
2
|
+
import type { GiEnvironment, ProbeAtlasUpload, VoxelSourceBox } from '../../types.cjs';
|
|
3
|
+
type Handlers = {
|
|
4
|
+
onAtlas: (levels: ProbeAtlasUpload[], usesWasm: boolean) => void;
|
|
5
|
+
onError: (error: unknown) => void;
|
|
6
|
+
};
|
|
7
|
+
/** Whether this page can run the GI worker at all (browsers; not SSR or plain test environments). */
|
|
8
|
+
export declare function canUseGiWorker(): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* The page's side of the GI worker: forwards the voxel scene and the light, hands packed atlases to `onAtlas` and
|
|
11
|
+
* reports a worker that could not start or stopped. Construction throws when the worker cannot be created (for
|
|
12
|
+
* example a content security policy without blob: workers); callers then keep the main-thread path.
|
|
13
|
+
*/
|
|
14
|
+
export declare class GiWorkerClient {
|
|
15
|
+
private readonly worker;
|
|
16
|
+
private closed;
|
|
17
|
+
constructor(module: WebAssembly.Module | null, options: {
|
|
18
|
+
probesPerTick: number;
|
|
19
|
+
uploadIntervalMs: number;
|
|
20
|
+
}, handlers: Handlers);
|
|
21
|
+
setScene(boxes: readonly VoxelSourceBox[], params: GiRuntimeParams, environment: GiEnvironment): void;
|
|
22
|
+
setEnvironment(environment: GiEnvironment): void;
|
|
23
|
+
/** Stops tracing while nothing is drawn (a hidden page) and picks it up again. */
|
|
24
|
+
setPaused(paused: boolean): void;
|
|
25
|
+
/** Hands arrays the renderer stopped using back to the worker, which packs later uploads into them. */
|
|
26
|
+
recycle(atlases: Uint16Array[]): void;
|
|
27
|
+
dispose(): void;
|
|
28
|
+
private send;
|
|
29
|
+
private fail;
|
|
30
|
+
}
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { GiRuntimeParams } from './types.js';
|
|
2
|
+
import type { GiEnvironment, ProbeAtlasUpload, VoxelSourceBox } from '../../types.js';
|
|
3
|
+
type Handlers = {
|
|
4
|
+
onAtlas: (levels: ProbeAtlasUpload[], usesWasm: boolean) => void;
|
|
5
|
+
onError: (error: unknown) => void;
|
|
6
|
+
};
|
|
7
|
+
/** Whether this page can run the GI worker at all (browsers; not SSR or plain test environments). */
|
|
8
|
+
export declare function canUseGiWorker(): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* The page's side of the GI worker: forwards the voxel scene and the light, hands packed atlases to `onAtlas` and
|
|
11
|
+
* reports a worker that could not start or stopped. Construction throws when the worker cannot be created (for
|
|
12
|
+
* example a content security policy without blob: workers); callers then keep the main-thread path.
|
|
13
|
+
*/
|
|
14
|
+
export declare class GiWorkerClient {
|
|
15
|
+
private readonly worker;
|
|
16
|
+
private closed;
|
|
17
|
+
constructor(module: WebAssembly.Module | null, options: {
|
|
18
|
+
probesPerTick: number;
|
|
19
|
+
uploadIntervalMs: number;
|
|
20
|
+
}, handlers: Handlers);
|
|
21
|
+
setScene(boxes: readonly VoxelSourceBox[], params: GiRuntimeParams, environment: GiEnvironment): void;
|
|
22
|
+
setEnvironment(environment: GiEnvironment): void;
|
|
23
|
+
/** Stops tracing while nothing is drawn (a hidden page) and picks it up again. */
|
|
24
|
+
setPaused(paused: boolean): void;
|
|
25
|
+
/** Hands arrays the renderer stopped using back to the worker, which packs later uploads into them. */
|
|
26
|
+
recycle(atlases: Uint16Array[]): void;
|
|
27
|
+
dispose(): void;
|
|
28
|
+
private send;
|
|
29
|
+
private fail;
|
|
30
|
+
}
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ProbeFaceBuffers, VoxelDims } from '../types.cjs';
|
|
2
|
+
/** Faces of an irradiance cube in atlas order: +x -x +y -y +z -z, laid side by side along the atlas x axis. */
|
|
3
|
+
export declare const PROBE_ATLAS_FACES = 6;
|
|
4
|
+
/** Channels per atlas texel (RGBA; alpha is always 1). */
|
|
5
|
+
export declare const PROBE_ATLAS_CHANNELS = 4;
|
|
6
|
+
/** Length of one level's atlas: every probe's six faces, four half floats each. */
|
|
7
|
+
export declare function probeAtlasLength(counts: VoxelDims): number;
|
|
8
|
+
/**
|
|
9
|
+
* Where probe `index`'s texel of `face` starts in the atlas. A probe row (fixed y and z) holds the six faces one after
|
|
10
|
+
* another, each `counts[0]` texels wide, so hardware filtering inside a face never reads its neighbour.
|
|
11
|
+
*/
|
|
12
|
+
export declare function probeAtlasOffset(counts: VoxelDims, index: number, face: number): number;
|
|
13
|
+
/** The half-float bits of alpha 1, written into every texel. */
|
|
14
|
+
export declare const PROBE_ATLAS_ALPHA = 15360;
|
|
15
|
+
/**
|
|
16
|
+
* IEEE 754 half-float bits of `value`, rounded to nearest even. Irradiance is never negative or huge, but the
|
|
17
|
+
* conversion stays total: NaN becomes 0 and anything past the half range the largest finite half.
|
|
18
|
+
*/
|
|
19
|
+
export declare function toHalfFloat(value: number): number;
|
|
20
|
+
/** Writes a level's six per-face RGBA float buffers (ProbeVolume.exportFaceData) into its half-float atlas. */
|
|
21
|
+
export declare function writeFaceBuffersToAtlas(target: Uint16Array, counts: VoxelDims, faces: ProbeFaceBuffers): void;
|
|
22
|
+
/**
|
|
23
|
+
* Writes every probe's irradiance cube (`cubeOf(index)`: six faces of RGB, ProbeVolume's layout) into a level's
|
|
24
|
+
* half-float atlas in one pass.
|
|
25
|
+
*/
|
|
26
|
+
export declare function packProbeAtlas(target: Uint16Array, counts: VoxelDims, cubeOf: (index: number) => ArrayLike<number>): void;
|
|
27
|
+
/** An atlas array of `length` from `pool` (removed from it), or a new one; callers hand spent arrays back to the pool. */
|
|
28
|
+
export declare function takeProbeAtlas(pool: Uint16Array[], length: number): Uint16Array;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ProbeFaceBuffers, VoxelDims } from '../types.js';
|
|
2
|
+
/** Faces of an irradiance cube in atlas order: +x -x +y -y +z -z, laid side by side along the atlas x axis. */
|
|
3
|
+
export declare const PROBE_ATLAS_FACES = 6;
|
|
4
|
+
/** Channels per atlas texel (RGBA; alpha is always 1). */
|
|
5
|
+
export declare const PROBE_ATLAS_CHANNELS = 4;
|
|
6
|
+
/** Length of one level's atlas: every probe's six faces, four half floats each. */
|
|
7
|
+
export declare function probeAtlasLength(counts: VoxelDims): number;
|
|
8
|
+
/**
|
|
9
|
+
* Where probe `index`'s texel of `face` starts in the atlas. A probe row (fixed y and z) holds the six faces one after
|
|
10
|
+
* another, each `counts[0]` texels wide, so hardware filtering inside a face never reads its neighbour.
|
|
11
|
+
*/
|
|
12
|
+
export declare function probeAtlasOffset(counts: VoxelDims, index: number, face: number): number;
|
|
13
|
+
/** The half-float bits of alpha 1, written into every texel. */
|
|
14
|
+
export declare const PROBE_ATLAS_ALPHA = 15360;
|
|
15
|
+
/**
|
|
16
|
+
* IEEE 754 half-float bits of `value`, rounded to nearest even. Irradiance is never negative or huge, but the
|
|
17
|
+
* conversion stays total: NaN becomes 0 and anything past the half range the largest finite half.
|
|
18
|
+
*/
|
|
19
|
+
export declare function toHalfFloat(value: number): number;
|
|
20
|
+
/** Writes a level's six per-face RGBA float buffers (ProbeVolume.exportFaceData) into its half-float atlas. */
|
|
21
|
+
export declare function writeFaceBuffersToAtlas(target: Uint16Array, counts: VoxelDims, faces: ProbeFaceBuffers): void;
|
|
22
|
+
/**
|
|
23
|
+
* Writes every probe's irradiance cube (`cubeOf(index)`: six faces of RGB, ProbeVolume's layout) into a level's
|
|
24
|
+
* half-float atlas in one pass.
|
|
25
|
+
*/
|
|
26
|
+
export declare function packProbeAtlas(target: Uint16Array, counts: VoxelDims, cubeOf: (index: number) => ArrayLike<number>): void;
|
|
27
|
+
/** An atlas array of `length` from `pool` (removed from it), or a new one; callers hand spent arrays back to the pool. */
|
|
28
|
+
export declare function takeProbeAtlas(pool: Uint16Array[], length: number): Uint16Array;
|
|
@@ -15,10 +15,16 @@ export declare class ProbeCascade {
|
|
|
15
15
|
private readonly grid;
|
|
16
16
|
private environment;
|
|
17
17
|
private kernel;
|
|
18
|
+
private updatedSinceChange;
|
|
18
19
|
constructor(grid: VoxelGrid, coarseConfig: ProbeVolumeConfig, fineConfig: ProbeVolumeConfig | null, environment: GiEnvironment);
|
|
19
20
|
get probeCount(): number;
|
|
20
21
|
get version(): number;
|
|
21
22
|
get usesWasm(): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* 복셀이나 빛이 마지막으로 바뀐 뒤 모든 프로브를 몇 번 돌았는지(갱신한 프로브 수 / 전체 수). 호출자는 이 값으로
|
|
25
|
+
* 수렴한 캐시의 갱신 속도를 낮춘다(probeSchedule.ts).
|
|
26
|
+
*/
|
|
27
|
+
get passesSinceChange(): number;
|
|
22
28
|
/**
|
|
23
29
|
* 두 레벨의 프로브 갱신을 WASM 커널로 옮긴다. 현재 프로브 값은 WASM 메모리로 복사되어 이어진다.
|
|
24
30
|
* 복셀 격자는 markAllDirty와 markDirtyBox, 환경은 setEnvironment에서 WASM 쪽으로 다시 복사된다.
|
|
@@ -15,10 +15,16 @@ export declare class ProbeCascade {
|
|
|
15
15
|
private readonly grid;
|
|
16
16
|
private environment;
|
|
17
17
|
private kernel;
|
|
18
|
+
private updatedSinceChange;
|
|
18
19
|
constructor(grid: VoxelGrid, coarseConfig: ProbeVolumeConfig, fineConfig: ProbeVolumeConfig | null, environment: GiEnvironment);
|
|
19
20
|
get probeCount(): number;
|
|
20
21
|
get version(): number;
|
|
21
22
|
get usesWasm(): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* 복셀이나 빛이 마지막으로 바뀐 뒤 모든 프로브를 몇 번 돌았는지(갱신한 프로브 수 / 전체 수). 호출자는 이 값으로
|
|
25
|
+
* 수렴한 캐시의 갱신 속도를 낮춘다(probeSchedule.ts).
|
|
26
|
+
*/
|
|
27
|
+
get passesSinceChange(): number;
|
|
22
28
|
/**
|
|
23
29
|
* 두 레벨의 프로브 갱신을 WASM 커널로 옮긴다. 현재 프로브 값은 WASM 메모리로 복사되어 이어진다.
|
|
24
30
|
* 복셀 격자는 markAllDirty와 markDirtyBox, 환경은 setEnvironment에서 WASM 쪽으로 다시 복사된다.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Passes over every probe, after the voxels or the light changed, that run at the full rate. The running average moves
|
|
3
|
+
* 10% of the way per update at the default blend, so twelve passes leave under a third of the old light's noise; the
|
|
4
|
+
* adaptive blend already follows large changes within a pass or two.
|
|
5
|
+
*/
|
|
6
|
+
export declare const SETTLE_PASSES = 12;
|
|
7
|
+
/** A settled cache keeps a quarter of the rate: enough to follow small changes, without a steady share of a core. */
|
|
8
|
+
export declare const SETTLED_RATE_DIVISOR = 4;
|
|
9
|
+
/**
|
|
10
|
+
* Probes to update in one frame (or one worker tick) `passes` passes after the cascade's last change: `perFrame` times
|
|
11
|
+
* `firstPass` until every probe has been traced once, so new light shows up quickly, `perFrame` while the cache
|
|
12
|
+
* converges, then a quarter of it.
|
|
13
|
+
*/
|
|
14
|
+
export declare function scheduledProbeBudget(perFrame: number, passes: number, firstPass?: number): number;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Passes over every probe, after the voxels or the light changed, that run at the full rate. The running average moves
|
|
3
|
+
* 10% of the way per update at the default blend, so twelve passes leave under a third of the old light's noise; the
|
|
4
|
+
* adaptive blend already follows large changes within a pass or two.
|
|
5
|
+
*/
|
|
6
|
+
export declare const SETTLE_PASSES = 12;
|
|
7
|
+
/** A settled cache keeps a quarter of the rate: enough to follow small changes, without a steady share of a core. */
|
|
8
|
+
export declare const SETTLED_RATE_DIVISOR = 4;
|
|
9
|
+
/**
|
|
10
|
+
* Probes to update in one frame (or one worker tick) `passes` passes after the cascade's last change: `perFrame` times
|
|
11
|
+
* `firstPass` until every probe has been traced once, so new light shows up quickly, `perFrame` while the cache
|
|
12
|
+
* converges, then a quarter of it.
|
|
13
|
+
*/
|
|
14
|
+
export declare function scheduledProbeBudget(perFrame: number, passes: number, firstPass?: number): number;
|
|
@@ -63,6 +63,10 @@ export declare class ProbeVolume {
|
|
|
63
63
|
* 복셀 안에 묻힌 프로브는 이웃 유효 프로브 평균으로 채워 하드웨어 보간 시 어둡게 번지지 않게 한다.
|
|
64
64
|
*/
|
|
65
65
|
exportFaceData(target?: ProbeFaceBuffers): ProbeFaceBuffers;
|
|
66
|
+
/** exportFaceData와 같은 값을 반정밀도 아틀라스(probeAtlas.ts)에 면별 float 버퍼 없이 바로 쓴다. */
|
|
67
|
+
packAtlas(target: Uint16Array): void;
|
|
68
|
+
/** 프로브의 조도 큐브(복셀 안에 묻힌 프로브는 이웃 평균). 다음 호출이 덮어쓰는 내부 버퍼다. */
|
|
69
|
+
private probeCube;
|
|
66
70
|
private loadProbe;
|
|
67
71
|
private loadDilated;
|
|
68
72
|
private nextProbe;
|
|
@@ -63,6 +63,10 @@ export declare class ProbeVolume {
|
|
|
63
63
|
* 복셀 안에 묻힌 프로브는 이웃 유효 프로브 평균으로 채워 하드웨어 보간 시 어둡게 번지지 않게 한다.
|
|
64
64
|
*/
|
|
65
65
|
exportFaceData(target?: ProbeFaceBuffers): ProbeFaceBuffers;
|
|
66
|
+
/** exportFaceData와 같은 값을 반정밀도 아틀라스(probeAtlas.ts)에 면별 float 버퍼 없이 바로 쓴다. */
|
|
67
|
+
packAtlas(target: Uint16Array): void;
|
|
68
|
+
/** 프로브의 조도 큐브(복셀 안에 묻힌 프로브는 이웃 평균). 다음 호출이 덮어쓰는 내부 버퍼다. */
|
|
69
|
+
private probeCube;
|
|
66
70
|
private loadProbe;
|
|
67
71
|
private loadDilated;
|
|
68
72
|
private nextProbe;
|
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
import type { VoxelSourceBox } from '../types.cjs';
|
|
2
|
+
/**
|
|
3
|
+
* The building store as GI voxel boxes: tiles, walls, blocks and fires, plus stand-ins for trees and placed models
|
|
4
|
+
* once their files' bounds are known.
|
|
5
|
+
*/
|
|
2
6
|
export declare function useBuildingVoxelBoxes(): VoxelSourceBox[];
|
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
import type { VoxelSourceBox } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* The building store as GI voxel boxes: tiles, walls, blocks and fires, plus stand-ins for trees and placed models
|
|
4
|
+
* once their files' bounds are known.
|
|
5
|
+
*/
|
|
2
6
|
export declare function useBuildingVoxelBoxes(): VoxelSourceBox[];
|
package/dist/core/gi/index.d.cts
CHANGED
|
@@ -16,4 +16,4 @@ export { CUBE_CHANNELS, CUBE_FACE_COUNT, CUBE_STRIDE, accumulateAmbientCube, eva
|
|
|
16
16
|
export { createVoxelHitScratch, traceVoxelRay, traceVoxelRayInto } from './core/traceVoxels.cjs';
|
|
17
17
|
export { DEFAULT_MATERIAL_ID, MAX_MATERIAL_ID, clearVoxelGrid, createVoxelGrid, fillVoxelBox, isInsideVoxelGrid, isVoxelOccupied, registerVoxelMaterial, resetVoxelMaterials, voxelIndex, voxelMaterialId, } from './core/voxelGrid.cjs';
|
|
18
18
|
export { alignedProbeLayout, computeBoxBounds, computeGridSpec, createGridForBounds, expandBounds, rebuildVoxelGrid, } from './core/voxelScene.cjs';
|
|
19
|
-
export type { Aabb, FieldSampler, GiEnvironment, GiWasmExports, Mat3, MutableRgb, ProbeFaceBuffers, ProbeLevelUpload, ProbeVolumeConfig, Rgb, VoxelDims, VoxelGrid, VoxelHitScratch, VoxelMaterial, VoxelRayHit, VoxelSourceBox, } from './types.cjs';
|
|
19
|
+
export type { Aabb, FieldSampler, GiEnvironment, GiWasmExports, Mat3, MutableRgb, ProbeAtlasUpload, ProbeFaceBuffers, ProbeLevelUpload, ProbeVolumeConfig, Rgb, VoxelDims, VoxelGrid, VoxelHitScratch, VoxelMaterial, VoxelRayHit, VoxelSourceBox, } from './types.cjs';
|
package/dist/core/gi/index.d.ts
CHANGED
|
@@ -16,4 +16,4 @@ export { CUBE_CHANNELS, CUBE_FACE_COUNT, CUBE_STRIDE, accumulateAmbientCube, eva
|
|
|
16
16
|
export { createVoxelHitScratch, traceVoxelRay, traceVoxelRayInto } from './core/traceVoxels.js';
|
|
17
17
|
export { DEFAULT_MATERIAL_ID, MAX_MATERIAL_ID, clearVoxelGrid, createVoxelGrid, fillVoxelBox, isInsideVoxelGrid, isVoxelOccupied, registerVoxelMaterial, resetVoxelMaterials, voxelIndex, voxelMaterialId, } from './core/voxelGrid.js';
|
|
18
18
|
export { alignedProbeLayout, computeBoxBounds, computeGridSpec, createGridForBounds, expandBounds, rebuildVoxelGrid, } from './core/voxelScene.js';
|
|
19
|
-
export type { Aabb, FieldSampler, GiEnvironment, GiWasmExports, Mat3, MutableRgb, ProbeFaceBuffers, ProbeLevelUpload, ProbeVolumeConfig, Rgb, VoxelDims, VoxelGrid, VoxelHitScratch, VoxelMaterial, VoxelRayHit, VoxelSourceBox, } from './types.js';
|
|
19
|
+
export type { Aabb, FieldSampler, GiEnvironment, GiWasmExports, Mat3, MutableRgb, ProbeAtlasUpload, ProbeFaceBuffers, ProbeLevelUpload, ProbeVolumeConfig, Rgb, VoxelDims, VoxelGrid, VoxelHitScratch, VoxelMaterial, VoxelRayHit, VoxelSourceBox, } from './types.js';
|
package/dist/core/gi/types.d.cts
CHANGED
|
@@ -65,6 +65,11 @@ export type ProbeLevelUpload = {
|
|
|
65
65
|
config: ProbeVolumeConfig;
|
|
66
66
|
faces: ProbeFaceBuffers;
|
|
67
67
|
};
|
|
68
|
+
/** One level as its half-float atlas: six faces side by side along x, RGBA per probe (see ProbeVolume.packAtlas). */
|
|
69
|
+
export type ProbeAtlasUpload = {
|
|
70
|
+
config: ProbeVolumeConfig;
|
|
71
|
+
atlas: Uint16Array;
|
|
72
|
+
};
|
|
68
73
|
export type GiWasmExports = {
|
|
69
74
|
readonly memory: WebAssembly.Memory;
|
|
70
75
|
readonly alloc_f32: (len: number) => number;
|
package/dist/core/gi/types.d.ts
CHANGED
|
@@ -65,6 +65,11 @@ export type ProbeLevelUpload = {
|
|
|
65
65
|
config: ProbeVolumeConfig;
|
|
66
66
|
faces: ProbeFaceBuffers;
|
|
67
67
|
};
|
|
68
|
+
/** One level as its half-float atlas: six faces side by side along x, RGBA per probe (see ProbeVolume.packAtlas). */
|
|
69
|
+
export type ProbeAtlasUpload = {
|
|
70
|
+
config: ProbeVolumeConfig;
|
|
71
|
+
atlas: Uint16Array;
|
|
72
|
+
};
|
|
68
73
|
export type GiWasmExports = {
|
|
69
74
|
readonly memory: WebAssembly.Memory;
|
|
70
75
|
readonly alloc_f32: (len: number) => number;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { BuildingWallKind } from '../../building/types/index.cjs';
|
|
2
|
-
import type { VoxelSourceBox } from '../types.cjs';
|
|
2
|
+
import type { Aabb, VoxelSourceBox } from '../types.cjs';
|
|
3
3
|
import type { BuildingVoxelSource, WallPiece } from './types.cjs';
|
|
4
4
|
export declare function wallPieces(kind: BuildingWallKind, width: number, height: number, depth: number): WallPiece[];
|
|
5
5
|
/**
|
|
6
6
|
* 건축 스토어의 타일, 블록, 벽, 불 오브젝트를 GI용 복셀 박스로 변환한다.
|
|
7
7
|
* 문·창 벽은 개구부를 남기고 유리와 난간은 빛이 통과하도록 생략한다.
|
|
8
|
+
* `modelBounds`(모델 URL별 경계 상자)를 주면 나무·가구·바위 같은 배치 오브젝트도 대리 박스로 넣어 빛을 가리게 하고,
|
|
9
|
+
* 조명의 머리는 발광체로 넣는다(objectProxies.ts).
|
|
8
10
|
*/
|
|
9
|
-
export declare function buildingToVoxelBoxes(source: BuildingVoxelSource): VoxelSourceBox[];
|
|
11
|
+
export declare function buildingToVoxelBoxes(source: BuildingVoxelSource, modelBounds?: ReadonlyMap<string, Aabb | null>): VoxelSourceBox[];
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { BuildingWallKind } from '../../building/types/index.js';
|
|
2
|
-
import type { VoxelSourceBox } from '../types.js';
|
|
2
|
+
import type { Aabb, VoxelSourceBox } from '../types.js';
|
|
3
3
|
import type { BuildingVoxelSource, WallPiece } from './types.js';
|
|
4
4
|
export declare function wallPieces(kind: BuildingWallKind, width: number, height: number, depth: number): WallPiece[];
|
|
5
5
|
/**
|
|
6
6
|
* 건축 스토어의 타일, 블록, 벽, 불 오브젝트를 GI용 복셀 박스로 변환한다.
|
|
7
7
|
* 문·창 벽은 개구부를 남기고 유리와 난간은 빛이 통과하도록 생략한다.
|
|
8
|
+
* `modelBounds`(모델 URL별 경계 상자)를 주면 나무·가구·바위 같은 배치 오브젝트도 대리 박스로 넣어 빛을 가리게 하고,
|
|
9
|
+
* 조명의 머리는 발광체로 넣는다(objectProxies.ts).
|
|
8
10
|
*/
|
|
9
|
-
export declare function buildingToVoxelBoxes(source: BuildingVoxelSource): VoxelSourceBox[];
|
|
11
|
+
export declare function buildingToVoxelBoxes(source: BuildingVoxelSource, modelBounds?: ReadonlyMap<string, Aabb | null>): VoxelSourceBox[];
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Aabb } from '../types.cjs';
|
|
2
|
+
type GltfAccessor = {
|
|
3
|
+
min?: number[];
|
|
4
|
+
max?: number[];
|
|
5
|
+
normalized?: boolean;
|
|
6
|
+
componentType?: number;
|
|
7
|
+
};
|
|
8
|
+
type GltfNode = {
|
|
9
|
+
children?: number[];
|
|
10
|
+
mesh?: number;
|
|
11
|
+
matrix?: number[];
|
|
12
|
+
translation?: number[];
|
|
13
|
+
rotation?: number[];
|
|
14
|
+
scale?: number[];
|
|
15
|
+
};
|
|
16
|
+
type GltfJson = {
|
|
17
|
+
scene?: number;
|
|
18
|
+
scenes?: {
|
|
19
|
+
nodes?: number[];
|
|
20
|
+
}[];
|
|
21
|
+
nodes?: GltfNode[];
|
|
22
|
+
meshes?: {
|
|
23
|
+
primitives?: {
|
|
24
|
+
attributes?: {
|
|
25
|
+
POSITION?: number;
|
|
26
|
+
};
|
|
27
|
+
}[];
|
|
28
|
+
}[];
|
|
29
|
+
accessors?: GltfAccessor[];
|
|
30
|
+
};
|
|
31
|
+
/** Local bounding box of a glTF's default scene from the accessors' min/max; no geometry is decoded. */
|
|
32
|
+
export declare function gltfBounds(json: GltfJson): Aabb | null;
|
|
33
|
+
/** The same box for a binary glTF, read from its JSON chunk alone. */
|
|
34
|
+
export declare function glbBounds(buffer: ArrayBuffer): Aabb | null;
|
|
35
|
+
/**
|
|
36
|
+
* A model's local bounds, fetched once per URL (resolved like the engine's glTF loader, so the HTTP cache usually
|
|
37
|
+
* answers). null when the file cannot be read; GI then leaves that model out.
|
|
38
|
+
*/
|
|
39
|
+
export declare function loadModelBounds(uri: string): Promise<Aabb | null>;
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Aabb } from '../types.js';
|
|
2
|
+
type GltfAccessor = {
|
|
3
|
+
min?: number[];
|
|
4
|
+
max?: number[];
|
|
5
|
+
normalized?: boolean;
|
|
6
|
+
componentType?: number;
|
|
7
|
+
};
|
|
8
|
+
type GltfNode = {
|
|
9
|
+
children?: number[];
|
|
10
|
+
mesh?: number;
|
|
11
|
+
matrix?: number[];
|
|
12
|
+
translation?: number[];
|
|
13
|
+
rotation?: number[];
|
|
14
|
+
scale?: number[];
|
|
15
|
+
};
|
|
16
|
+
type GltfJson = {
|
|
17
|
+
scene?: number;
|
|
18
|
+
scenes?: {
|
|
19
|
+
nodes?: number[];
|
|
20
|
+
}[];
|
|
21
|
+
nodes?: GltfNode[];
|
|
22
|
+
meshes?: {
|
|
23
|
+
primitives?: {
|
|
24
|
+
attributes?: {
|
|
25
|
+
POSITION?: number;
|
|
26
|
+
};
|
|
27
|
+
}[];
|
|
28
|
+
}[];
|
|
29
|
+
accessors?: GltfAccessor[];
|
|
30
|
+
};
|
|
31
|
+
/** Local bounding box of a glTF's default scene from the accessors' min/max; no geometry is decoded. */
|
|
32
|
+
export declare function gltfBounds(json: GltfJson): Aabb | null;
|
|
33
|
+
/** The same box for a binary glTF, read from its JSON chunk alone. */
|
|
34
|
+
export declare function glbBounds(buffer: ArrayBuffer): Aabb | null;
|
|
35
|
+
/**
|
|
36
|
+
* A model's local bounds, fetched once per URL (resolved like the engine's glTF loader, so the HTTP cache usually
|
|
37
|
+
* answers). null when the file cannot be read; GI then leaves that model out.
|
|
38
|
+
*/
|
|
39
|
+
export declare function loadModelBounds(uri: string): Promise<Aabb | null>;
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PlacedObject } from '../../building/types/index.cjs';
|
|
2
|
+
import type { Aabb, VoxelSourceBox } from '../types.cjs';
|
|
3
|
+
/**
|
|
4
|
+
* GI stand-ins for placed objects: procedural trees from their size, glTF models from their file's bounding box
|
|
5
|
+
* (`modelBounds`, keyed by model URL) cut into a few solid parts by what the model is (a table's top, a tree's trunk and
|
|
6
|
+
* crown, a lamp's glowing head). Models whose bounds are not known yet are skipped until they are.
|
|
7
|
+
*/
|
|
8
|
+
export declare function objectProxyBoxes(object: PlacedObject, modelBounds: ReadonlyMap<string, Aabb | null>): VoxelSourceBox[];
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PlacedObject } from '../../building/types/index.js';
|
|
2
|
+
import type { Aabb, VoxelSourceBox } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* GI stand-ins for placed objects: procedural trees from their size, glTF models from their file's bounding box
|
|
5
|
+
* (`modelBounds`, keyed by model URL) cut into a few solid parts by what the model is (a table's top, a tree's trunk and
|
|
6
|
+
* crown, a lamp's glowing head). Models whose bounds are not known yet are skipped until they are.
|
|
7
|
+
*/
|
|
8
|
+
export declare function objectProxyBoxes(object: PlacedObject, modelBounds: ReadonlyMap<string, Aabb | null>): VoxelSourceBox[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { GiWorkerRequest, GiWorkerResponse } from './protocol.cjs';
|
|
2
|
+
/** One tick stands in for a 60 Hz frame, so `probesPerTick` keeps the meaning of GiVolume's probesPerFrame. */
|
|
3
|
+
export declare const GI_WORKER_TICK_MS = 16;
|
|
4
|
+
export type GiWorkerClock = {
|
|
5
|
+
now: () => number;
|
|
6
|
+
setTimeout: (callback: () => void, ms: number) => unknown;
|
|
7
|
+
clearTimeout: (handle: unknown) => void;
|
|
8
|
+
};
|
|
9
|
+
type Post = (message: GiWorkerResponse, transfer: Transferable[]) => void;
|
|
10
|
+
/**
|
|
11
|
+
* The GI worker's state, kept apart from the worker global so tests can drive it: it owns the voxel grid and probe
|
|
12
|
+
* cascade (the same runtime GiVolume uses on the main thread), traces probes on a timer and posts packed atlases.
|
|
13
|
+
*/
|
|
14
|
+
export declare class GiWorkerHost {
|
|
15
|
+
private readonly post;
|
|
16
|
+
private readonly clock;
|
|
17
|
+
private runtime;
|
|
18
|
+
private module;
|
|
19
|
+
private probesPerTick;
|
|
20
|
+
private uploadIntervalMs;
|
|
21
|
+
private lastUpload;
|
|
22
|
+
private timer;
|
|
23
|
+
private disposed;
|
|
24
|
+
private paused;
|
|
25
|
+
constructor(post: Post, clock?: GiWorkerClock);
|
|
26
|
+
handle(message: GiWorkerRequest): void;
|
|
27
|
+
/** Runs one tick now; the timer calls it, and tests call it instead of waiting. */
|
|
28
|
+
tick(): void;
|
|
29
|
+
private restart;
|
|
30
|
+
private schedule;
|
|
31
|
+
private stop;
|
|
32
|
+
}
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { GiWorkerRequest, GiWorkerResponse } from './protocol.js';
|
|
2
|
+
/** One tick stands in for a 60 Hz frame, so `probesPerTick` keeps the meaning of GiVolume's probesPerFrame. */
|
|
3
|
+
export declare const GI_WORKER_TICK_MS = 16;
|
|
4
|
+
export type GiWorkerClock = {
|
|
5
|
+
now: () => number;
|
|
6
|
+
setTimeout: (callback: () => void, ms: number) => unknown;
|
|
7
|
+
clearTimeout: (handle: unknown) => void;
|
|
8
|
+
};
|
|
9
|
+
type Post = (message: GiWorkerResponse, transfer: Transferable[]) => void;
|
|
10
|
+
/**
|
|
11
|
+
* The GI worker's state, kept apart from the worker global so tests can drive it: it owns the voxel grid and probe
|
|
12
|
+
* cascade (the same runtime GiVolume uses on the main thread), traces probes on a timer and posts packed atlases.
|
|
13
|
+
*/
|
|
14
|
+
export declare class GiWorkerHost {
|
|
15
|
+
private readonly post;
|
|
16
|
+
private readonly clock;
|
|
17
|
+
private runtime;
|
|
18
|
+
private module;
|
|
19
|
+
private probesPerTick;
|
|
20
|
+
private uploadIntervalMs;
|
|
21
|
+
private lastUpload;
|
|
22
|
+
private timer;
|
|
23
|
+
private disposed;
|
|
24
|
+
private paused;
|
|
25
|
+
constructor(post: Post, clock?: GiWorkerClock);
|
|
26
|
+
handle(message: GiWorkerRequest): void;
|
|
27
|
+
/** Runs one tick now; the timer calls it, and tests call it instead of waiting. */
|
|
28
|
+
tick(): void;
|
|
29
|
+
private restart;
|
|
30
|
+
private schedule;
|
|
31
|
+
private stop;
|
|
32
|
+
}
|
|
33
|
+
export {};
|