ice3 0.2.1 → 0.2.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 +7 -6
- package/dist/_types/assets/ICEGLBReader.d.ts +8 -1
- package/dist/_types/assets/ICEPreparedGLB.d.ts +25 -0
- package/dist/_types/assets/index.d.ts +1 -0
- package/dist/_types/core/camera/ICEPerspectiveCamera.d.ts +5 -0
- package/dist/_types/core/index.d.ts +1 -1
- package/dist/_types/core/material/ICEBasicMaterial.d.ts +50 -0
- package/dist/_types/renderer/InstanceBatch.d.ts +7 -0
- package/dist/_types/renderer/SceneBounds.d.ts +16 -0
- package/dist/_types/renderer/ShadowFrustum.d.ts +20 -0
- package/dist/_types/renderer/WebGL2DepthMath.d.ts +22 -0
- package/dist/_types/renderer/WebGL2InstanceBatch.d.ts +1 -1
- package/dist/_types/renderer/WebGL2Program.d.ts +55 -1
- package/dist/_types/renderer/WebGL2RendererBackend.d.ts +45 -1
- package/dist/_types/renderer/WebGL2SceneDepth.d.ts +19 -0
- package/dist/_types/renderer/WebGL2Shader.d.ts +11 -0
- package/dist/_types/renderer/WebGL2ShadowMap.d.ts +22 -6
- package/dist/_types/renderer/WebGL2TextureCache.d.ts +31 -0
- package/dist/_types/renderer/WebGL2Uv.d.ts +16 -0
- package/dist/_types/renderer/index.d.ts +1 -1
- package/dist/_types/renderer/types.d.ts +6 -0
- package/dist/_types/runtime/ICE3.d.ts +6 -0
- package/dist/index.js +1279 -166
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,13 +9,13 @@
|
|
|
9
9
|
ICE3 是面向工业场景的浏览器 3D Runtime。公开代码通过单向 facade 暴露 Scene、
|
|
10
10
|
Geometry、Camera、Asset 和 Tileset API。
|
|
11
11
|
|
|
12
|
-
## 安装
|
|
12
|
+
## 1. 安装
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
15
|
npm install ice3
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
## 最小使用
|
|
18
|
+
## 2. 最小使用
|
|
19
19
|
|
|
20
20
|
```ts
|
|
21
21
|
import {
|
|
@@ -54,9 +54,10 @@ WebGL2 兼容别名。拾取使用 `await engine.pick(point)`。
|
|
|
54
54
|
完整文档和相关工具见
|
|
55
55
|
[Engine 文档](https://github.com/ice-3d/ice3-engine/blob/main/README.md)。
|
|
56
56
|
|
|
57
|
-
工业模型接入 Runtime
|
|
58
|
-
[ICE3
|
|
59
|
-
|
|
60
|
-
[
|
|
57
|
+
工业模型接入 Runtime 前,使用
|
|
58
|
+
[ICE3 Studio](https://github.com/ice-3d/ice3-studio/blob/main/README.md)
|
|
59
|
+
完成 Source Import、Prepare、验证、partition、LOD 和 Tileset 发布。当前生产链见
|
|
60
|
+
[Studio Asset Pipeline](https://github.com/ice-3d/ice3-studio/blob/main/docs/reference/asset-pipeline.md)。
|
|
61
|
+
公开 package 的当前版本为 `0.2.3`。
|
|
61
62
|
|
|
62
63
|
本项目采用 MIT License。
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import type { ICEPreparedAssetSnapshot } from './ICEPreparedGLB.js';
|
|
2
|
-
export
|
|
2
|
+
export interface ICEPreparedReadOptions {
|
|
3
|
+
/**
|
|
4
|
+
* URL the GLB was loaded from. Texture images are resolved against it, as
|
|
5
|
+
* glTF requires external resources to be relative to the referencing file.
|
|
6
|
+
*/
|
|
7
|
+
readonly baseUrl?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function readPreparedGLB(bytes: ArrayBuffer, options?: ICEPreparedReadOptions): ICEPreparedAssetSnapshot;
|
|
3
10
|
export declare function verifyPreparedGLBIntegrity(bytes: ArrayBuffer): Promise<boolean>;
|
|
4
11
|
//# sourceMappingURL=ICEGLBReader.d.ts.map
|
|
@@ -22,6 +22,31 @@ export interface ICEPreparedMaterial {
|
|
|
22
22
|
readonly baseColor: string;
|
|
23
23
|
readonly edgeColor?: string;
|
|
24
24
|
readonly shading?: 'directional' | 'flat' | 'water';
|
|
25
|
+
/** Base-colour texture resolved from the source glTF. */
|
|
26
|
+
readonly map?: {
|
|
27
|
+
readonly url: string;
|
|
28
|
+
readonly scale?: readonly [number, number];
|
|
29
|
+
};
|
|
30
|
+
/** Tangent-space normal map. */
|
|
31
|
+
readonly normalMap?: {
|
|
32
|
+
readonly url: string;
|
|
33
|
+
readonly strength?: number;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Packed ORM map: R occlusion, G roughness, B metallic. A glTF may ship the
|
|
37
|
+
* two halves as separate slots; when they resolve to the same image the
|
|
38
|
+
* renderer samples it once.
|
|
39
|
+
*/
|
|
40
|
+
readonly ormMap?: {
|
|
41
|
+
readonly url: string;
|
|
42
|
+
readonly scale?: readonly [number, number];
|
|
43
|
+
readonly occlusion: boolean;
|
|
44
|
+
readonly metallicRoughness: boolean;
|
|
45
|
+
};
|
|
46
|
+
/** Metallic-roughness factors straight from the glTF material. */
|
|
47
|
+
readonly metallic?: number;
|
|
48
|
+
readonly roughness?: number;
|
|
49
|
+
readonly emissive?: readonly [number, number, number];
|
|
25
50
|
}
|
|
26
51
|
export interface ICEPreparedMesh {
|
|
27
52
|
readonly id: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { readPreparedGLB, verifyPreparedGLBIntegrity, } from './ICEGLBReader.js';
|
|
2
|
+
export type { ICEPreparedReadOptions } from './ICEGLBReader.js';
|
|
2
3
|
export type { ICEPreparedAssetSnapshot, ICEPreparedBatch, ICEPreparedBatching, ICEPreparedContract, ICEPreparedGeometry, ICEPreparedMaterial, ICEPreparedMesh, ICEPreparedNode, ICEPreparedStats, } from './ICEPreparedGLB.js';
|
|
3
4
|
export { applyPreviewGeometryDelta, parsePreviewGeometryPacket, } from './ICEPreviewGeometryPacket.js';
|
|
4
5
|
export type { ICEPreviewGeometry, ICEPreviewGeometryBackend, ICEPreviewGeometryDelta, ICEPreviewGeometryManifest, ICEPreviewGeometryMaterial, ICEPreviewGeometryNode, ICEPreviewGeometryPacket, ICEPreviewGeometryRange, ICEPreviewGeometryRangeUsage, ICEPreviewGeometryRecord, ICEPreviewGeometryResidencyMode, } from './ICEPreviewGeometryPacket.js';
|
|
@@ -21,6 +21,11 @@ export declare class ICEPerspectiveCamera {
|
|
|
21
21
|
setClipPlanes(near: number, far: number): this;
|
|
22
22
|
getPosition(): ICEVector3;
|
|
23
23
|
getTarget(): ICEVector3;
|
|
24
|
+
/**
|
|
25
|
+
* 投影矩阵。屏幕空间效果要从深度重建视空间坐标,光有 viewProjection 不够。
|
|
26
|
+
*/
|
|
27
|
+
getProjectionMatrix(aspect: number): ICEMatrix4;
|
|
28
|
+
getViewMatrix(): ICEMatrix4;
|
|
24
29
|
getViewProjectionMatrix(aspect: number): ICEMatrix4;
|
|
25
30
|
}
|
|
26
31
|
//# sourceMappingURL=ICEPerspectiveCamera.d.ts.map
|
|
@@ -9,7 +9,7 @@ export { ICEIndexedGeometry } from './geometry/ICEIndexedGeometry.js';
|
|
|
9
9
|
export type { ICEIndexedGeometryOptions } from './geometry/ICEIndexedGeometry.js';
|
|
10
10
|
export type { ICEGeometry, ICEGeometryBounds, ICEGeometryBufferUpdate, ICEGeometryByteRange, ICEGeometryIdentity, } from './geometry/ICEGeometry.js';
|
|
11
11
|
export { ICEBasicMaterial } from './material/ICEBasicMaterial.js';
|
|
12
|
-
export type { ICEBasicMaterialOptions } from './material/ICEBasicMaterial.js';
|
|
12
|
+
export type { ICEBasicMaterialMap, ICEBasicMaterialNormalMap, ICEBasicMaterialOptions, ICEBasicMaterialOrmMap, } from './material/ICEBasicMaterial.js';
|
|
13
13
|
export { ICEPerspectiveCamera } from './camera/ICEPerspectiveCamera.js';
|
|
14
14
|
export type { ICEPerspectiveCameraOptions } from './camera/ICEPerspectiveCamera.js';
|
|
15
15
|
export { ICEFrustum } from './culling/ICEFrustum.js';
|
|
@@ -1,13 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base-colour texture reference.
|
|
3
|
+
*
|
|
4
|
+
* `url` points at an image the renderer loads asynchronously; `scale` tiles it
|
|
5
|
+
* over the metre-based UV projection (`[1,1]` means one texture repeat per metre).
|
|
6
|
+
*/
|
|
7
|
+
export declare const DEFAULT_ROUGHNESS = 0.85;
|
|
8
|
+
export interface ICEBasicMaterialMap {
|
|
9
|
+
readonly url: string;
|
|
10
|
+
readonly scale?: readonly [number, number];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Tangent-space normal map.
|
|
14
|
+
*
|
|
15
|
+
* `strength` multiplies the sampled X/Y perturbation, matching glTF's
|
|
16
|
+
* `normalTexture.scale`; 1 is neutral.
|
|
17
|
+
*/
|
|
18
|
+
export interface ICEBasicMaterialNormalMap {
|
|
19
|
+
readonly url: string;
|
|
20
|
+
readonly strength?: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Packed occlusion / roughness / metallic map, the glTF ORM layout:
|
|
24
|
+
* R = ambient occlusion, G = roughness, B = metallic.
|
|
25
|
+
*
|
|
26
|
+
* `occlusion` and `metallicRoughness` say which channels the image actually
|
|
27
|
+
* carries — an exporter may ship only the metallic-roughness half, and using the
|
|
28
|
+
* R channel then would darken surfaces for no reason.
|
|
29
|
+
*/
|
|
30
|
+
export interface ICEBasicMaterialOrmMap {
|
|
31
|
+
readonly url: string;
|
|
32
|
+
readonly scale?: readonly [number, number];
|
|
33
|
+
readonly occlusion?: boolean;
|
|
34
|
+
readonly metallicRoughness?: boolean;
|
|
35
|
+
}
|
|
1
36
|
export interface ICEBasicMaterialOptions {
|
|
2
37
|
readonly color: string;
|
|
3
38
|
readonly edgeColor?: string;
|
|
4
39
|
readonly shading?: 'directional' | 'flat' | 'water';
|
|
40
|
+
readonly map?: ICEBasicMaterialMap;
|
|
41
|
+
readonly normalMap?: ICEBasicMaterialNormalMap;
|
|
42
|
+
readonly ormMap?: ICEBasicMaterialOrmMap;
|
|
43
|
+
/** 0 = dielectric, 1 = metal. Drives the specular tint and strength. */
|
|
44
|
+
readonly metallic?: number;
|
|
45
|
+
/** 0 = mirror-smooth highlight, 1 = broad and dull. */
|
|
46
|
+
readonly roughness?: number;
|
|
47
|
+
/** Linear RGB emitted by the surface, added after lighting. */
|
|
48
|
+
readonly emissive?: readonly [number, number, number];
|
|
5
49
|
}
|
|
6
50
|
export declare class ICEBasicMaterial {
|
|
7
51
|
readonly typeId = "ice3:BasicMaterial";
|
|
8
52
|
readonly color: string;
|
|
9
53
|
readonly edgeColor: string | undefined;
|
|
10
54
|
readonly shading: 'directional' | 'flat' | 'water' | undefined;
|
|
55
|
+
readonly map: ICEBasicMaterialMap | undefined;
|
|
56
|
+
readonly normalMap: ICEBasicMaterialNormalMap | undefined;
|
|
57
|
+
readonly ormMap: ICEBasicMaterialOrmMap | undefined;
|
|
58
|
+
readonly metallic: number;
|
|
59
|
+
readonly roughness: number;
|
|
60
|
+
readonly emissive: readonly [number, number, number] | undefined;
|
|
11
61
|
constructor(options: ICEBasicMaterialOptions);
|
|
12
62
|
toJSON(): Record<string, unknown>;
|
|
13
63
|
}
|
|
@@ -11,4 +11,11 @@ export interface ICEInstanceBatch {
|
|
|
11
11
|
readonly materialKey: string;
|
|
12
12
|
}
|
|
13
13
|
export declare function collectInstanceBatches(renderables: readonly ICEGeometryRenderable[], output?: ICEInstanceBatch[]): readonly ICEInstanceBatch[];
|
|
14
|
+
/**
|
|
15
|
+
* 落单的网格:几何与材质组合只出现一次,实例化省不下开销,主通道仍按单体绘制。
|
|
16
|
+
*
|
|
17
|
+
* 单独抽出来是因为**每个附加通道都要画同一批东西**。深度通道漏掉这一条,
|
|
18
|
+
* 落单的网格就既不参与遮挡也不接收遮蔽(SPEC-007 第 5 节)。
|
|
19
|
+
*/
|
|
20
|
+
export declare function renderablesOutsideInstanceBatches(renderables: readonly ICEGeometryRenderable[], batches: readonly ICEInstanceBatch[]): ICEGeometryRenderable[];
|
|
14
21
|
//# sourceMappingURL=InstanceBatch.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ICEGeometry } from '../core/index.js';
|
|
2
|
+
import type { ICEGeometryRenderable } from './Renderables.js';
|
|
3
|
+
import type { ICEBounds } from './ShadowFrustum.js';
|
|
4
|
+
type LocalBounds = Readonly<{
|
|
5
|
+
min: readonly [number, number, number];
|
|
6
|
+
max: readonly [number, number, number];
|
|
7
|
+
}>;
|
|
8
|
+
/** 几何的局部包围盒:只在首次见到该几何时扫描一遍顶点。 */
|
|
9
|
+
export declare function geometryLocalBounds(geometry: ICEGeometry): LocalBounds | null;
|
|
10
|
+
/**
|
|
11
|
+
* 累加所有可渲染网格的世界包围盒。返回 `null` 表示场景是空的,
|
|
12
|
+
* 调用方应退回默认视锥而不是用空盒子去拟合(否则视锥退化成一条线)。
|
|
13
|
+
*/
|
|
14
|
+
export declare function accumulateSceneBounds(renderables: readonly ICEGeometryRenderable[]): ICEBounds | null;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=SceneBounds.d.ts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type ICEBounds = Readonly<{
|
|
2
|
+
min: readonly [number, number, number];
|
|
3
|
+
max: readonly [number, number, number];
|
|
4
|
+
}>;
|
|
5
|
+
/** 光源方向(与主着色器、阴影 pass 共用同一约定:指向"光传播"的方向)。 */
|
|
6
|
+
export declare const SHADOW_LIGHT_DIRECTION: readonly [number, number, number];
|
|
7
|
+
export type ICEShadowFrustum = Readonly<{
|
|
8
|
+
/** 光照视图投影矩阵(列主序 16 元素)。 */
|
|
9
|
+
matrix: Float32Array;
|
|
10
|
+
/** 一个纹素在世界空间里的边长(米):法线偏移量按它来算。 */
|
|
11
|
+
texelWorld: number;
|
|
12
|
+
}>;
|
|
13
|
+
/**
|
|
14
|
+
* 场景包围盒 → 光照视图投影矩阵(列主序 16 元素)。
|
|
15
|
+
*
|
|
16
|
+
* 传入 `null` 时退回一个覆盖 600 米场地的默认盒,避免直接抛错:
|
|
17
|
+
* 阴影是可选效果,宁可保守覆盖也不要整帧失败。
|
|
18
|
+
*/
|
|
19
|
+
export declare function shadowFrustum(bounds: ICEBounds | null, mapSize?: number): ICEShadowFrustum;
|
|
20
|
+
//# sourceMappingURL=ShadowFrustum.d.ts.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type PerspectiveProjection = {
|
|
2
|
+
/** 投影矩阵列主序元素,与 `ICEMatrix4.elements` 一致。 */
|
|
3
|
+
readonly elements: Float32Array | readonly number[];
|
|
4
|
+
readonly near: number;
|
|
5
|
+
readonly far: number;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* NDC `(x, y, depth)` → 视空间坐标(右手系,相机看向 −Z)。
|
|
9
|
+
*
|
|
10
|
+
* `depth` 取深度缓冲里的值,范围 `[0, 1]`。
|
|
11
|
+
*/
|
|
12
|
+
export declare function viewPositionFromNdc(ndcX: number, ndcY: number, depth: number, projection: PerspectiveProjection): [number, number, number];
|
|
13
|
+
/** 视空间坐标 → NDC;`w` 不为正说明落在相机背面。 */
|
|
14
|
+
export declare function ndcFromViewPosition(position: readonly [number, number, number], projection: PerspectiveProjection): [number, number, number, number];
|
|
15
|
+
/**
|
|
16
|
+
* 视空间半径 → 屏幕像素半径。
|
|
17
|
+
*
|
|
18
|
+
* 用样本点到相机的深度换算,靠近相机时半径自然放大、远处收小;这正是
|
|
19
|
+
* "按视距自适应"要的效果,而且不需要知道世界单位与像素的比例。
|
|
20
|
+
*/
|
|
21
|
+
export declare function screenRadiusForWorldRadius(worldRadius: number, viewDepth: number, viewportHeight: number, projection: PerspectiveProjection): number;
|
|
22
|
+
//# sourceMappingURL=WebGL2DepthMath.d.ts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { WebGL2GeometryCache } from './WebGL2GeometryCache.js';
|
|
2
2
|
import type { ICEInstanceBatch } from './InstanceBatch.js';
|
|
3
3
|
export type { ICEGeometryRenderable } from './Renderables.js';
|
|
4
|
-
export { collectInstanceBatches, type ICEInstanceBatch, } from './InstanceBatch.js';
|
|
4
|
+
export { collectInstanceBatches, renderablesOutsideInstanceBatches, type ICEInstanceBatch, } from './InstanceBatch.js';
|
|
5
5
|
export interface WebGL2InstanceEntry {
|
|
6
6
|
readonly vertexArray: WebGLVertexArrayObject;
|
|
7
7
|
readonly matrixBuffer: WebGLBuffer;
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import type { ICEMatrix4 } from '../core/index.js';
|
|
2
2
|
export declare function directionalLightingShade(normal: readonly [number, number, number]): number;
|
|
3
|
+
/**
|
|
4
|
+
* Mirror of the shader's specular curve, exported so the response can be tested
|
|
5
|
+
* without a GPU: smoother surfaces get a tighter, stronger highlight.
|
|
6
|
+
*/
|
|
7
|
+
export declare function specularShininess(roughness: number): number;
|
|
8
|
+
export declare function specularGain(roughness: number): number;
|
|
9
|
+
/** Metals tint their highlight with the base colour; dielectrics stay neutral. */
|
|
10
|
+
export declare function specularReflectance(metallic: number, color: readonly [number, number, number]): [number, number, number];
|
|
3
11
|
export declare class WebGL2Program {
|
|
4
12
|
private readonly gl;
|
|
5
13
|
static readonly POSITION_ATTRIBUTE = 0;
|
|
@@ -17,16 +25,62 @@ export declare class WebGL2Program {
|
|
|
17
25
|
private readonly shadowMapLocation;
|
|
18
26
|
private readonly lightMatrixLocation;
|
|
19
27
|
private readonly shadowEnabledLocation;
|
|
28
|
+
private readonly shadowNormalOffsetLocation;
|
|
29
|
+
private readonly shadowDebugLocation;
|
|
20
30
|
private readonly instancingLocation;
|
|
21
31
|
private readonly pickModeLocation;
|
|
32
|
+
private readonly clipPlaneLocation;
|
|
33
|
+
private readonly baseColorMapLocation;
|
|
34
|
+
private readonly useBaseColorMapLocation;
|
|
35
|
+
private readonly uvScaleLocation;
|
|
36
|
+
private readonly normalMapLocation;
|
|
37
|
+
private readonly ormMapLocation;
|
|
38
|
+
private readonly useOrmMapLocation;
|
|
39
|
+
private readonly ormOcclusionLocation;
|
|
40
|
+
private readonly ormMetallicRoughnessLocation;
|
|
41
|
+
private readonly useNormalMapLocation;
|
|
42
|
+
private readonly normalScaleLocation;
|
|
43
|
+
private readonly metallicLocation;
|
|
44
|
+
private readonly roughnessLocation;
|
|
45
|
+
private readonly emissiveLocation;
|
|
46
|
+
private readonly sceneDepthLocation;
|
|
47
|
+
private readonly useSceneDepthLocation;
|
|
48
|
+
private readonly projectionLocation;
|
|
49
|
+
private readonly viewportLocation;
|
|
50
|
+
private readonly clipRangeLocation;
|
|
51
|
+
private readonly aoRadiusLocation;
|
|
52
|
+
private readonly aoStrengthLocation;
|
|
22
53
|
constructor(gl: WebGL2RenderingContext);
|
|
23
54
|
use(): void;
|
|
24
55
|
setMatrix(matrix: ICEMatrix4): void;
|
|
25
56
|
setColor(color: readonly [number, number, number, number]): void;
|
|
57
|
+
/**
|
|
58
|
+
* Bind a base-colour texture to unit 0 and enable sampling. Passing `null`
|
|
59
|
+
* restores flat shading without touching the bound texture.
|
|
60
|
+
*/
|
|
61
|
+
setBaseColorMap(texture: WebGLTexture | null, scale: readonly [number, number]): void;
|
|
62
|
+
/** Bind a tangent-space normal map to unit 1; `null` disables perturbation. */
|
|
63
|
+
setNormalMap(texture: WebGLTexture | null, strength: number): void;
|
|
64
|
+
/**
|
|
65
|
+
* Bind the packed ORM map. `occlusion` / `metallicRoughness` describe which
|
|
66
|
+
* halves of the image are meaningful; both false disables sampling.
|
|
67
|
+
*/
|
|
68
|
+
setOrmMap(texture: WebGLTexture | null, occlusion: boolean, metallicRoughness: boolean): void;
|
|
69
|
+
/** Metallic-roughness factors plus emission for the current draw. */
|
|
70
|
+
setSurface(metallic: number, roughness: number, emissive: readonly [number, number, number] | undefined): void;
|
|
71
|
+
/** 绑定相机深度纹理(unit 2)并传入重建视空间所需的相机参数。 */
|
|
72
|
+
setSceneDepth(texture: WebGLTexture | null, projection: {
|
|
73
|
+
readonly elements: Float32Array;
|
|
74
|
+
} | null, near: number, far: number, deviceWidth: number, deviceHeight: number): void;
|
|
75
|
+
/** 遮蔽半径(米)与强度,供运行时调节。强度 0 等于关闭。 */
|
|
76
|
+
setOcclusion(radius: number, strength: number): void;
|
|
26
77
|
setClipOffset(x: number, y: number): void;
|
|
78
|
+
setClipPlane(plane: readonly [number, number, number, number]): void;
|
|
27
79
|
setVertexColors(enabled: boolean): void;
|
|
28
80
|
/** 绑定阴影贴图与光源矩阵;关闭时着色器跳过采样。 */
|
|
29
|
-
setShadow(enabled: boolean, texture: WebGLTexture | null, matrix: Float32Array | null, unit?: number): void;
|
|
81
|
+
setShadow(enabled: boolean, texture: WebGLTexture | null, matrix: Float32Array | null, normalOffset?: number, unit?: number): void;
|
|
82
|
+
/** 阴影调试通道:0 关闭,1 输出遮蔽判定,2 输出深度图。 */
|
|
83
|
+
setShadowDebug(mode: number): void;
|
|
30
84
|
setDirectionalShading(enabled: boolean): void;
|
|
31
85
|
setWaterShading(enabled: boolean): void;
|
|
32
86
|
setCameraPosition(position: readonly [number, number, number]): void;
|
|
@@ -11,8 +11,16 @@ export declare class WebGL2RendererBackend implements ICERendererBackend {
|
|
|
11
11
|
private onContextLost;
|
|
12
12
|
private onContextRestored;
|
|
13
13
|
private program;
|
|
14
|
+
private clipPlane;
|
|
14
15
|
private shadowMap;
|
|
15
|
-
|
|
16
|
+
/**
|
|
17
|
+
* 方向光阴影开关。默认开启:没有影子的厂区看起来像浮在地上,
|
|
18
|
+
* 而多一次全场景深度 pass 的代价远小于这个观感损失。
|
|
19
|
+
* 要关掉用 `initialize({ shadows: false })` 或页面地址 `?shadows=0`。
|
|
20
|
+
*/
|
|
21
|
+
private shadowEnabled;
|
|
22
|
+
/** `?shadowdebug=1` 输出遮蔽判定,`=2` 输出深度图;排查阴影问题的唯一可信手段。 */
|
|
23
|
+
private shadowDebug;
|
|
16
24
|
private semanticProgram;
|
|
17
25
|
private geometryCache;
|
|
18
26
|
private instanceCache;
|
|
@@ -27,12 +35,47 @@ export declare class WebGL2RendererBackend implements ICERendererBackend {
|
|
|
27
35
|
private lastFrameProfile;
|
|
28
36
|
private backgroundRgba;
|
|
29
37
|
private frameStats;
|
|
38
|
+
private textures;
|
|
39
|
+
private sceneDepth;
|
|
40
|
+
private occlusionRadius;
|
|
41
|
+
/**
|
|
42
|
+
* 三圈采样比双圈多找到约 1.7 个亮度点的遮蔽(同参数 96.36 → 94.65),原样沿用到
|
|
43
|
+
* 默认值就把厂区压得发闷。0.30 是回调后的值:整帧 95.70(无遮蔽 99.59),
|
|
44
|
+
* 高光像素 878(无遮蔽 1088),接触暗部仍看得见。详见 SPEC-007 第 5.5 节。
|
|
45
|
+
*/
|
|
46
|
+
private occlusionStrength;
|
|
47
|
+
private options;
|
|
48
|
+
/**
|
|
49
|
+
* Bind the material's colour and (if it has one) its base-colour texture.
|
|
50
|
+
* Called for every opaque/shaded draw so a batched draw and a single mesh draw
|
|
51
|
+
* cannot drift apart.
|
|
52
|
+
*/
|
|
53
|
+
private applyMaterial;
|
|
54
|
+
/** Edge overlays are line work: never sampled, always flat. */
|
|
55
|
+
private applyEdgeMaterial;
|
|
56
|
+
/**
|
|
57
|
+
* `?ao=<radius>,<strength>` 覆盖遮蔽参数(`ao=off` 关闭)。
|
|
58
|
+
*
|
|
59
|
+
* 屏幕空间遮蔽的合适参数与场景尺度强相关,靠改代码重编译来找太慢。这里只读一次
|
|
60
|
+
* 页面地址,纯属调参通道,不参与渲染决策。
|
|
61
|
+
*/
|
|
62
|
+
private readOcclusionOverride;
|
|
63
|
+
/**
|
|
64
|
+
* `?shadows=1` / `?shadows=0` 覆盖阴影开关,与 `?ao` 同属调参通道。
|
|
65
|
+
*
|
|
66
|
+
* 阴影是一次额外全场景 pass,默认不开;演示与对比时靠地址栏切换,
|
|
67
|
+
* 不必为看清"有影子/没影子"重编译一次。
|
|
68
|
+
*/
|
|
69
|
+
private readShadowOverride;
|
|
70
|
+
private ensureTextureCache;
|
|
30
71
|
private readonly handleContextLost;
|
|
31
72
|
private readonly handleContextRestored;
|
|
32
73
|
initialize(options: {
|
|
33
74
|
readonly canvas: HTMLCanvasElement;
|
|
34
75
|
readonly onContextLost?: () => void;
|
|
35
76
|
readonly onContextRestored?: () => void;
|
|
77
|
+
readonly onUploadReady?: () => void;
|
|
78
|
+
readonly shadows?: boolean;
|
|
36
79
|
}): void;
|
|
37
80
|
resize(viewport: ICEViewport, dpr: number): void;
|
|
38
81
|
setBackgroundColor(color: string): void;
|
|
@@ -40,6 +83,7 @@ export declare class WebGL2RendererBackend implements ICERendererBackend {
|
|
|
40
83
|
prepareGeometry(geometry: ICEGeometry, update?: import('../core/index.js').ICEGeometryBufferUpdate): void;
|
|
41
84
|
releaseGeometry(geometry: ICEGeometry): void;
|
|
42
85
|
releaseBatchGeometry(geometry: ICEGeometry): void;
|
|
86
|
+
setClipPlane(plane: readonly [number, number, number, number] | null): void;
|
|
43
87
|
render(frame: ICEFrame): void;
|
|
44
88
|
enableProfiling(enabled: boolean): void;
|
|
45
89
|
get frameProfile(): ICEFrameStageProfile | null;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare class WebGL2SceneDepth {
|
|
2
|
+
private readonly gl;
|
|
3
|
+
private readonly framebuffer;
|
|
4
|
+
private depthTexture;
|
|
5
|
+
private readonly program;
|
|
6
|
+
private readonly matrixLocation;
|
|
7
|
+
private readonly instancingLocation;
|
|
8
|
+
private width;
|
|
9
|
+
private height;
|
|
10
|
+
constructor(gl: WebGL2RenderingContext);
|
|
11
|
+
get texture(): WebGLTexture | null;
|
|
12
|
+
begin(viewProjection: Float32Array, width: number, height: number): void;
|
|
13
|
+
setMatrix(matrix: Float32Array): void;
|
|
14
|
+
setInstancing(enabled: boolean): void;
|
|
15
|
+
end(width: number, height: number): void;
|
|
16
|
+
dispose(): void;
|
|
17
|
+
private ensureTexture;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=WebGL2SceneDepth.d.ts.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compile and link a program, throwing with the driver's info log on failure.
|
|
3
|
+
*
|
|
4
|
+
* WebGL fails silently: `compileShader`/`linkProgram` only set a status flag, and
|
|
5
|
+
* code that returns `null` on failure turns a shader typo into "this pass simply
|
|
6
|
+
* does nothing". That is exactly how a depth pass can run for two rounds without
|
|
7
|
+
* changing a single pixel (SPEC-007). Every program in the renderer goes through
|
|
8
|
+
* here so a broken shader is loud and quotable.
|
|
9
|
+
*/
|
|
10
|
+
export declare function createShaderProgram(gl: WebGL2RenderingContext, vertexSource: string, fragmentSource: string, label: string): WebGLProgram;
|
|
11
|
+
//# sourceMappingURL=WebGL2Shader.d.ts.map
|
|
@@ -1,26 +1,42 @@
|
|
|
1
|
+
import { type ICEBounds } from './ShadowFrustum.js';
|
|
1
2
|
/** 光源方向(与主着色器的 diffuse 保持同一方向)。 */
|
|
2
|
-
export
|
|
3
|
+
export { SHADOW_LIGHT_DIRECTION as LIGHT_DIRECTION } from './ShadowFrustum.js';
|
|
3
4
|
export declare class WebGL2ShadowMap {
|
|
4
5
|
private readonly gl;
|
|
6
|
+
/** 最近一次着色器编译/链接失败的原因,供诊断读取。 */
|
|
7
|
+
lastError: string | null;
|
|
5
8
|
private framebuffer;
|
|
6
9
|
private depthTexture;
|
|
7
10
|
private program;
|
|
8
|
-
private
|
|
11
|
+
private matrixLocation;
|
|
12
|
+
private instancingLocation;
|
|
9
13
|
private matrixScratch;
|
|
14
|
+
private texelWorldValue;
|
|
10
15
|
constructor(gl: WebGL2RenderingContext);
|
|
11
16
|
/** 深度纹理,供主着色器采样。 */
|
|
12
17
|
get texture(): WebGLTexture | null;
|
|
13
18
|
get matrix(): Float32Array;
|
|
19
|
+
/** 一个深度纹素在世界空间的边长(米)。法线偏移按它换算,别用魔数。 */
|
|
20
|
+
get texelWorld(): number;
|
|
21
|
+
/**
|
|
22
|
+
* 按场景包围盒拟合视锥。每帧调用没有意义——场景内容不变时矩阵也不会变,
|
|
23
|
+
* 所以由调用方决定何时重算(包围盒变化或首帧)。
|
|
24
|
+
*/
|
|
25
|
+
setBounds(bounds: ICEBounds | null): void;
|
|
14
26
|
/** 绑定阴影帧缓冲,返回是否成功。 */
|
|
15
27
|
begin(): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* 非实例化绘制:矩阵换成 `lightViewProjection × world`,顶点位置直接当世界坐标用。
|
|
30
|
+
*
|
|
31
|
+
* 阴影通道原先只会画实例化批次,瓦片(渲染批次)与落单网格因此完全不投影。
|
|
32
|
+
* 补这两条路径靠的就是这个入口——和 `WebGL2SceneDepth` 同一套写法。
|
|
33
|
+
*/
|
|
34
|
+
setMatrix(matrix: Float32Array): void;
|
|
35
|
+
setInstancing(enabled: boolean): void;
|
|
16
36
|
/** 解绑,恢复默认帧缓冲。 */
|
|
17
37
|
end(width: number, height: number): void;
|
|
18
38
|
dispose(): void;
|
|
19
39
|
private createResources;
|
|
20
|
-
/** 正交光源矩阵:覆盖整片场地,与主着色器的光方向一致。 */
|
|
21
|
-
private updateLightMatrix;
|
|
22
40
|
private createProgram;
|
|
23
|
-
private compile;
|
|
24
41
|
}
|
|
25
|
-
export declare const SHADOW_BIAS = 0.0018;
|
|
26
42
|
//# sourceMappingURL=WebGL2ShadowMap.d.ts.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base-colour texture cache.
|
|
3
|
+
*
|
|
4
|
+
* Materials reference textures by URL; the renderer turns each URL into one
|
|
5
|
+
* `WebGLTexture` the first time a frame needs it and keeps it for later frames.
|
|
6
|
+
* Loading is asynchronous, so the first frames after a URL appears draw with the
|
|
7
|
+
* flat material colour and switch to the texture once the upload lands — a
|
|
8
|
+
* self-correcting behaviour that never blocks the frame loop.
|
|
9
|
+
*/
|
|
10
|
+
export type ICEImageLoader = (url: string) => Promise<ImageBitmap>;
|
|
11
|
+
export type ICEWebGL2TextureStats = {
|
|
12
|
+
readonly loaded: number;
|
|
13
|
+
readonly pending: number;
|
|
14
|
+
readonly failed: number;
|
|
15
|
+
};
|
|
16
|
+
/** Default loader: fetch the image and decode it off the main thread. */
|
|
17
|
+
export declare const fetchImageLoader: ICEImageLoader;
|
|
18
|
+
export declare class WebGL2TextureCache {
|
|
19
|
+
private readonly gl;
|
|
20
|
+
private readonly load;
|
|
21
|
+
private readonly onUpload?;
|
|
22
|
+
private readonly entries;
|
|
23
|
+
private disposed;
|
|
24
|
+
constructor(gl: WebGL2RenderingContext, load?: ICEImageLoader, onUpload?: (() => void) | undefined);
|
|
25
|
+
/** Texture for `url`, or `null` while it is still loading (or after failure). */
|
|
26
|
+
texture(url: string): WebGLTexture | null;
|
|
27
|
+
stats(): ICEWebGL2TextureStats;
|
|
28
|
+
dispose(): void;
|
|
29
|
+
private upload;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=WebGL2TextureCache.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Box-projected texture coordinates.
|
|
3
|
+
*
|
|
4
|
+
* Studio generates geometry procedurally, so meshes reach the renderer without a
|
|
5
|
+
* UV attribute. The projection is derived from the surface instead: each fragment
|
|
6
|
+
* is projected along the dominant axis of its normal, which is stable inside a
|
|
7
|
+
* face and needs no extra vertex channel.
|
|
8
|
+
*
|
|
9
|
+
* This mirrors `box_projected_uvs` in Studio's exporter, so a surface textured in
|
|
10
|
+
* the viewport and the same surface exported as glTF land on the same texels.
|
|
11
|
+
* Coordinates are in metres; tiling is a material concern.
|
|
12
|
+
*/
|
|
13
|
+
export type ICEUvScale = readonly [number, number];
|
|
14
|
+
export declare const DEFAULT_UV_SCALE: ICEUvScale;
|
|
15
|
+
export declare function boxProjectedUv(position: readonly [number, number, number], normal: readonly [number, number, number], scale?: ICEUvScale): [number, number];
|
|
16
|
+
//# sourceMappingURL=WebGL2Uv.d.ts.map
|
|
@@ -15,7 +15,7 @@ export { WebGPUBundleCache } from './WebGPUBundleCache.js';
|
|
|
15
15
|
export { buildSelectionMask, WebGPUSelectionMaskBuffer, type ICESelectionMaskLayout, } from './WebGPUSelectionMask.js';
|
|
16
16
|
export { collectWebGPUPickIds, WebGPUPicker, } from './WebGPUPicker.js';
|
|
17
17
|
export { collectRenderables, selectionIdentity, type ICEGeometryRenderable, } from './Renderables.js';
|
|
18
|
-
export { collectInstanceBatches, type ICEInstanceBatch, } from './InstanceBatch.js';
|
|
18
|
+
export { collectInstanceBatches, renderablesOutsideInstanceBatches, type ICEInstanceBatch, } from './InstanceBatch.js';
|
|
19
19
|
export { queueBatchGeneration } from './ICEWebGL2BatchGenerationUploader.js';
|
|
20
20
|
export type { ICEFrameStageProfile, } from './RendererProfiler.js';
|
|
21
21
|
export { RendererProfiler, } from './RendererProfiler.js';
|
|
@@ -49,9 +49,15 @@ export interface ICERendererBackend {
|
|
|
49
49
|
readonly onContextLost?: () => void;
|
|
50
50
|
readonly onContextRestored?: () => void;
|
|
51
51
|
readonly onError?: (error: ICEEngineError) => void;
|
|
52
|
+
/** A deferred GPU upload (for example a base-colour texture) just landed. */
|
|
53
|
+
readonly onUploadReady?: () => void;
|
|
54
|
+
/** Directional-light shadows. On by default; pass false to skip the extra scene pass. */
|
|
55
|
+
readonly shadows?: boolean;
|
|
52
56
|
}): void;
|
|
53
57
|
resize(viewport: ICEViewport, dpr: number): void;
|
|
54
58
|
setBackgroundColor?(color: string): void;
|
|
59
|
+
/** Clip plane `[nx, ny, nz, d]`: fragments with `dot(world, n) + d < 0` are discarded; `null` disables. */
|
|
60
|
+
setClipPlane?(plane: readonly [number, number, number, number] | null): void;
|
|
55
61
|
prepareBatchGeometry?(geometry: ICEGeometry): void;
|
|
56
62
|
releaseBatchGeometry?(geometry: ICEGeometry): void;
|
|
57
63
|
prepareGeometry?(geometry: ICEGeometry, update?: ICEGeometryBufferUpdate): void;
|
|
@@ -72,6 +72,7 @@ export declare class ICE3 extends ICEEventDispatcher {
|
|
|
72
72
|
private generatedOverlayCanvas;
|
|
73
73
|
private scene;
|
|
74
74
|
private camera;
|
|
75
|
+
private clipPlane;
|
|
75
76
|
private viewport;
|
|
76
77
|
private dpr;
|
|
77
78
|
private frameId;
|
|
@@ -96,6 +97,11 @@ export declare class ICE3 extends ICEEventDispatcher {
|
|
|
96
97
|
setScene(scene: ICEScene): this;
|
|
97
98
|
setCamera(camera: ICEPerspectiveCamera): this;
|
|
98
99
|
setBackgroundColor(color: string): this;
|
|
100
|
+
/**
|
|
101
|
+
* Section plane `[nx, ny, nz, d]`: fragments with `dot(world, n) + d < 0`
|
|
102
|
+
* are discarded. `null` (or a zero plane) disables clipping.
|
|
103
|
+
*/
|
|
104
|
+
setClipPlane(plane: readonly [number, number, number, number] | null): this;
|
|
99
105
|
prepareRenderBatchGeometry(geometry: ICEGeometry): this;
|
|
100
106
|
releaseRenderBatchGeometry(geometry: ICEGeometry): this;
|
|
101
107
|
prepareGeometry(geometry: ICEGeometry, update?: import('../core/index.js').ICEGeometryBufferUpdate): this;
|