@woosh/meep-engine 2.138.3 → 2.138.5
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/package.json +1 -1
- package/src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.d.ts +13 -5
- package/src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.d.ts.map +1 -1
- package/src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.js +253 -280
- package/src/core/bvh2/bvh3/ebvh_update_hierarchy_bounds.js +1 -1
- package/src/core/bvh2/bvh3/query/bvh_query_depth_range_in_frustum.d.ts +31 -0
- package/src/core/bvh2/bvh3/query/bvh_query_depth_range_in_frustum.d.ts.map +1 -0
- package/src/core/bvh2/bvh3/query/bvh_query_depth_range_in_frustum.js +101 -0
- package/src/core/cache/CacheV2.d.ts +6 -2
- package/src/core/cache/CacheV2.d.ts.map +1 -1
- package/src/core/cache/CacheV2.js +6 -2
- package/src/engine/EngineHarness.js +2 -2
- package/src/engine/ecs/renderable/RenderSystem.d.ts.map +1 -1
- package/src/engine/ecs/renderable/RenderSystem.js +6 -0
- package/src/engine/ecs/terrain/ecs/TerrainSystem.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/TerrainSystem.js +19 -0
- package/src/engine/graphics/ecs/camera/auto_set_camera_clipping_planes.d.ts +4 -1
- package/src/engine/graphics/ecs/camera/auto_set_camera_clipping_planes.d.ts.map +1 -1
- package/src/engine/graphics/ecs/camera/auto_set_camera_clipping_planes.js +121 -12
- package/src/engine/graphics/ecs/light/LightSystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/light/LightSystem.js +80 -18
- package/src/engine/graphics/ecs/light/shadow/compute_view_frustum_aabb_in_space.d.ts +14 -0
- package/src/engine/graphics/ecs/light/shadow/compute_view_frustum_aabb_in_space.d.ts.map +1 -0
- package/src/engine/graphics/ecs/light/shadow/compute_view_frustum_aabb_in_space.js +62 -0
- package/src/engine/graphics/ecs/light/shadow/extend_shadow_camera_near_for_casters.d.ts +30 -0
- package/src/engine/graphics/ecs/light/shadow/extend_shadow_camera_near_for_casters.d.ts.map +1 -0
- package/src/engine/graphics/ecs/light/shadow/extend_shadow_camera_near_for_casters.js +97 -0
- package/src/engine/graphics/ecs/mesh/MeshSystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/mesh/MeshSystem.js +6 -0
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +6 -0
- package/src/engine/graphics/ecs/trail2d/Trail2DSystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/trail2d/Trail2DSystem.js +6 -0
- package/src/engine/graphics/ecs/water/WaterSystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/water/WaterSystem.js +6 -0
- package/src/engine/graphics/impostors/octahedral/prototypeBaker.js +7 -10
- package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderV0.d.ts.map +1 -1
- package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderV0.js +139 -57
- package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderWireframeV0.d.ts.map +1 -1
- package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderWireframeV0.js +123 -38
- package/src/engine/graphics/impostors/octahedral/util/makeImpostorAtlasPreview.d.ts +1 -1
- package/src/engine/graphics/impostors/octahedral/util/makeImpostorAtlasPreview.d.ts.map +1 -1
- package/src/engine/graphics/impostors/octahedral/util/makeImpostorAtlasPreview.js +7 -3
- package/src/engine/graphics/particles/ecs/ParticleEmitterSystem.d.ts.map +1 -1
- package/src/engine/graphics/particles/ecs/ParticleEmitterSystem.js +6 -0
- package/src/engine/graphics/render/layers/RenderLayer.d.ts +2 -0
- package/src/engine/graphics/render/layers/RenderLayer.d.ts.map +1 -1
- package/src/engine/graphics/render/layers/RenderLayer.js +14 -0
- package/src/engine/intelligence/mcts/MonteCarlo.js +1 -1
- package/src/engine/graphics/ecs/camera/FrustumProjector.d.ts +0 -14
- package/src/engine/graphics/ecs/camera/FrustumProjector.d.ts.map +0 -1
- package/src/engine/graphics/ecs/camera/FrustumProjector.js +0 -86
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import {
|
|
2
|
+
clipping_volume_matrix4_project
|
|
3
|
+
} from "../../../../../core/geom/3d/frustum/clipping_volume_matrix4_project.js";
|
|
4
|
+
import { hexahedron_from_aabb } from "../../../../../core/geom/3d/frustum/hexahedron_from_aabb.js";
|
|
5
|
+
|
|
6
|
+
const scratch_local_planes = new Float32Array(24);
|
|
7
|
+
const scratch_world_planes = new Float32Array(24);
|
|
8
|
+
const scratch_range = { near: 0, far: 0 };
|
|
9
|
+
|
|
10
|
+
// Half-extent of the z range used for the caster query. We want any object in
|
|
11
|
+
// the column above the receivers regardless of how far it sits along the light
|
|
12
|
+
// direction, so the query volume is effectively unbounded in z; the BVH walk's
|
|
13
|
+
// AABB-vs-frustum test is happy with a wide-but-finite range and avoids
|
|
14
|
+
// infinities propagating through plane math.
|
|
15
|
+
const CASTER_QUERY_HALF_RANGE = 1e7;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Push the shadow camera's near plane back toward the light to include any
|
|
19
|
+
* occluder whose shadow would fall within the camera's x/y bounds, even when
|
|
20
|
+
* the occluder itself sits outside the main view frustum.
|
|
21
|
+
*
|
|
22
|
+
* Without this step the textbook "fit shadow camera to view frustum" leaves
|
|
23
|
+
* the near plane at the closest receiver — a brick floating just above the
|
|
24
|
+
* view frustum gets clipped out of the shadow map and casts no shadow on the
|
|
25
|
+
* ground below.
|
|
26
|
+
*
|
|
27
|
+
* Algorithm:
|
|
28
|
+
* 1. Take the shadow camera's existing left/right/top/bottom (already fit
|
|
29
|
+
* to receivers) as the x/y extents of a light-local query box. Extend z
|
|
30
|
+
* to a wide range so any caster along the light direction is captured.
|
|
31
|
+
* 2. Transform the 6 box planes to world space via the shadow camera's
|
|
32
|
+
* matrixWorld.
|
|
33
|
+
* 3. Walk every render layer's BVH through `compute_depth_range` against
|
|
34
|
+
* this world-space volume, measured along the shadow camera's view
|
|
35
|
+
* direction.
|
|
36
|
+
* 4. If the closest depth found is smaller than the camera's current near,
|
|
37
|
+
* replace near with it.
|
|
38
|
+
*
|
|
39
|
+
* Far is intentionally left alone: casters behind the farthest receiver (in
|
|
40
|
+
* light direction) can't shadow anything in the view.
|
|
41
|
+
*
|
|
42
|
+
* @param {THREE.OrthographicCamera} shadow_camera
|
|
43
|
+
* @param {RenderLayerManager} layers
|
|
44
|
+
*/
|
|
45
|
+
export function extend_shadow_camera_near_for_casters(shadow_camera, layers) {
|
|
46
|
+
if (layers === null) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const x0 = shadow_camera.left;
|
|
51
|
+
const x1 = shadow_camera.right;
|
|
52
|
+
const y0 = shadow_camera.bottom;
|
|
53
|
+
const y1 = shadow_camera.top;
|
|
54
|
+
|
|
55
|
+
hexahedron_from_aabb(
|
|
56
|
+
scratch_local_planes, 0,
|
|
57
|
+
x0, y0, -CASTER_QUERY_HALF_RANGE,
|
|
58
|
+
x1, y1, CASTER_QUERY_HALF_RANGE
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
clipping_volume_matrix4_project(
|
|
62
|
+
scratch_world_planes, 0,
|
|
63
|
+
scratch_local_planes, 0,
|
|
64
|
+
6,
|
|
65
|
+
shadow_camera.matrixWorld.elements
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
// Depth plane: world-space, normal along the shadow camera's view direction
|
|
69
|
+
// (-Z column of matrixWorld), passing through the camera position. A point's
|
|
70
|
+
// distance to this plane equals its depth in front of the camera.
|
|
71
|
+
const m = shadow_camera.matrixWorld.elements;
|
|
72
|
+
const nx = -m[8];
|
|
73
|
+
const ny = -m[9];
|
|
74
|
+
const nz = -m[10];
|
|
75
|
+
const plane_constant = -(nx * m[12] + ny * m[13] + nz * m[14]);
|
|
76
|
+
|
|
77
|
+
scratch_range.near = Number.POSITIVE_INFINITY;
|
|
78
|
+
scratch_range.far = Number.NEGATIVE_INFINITY;
|
|
79
|
+
|
|
80
|
+
layers.traverse((layer) => {
|
|
81
|
+
if (!layer.state.visible) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const compute = layer.compute_depth_range;
|
|
86
|
+
|
|
87
|
+
if (compute === null) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
compute(scratch_range, scratch_world_planes, nx, ny, nz, plane_constant);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
if (isFinite(scratch_range.near) && scratch_range.near < shadow_camera.near) {
|
|
95
|
+
shadow_camera.near = scratch_range.near;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MeshSystem.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/ecs/mesh/MeshSystem.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MeshSystem.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/ecs/mesh/MeshSystem.js"],"names":[],"mappings":"AA8BA;IAsZI;;;;;;;OAOG;IACH,kCANW,IAAI,uCAEJ,OAAO,GACL,OAAO,CAQnB;IAlaD;;;;;OAKG;IACH,4BAwDC;IAjDG;;;;OAIG;IACH,iBAAsB;IAEtB,iDAAqC;IAErC,4DAEC;IAGD;;;OAGG;IACH,2BAAgC;IAEhC,sBAAwB;IAExB;;;OAGG;IACH,YAFU,MAAO,MAAO,aAAa,CAAC,CAAC,CAEnB;IAEpB,cAAwB;IAExB;;;OAGG;IACH,aAFU,cAAY,IAAI,CAEH;IAEvB;;;;OAIG;IACH,+BAAmC;IAEnC;;;;OAIG;IACH,qBAA6B;IAGjC;;;;;;OAMG;IACH,8BALW,MAAM,4DAGN,IAAI,QA+Bd;IAED,2CA4DC;IAED;;;;OAIG;IACH,gCAHoB,IAAI,QAAE,MAAM,+BA8C/B;IAED,4CAEC;IAED;;;;;OAKG;IACH,YAHW,IAAI,aADJ,SAAS,UAET,MAAM,QAkChB;IAED;;;;;OAKG;IACH,cAHW,IAAI,aADJ,SAAS,YAET,MAAM,QAmChB;IAED;;;;OAIG;IACH,gCAFW,IAAI,QA+Ed;IAED,6BAoBC;CAgBJ;uBAxbsB,wBAAwB;0BACrB,qCAAqC;iBAO/B,WAAW;4CAVC,uDAAuD;8BAJrE,iDAAiD;oBAE3D,kCAAkC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { BoxBufferGeometry, MeshLambertMaterial } from "three";
|
|
2
2
|
import { assert } from "../../../../core/assert.js";
|
|
3
3
|
import { BVH } from "../../../../core/bvh2/bvh3/BVH.js";
|
|
4
|
+
import { bvh_query_depth_range_in_frustum } from "../../../../core/bvh2/bvh3/query/bvh_query_depth_range_in_frustum.js";
|
|
4
5
|
import { SignalBinding } from "../../../../core/events/signal/SignalBinding.js";
|
|
5
6
|
|
|
6
7
|
import Vector3 from "../../../../core/geom/Vector3.js";
|
|
@@ -157,6 +158,11 @@ export class MeshSystem extends System {
|
|
|
157
158
|
}
|
|
158
159
|
)
|
|
159
160
|
|
|
161
|
+
const bvh = this.__bvh_binary;
|
|
162
|
+
this.renderLayer.compute_depth_range = (result, frustum, nx, ny, nz, c) => {
|
|
163
|
+
bvh_query_depth_range_in_frustum(result, bvh, frustum, nx, ny, nz, c);
|
|
164
|
+
};
|
|
165
|
+
|
|
160
166
|
const visibleSet = this.renderLayer.visibleSet;
|
|
161
167
|
|
|
162
168
|
visibleSet.onAdded.add(m => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShadedGeometrySystem.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ShadedGeometrySystem.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js"],"names":[],"mappings":"AA8DA;IACI;;;OAGG;IACH,4BAmEC;IAjEG,2DAA+C;IAE/C;;;;OAIG;IACH,iBAAsB;IAEtB;;;;OAIG;IACH,uBAA0B;IAE1B;;;;OAIG;IACH,wBAAgC;IAEhC;;;;OAIG;IACH,4BAAoC;IAEpC;;;;OAIG;IACH,kCAA0C;IAE1C;;;;OAIG;IACH,qBAA6B;IAI7B,0BAYE;IAEF,yBAIC;IAIL;;;OAGG;IACH,eAEC;IAED;;;OAGG;IACH,4BAFa,IAAI,MAAM,EAAC,MAAM,CAAC,CAI9B;IAED;;;;OAIG;IACH,+BAHW,MAAM,+CAsBhB;IAED;;;;OAIG;IACH,iCAHW,MAAM,GACL,OAAO,CAmBlB;IAED;;;;OAIG;IACH,4BASC;IAED;;;;OAIG;IACH,8BAMC;IAED,2CAqCC;IAED,4CAcC;IAED;;;;;OAKG;IACH,SAJW,cAAc,KACd,SAAS,UACT,MAAM,QAqBhB;IAED;;;;;OAKG;IACH,WAJW,cAAc,KACd,SAAS,UACT,MAAM,QAsBhB;IAED;;;;;;OAMG;IACH,4BALW,MAAM,EAAE,iBACR,MAAM,UACN,MAAM,EAAE,GAAC,UAAU,MAAM,CAAC,GACxB,MAAM,CAQlB;IAED;;;;;;;;;;;OAWG;IACH,kBAVW,MAAM,YACN,MAAM,YACN,MAAM,eACN,MAAM,eACN,MAAM,eACN,MAAM,uEAGJ;QAAC,MAAM,EAAC,MAAM,CAAC;QAAC,IAAI,EAAC,cAAc,CAAC;QAAC,OAAO,EAAE,aAAa,CAAA;KAAC,EAAE,CA8D1E;IAGD;;;;;;;;;;;;OAYG;IACH,wBAXW,aAAa,YACb,MAAM,YACN,MAAM,YACN,MAAM,eACN,MAAM,eACN,MAAM,eACN,MAAM,uEAGJ;QAAC,MAAM,EAAC,MAAM,CAAC;QAAC,IAAI,EAAC,cAAc,CAAA;KAAC,GAAC,SAAS,CAmF1D;CACJ;uBA7fsB,wBAAwB;0BACrB,qCAAqC;+BAGhC,qBAAqB;iBARnC,uCAAuC;oBAZpC,mCAAmC;2BAQ5B,yCAAyC;8BAEtC,2CAA2C"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { mat4 } from "gl-matrix";
|
|
2
2
|
import { assert } from "../../../../core/assert.js";
|
|
3
3
|
import { BVH } from "../../../../core/bvh2/bvh3/BVH.js";
|
|
4
|
+
import { bvh_query_depth_range_in_frustum } from "../../../../core/bvh2/bvh3/query/bvh_query_depth_range_in_frustum.js";
|
|
4
5
|
import { bvh_query_leaves_generic } from "../../../../core/bvh2/bvh3/query/bvh_query_leaves_generic.js";
|
|
5
6
|
import {
|
|
6
7
|
bvh_query_user_data_overlaps_frustum
|
|
@@ -256,6 +257,11 @@ export class ShadedGeometrySystem extends System {
|
|
|
256
257
|
return ctx.collect(destination, destination_offset, graphics.renderer, view, this.__bvh_binary, ecd);
|
|
257
258
|
});
|
|
258
259
|
|
|
260
|
+
const bvh = this.__bvh_binary;
|
|
261
|
+
this.__render_layer.compute_depth_range = (result, frustum, nx, ny, nz, c) => {
|
|
262
|
+
bvh_query_depth_range_in_frustum(result, bvh, frustum, nx, ny, nz, c);
|
|
263
|
+
};
|
|
264
|
+
|
|
259
265
|
this.__optimization_task.state.set(TaskState.INITIAL);
|
|
260
266
|
engine.executor.run(this.__optimization_task);
|
|
261
267
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Trail2DSystem.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/ecs/trail2d/Trail2DSystem.js"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"Trail2DSystem.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/ecs/trail2d/Trail2DSystem.js"],"names":[],"mappings":";AA0BA;IAkCI;;;OAGG;IACH,4BA4BC;IAjED,oDAAoC;IAEpC,+DAEE;IAEF;;;OAGG;IACH,WAFU,4BAA4B,CAES;IAE/C;;;;OAIG;IACH,wBAAiC;IAGjC;;;;OAIG;IACH,oBAAgB;IAEhB;;;OAGG;IACH,YAAgB;IAcZ;;;;OAIG;IACH,iBAAsB;IAEtB;;;OAGG;IACH,UAFU,cAAc,CAEO;IAE/B;;;OAGG;IACH,aAFU,cAAY,IAAI,CAEH;IAK3B,2CAmBC;IAED,4CAIC;IAED;;;;;OAKG;IACH,sBAoDC;IAED;;;;;OAKG;IACH,YAHW,OAAO,aADP,SAAS,YAET,MAAM,QAahB;IAED;;;;;OAKG;IACH,kBAJW,OAAO,aACP,SAAS,UACT,MAAM,QAShB;IAED;;;;OAIG;IACH,yBAHW,OAAO,aACP,SAAS,QAoCnB;IAED,6BAWC;CACJ;uBApQsB,wBAAwB;0BACrB,qCAAqC;oBAY3C,cAAc;4CAdU,uDAAuD;6CAYtD,yDAAyD;+BARvE,yBAAyB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { assert } from "../../../../core/assert.js";
|
|
2
2
|
import { BVH } from "../../../../core/bvh2/bvh3/BVH.js";
|
|
3
|
+
import { bvh_query_depth_range_in_frustum } from "../../../../core/bvh2/bvh3/query/bvh_query_depth_range_in_frustum.js";
|
|
3
4
|
import Vector3 from '../../../../core/geom/Vector3.js';
|
|
4
5
|
import { clamp } from "../../../../core/math/clamp.js";
|
|
5
6
|
import { max2 } from "../../../../core/math/max2.js";
|
|
@@ -104,6 +105,11 @@ class Trail2DSystem extends System {
|
|
|
104
105
|
}
|
|
105
106
|
);
|
|
106
107
|
|
|
108
|
+
const bvh = this.bvh;
|
|
109
|
+
this.renderLayer.compute_depth_range = (result, frustum, nx, ny, nz, c) => {
|
|
110
|
+
bvh_query_depth_range_in_frustum(result, bvh, frustum, nx, ny, nz, c);
|
|
111
|
+
};
|
|
112
|
+
|
|
107
113
|
this.__ribbon_plugin = await this.__engine.plugins.acquire(RibbonXPlugin);
|
|
108
114
|
}
|
|
109
115
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WaterSystem.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/ecs/water/WaterSystem.js"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"WaterSystem.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/ecs/water/WaterSystem.js"],"names":[],"mappings":";AAaA;IAyBI;;;;OAIG;IACH,sCAYC;IAzCD,+BAAuB;IAEvB;;;OAGG;IACH,cAFU,GAAG,CAEG;IAGhB,cAAY;IAEZ;;;OAGG;IACH,aAFU,KAAK,EAAE,CAEA;IAEjB;;;;OAIG;IACH,qBAAiB;IAWb,+BAA8B;IAE9B;;;OAGG;IACH,aAFU,cAAY,IAAI,CAEH;IAK3B,4CAMC;IAED,2CAiEC;IAED;;;;OAIG;IACH,gBAHW,KAAK,UACL,MAAM,QAsDhB;IAED;;;;OAIG;IACH,kBAHW,KAAK,UACL,MAAM,QAgBhB;IAED,2BAgCC;IAED;;;;;OAKG;IACH,0BAUC;IAED,6BAcC;CACJ;;;;uBApRsB,wBAAwB;kBAM7B,YAAY;oBARV,mCAAmC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { BackSide, PlaneBufferGeometry } from 'three';
|
|
2
2
|
import { assert } from "../../../../core/assert.js";
|
|
3
3
|
import { BVH } from "../../../../core/bvh2/bvh3/BVH.js";
|
|
4
|
+
import { bvh_query_depth_range_in_frustum } from "../../../../core/bvh2/bvh3/query/bvh_query_depth_range_in_frustum.js";
|
|
4
5
|
import { System } from '../../../ecs/System.js';
|
|
5
6
|
import { obtainTerrain } from "../../../ecs/terrain/util/obtainTerrain.js";
|
|
6
7
|
import { make_bvh_visibility_builder } from "../../render/make_bvh_visibility_builder.js";
|
|
@@ -90,6 +91,11 @@ class WaterSystem extends System {
|
|
|
90
91
|
}
|
|
91
92
|
)
|
|
92
93
|
|
|
94
|
+
const bvh = this.bvh;
|
|
95
|
+
this.renderLayer.compute_depth_range = (result, frustum, nx, ny, nz, c) => {
|
|
96
|
+
bvh_query_depth_range_in_frustum(result, bvh, frustum, nx, ny, nz, c);
|
|
97
|
+
};
|
|
98
|
+
|
|
93
99
|
|
|
94
100
|
const self = this;
|
|
95
101
|
|
|
@@ -39,14 +39,11 @@ async function main(engine) {
|
|
|
39
39
|
enableWater: false,
|
|
40
40
|
cameraFieldOfView: 45,
|
|
41
41
|
showFps: false,
|
|
42
|
-
enableLights:
|
|
42
|
+
enableLights: true,
|
|
43
|
+
enableShadows: true,
|
|
44
|
+
cameraAutoClip: true,
|
|
43
45
|
});
|
|
44
46
|
|
|
45
|
-
await EngineHarness.buildLights({
|
|
46
|
-
engine,
|
|
47
|
-
sunIntensity: 0,
|
|
48
|
-
ambientIntensity: 1
|
|
49
|
-
});
|
|
50
47
|
|
|
51
48
|
const ecd = engine.entityManager.dataset;
|
|
52
49
|
|
|
@@ -75,7 +72,7 @@ async function main(engine) {
|
|
|
75
72
|
// console.profile('bake');
|
|
76
73
|
const id = baker.bake({
|
|
77
74
|
objects,
|
|
78
|
-
frames:
|
|
75
|
+
frames: 32,
|
|
79
76
|
resolution: 1024,
|
|
80
77
|
type: ImpostorCaptureType.FullSphere
|
|
81
78
|
});
|
|
@@ -86,7 +83,7 @@ async function main(engine) {
|
|
|
86
83
|
const ctrl = makeImpostorAtlasPreview({
|
|
87
84
|
impostor: id,
|
|
88
85
|
renderer,
|
|
89
|
-
mode: '
|
|
86
|
+
mode: 'albedo'
|
|
90
87
|
});
|
|
91
88
|
|
|
92
89
|
ctrl.scale.setScalar(1);
|
|
@@ -119,8 +116,8 @@ async function main(engine) {
|
|
|
119
116
|
|
|
120
117
|
const sg_mesh = SGMesh.fromURL(path);
|
|
121
118
|
|
|
122
|
-
sg_mesh.castShadow =
|
|
123
|
-
sg_mesh.receiveShadow =
|
|
119
|
+
sg_mesh.castShadow = true;
|
|
120
|
+
sg_mesh.receiveShadow = true;
|
|
124
121
|
|
|
125
122
|
const entity_true_mesh = new Entity();
|
|
126
123
|
entity_true_mesh
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImpostorShaderV0.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/graphics/impostors/octahedral/shader/ImpostorShaderV0.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ImpostorShaderV0.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/graphics/impostors/octahedral/shader/ImpostorShaderV0.js"],"names":[],"mappings":"AAiZA;IACI,cAmEC;IAHG,4CAAyB;CAIhC;kCA9cM,OAAO"}
|
|
@@ -22,25 +22,42 @@ const shader_vx = `
|
|
|
22
22
|
// tangent-space parallax computation in the fragment shader.
|
|
23
23
|
out vec3 vViewPos;
|
|
24
24
|
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
//
|
|
25
|
+
// The 4 atlas frames at the corners of the current grid cell are chosen
|
|
26
|
+
// once per-impostor and forwarded as flat varyings so every fragment
|
|
27
|
+
// samples the same set (without this, a perspective camera could flip
|
|
28
|
+
// the chosen frames across the card and produce visible seams).
|
|
29
|
+
//
|
|
30
|
+
// We use bilinear interpolation over a full 2x2 cell, not a triangle
|
|
31
|
+
// interpolation over 3 corners. Triangle interpolation has a
|
|
32
|
+
// C1-discontinuous "diagonal switch" where one of the three contributing
|
|
33
|
+
// frames swaps between (gridFloor+(1,0)) and (gridFloor+(0,1)); even
|
|
34
|
+
// though the swap happens at zero weight (so the result is C0), the
|
|
35
|
+
// weight DERIVATIVE jumps, which the eye perceives as a snap inside the
|
|
36
|
+
// cell. Bilinear has no such switch — all 4 corners always contribute
|
|
37
|
+
// with weights that are smooth products of fract(grid).
|
|
30
38
|
flat out vec2 vGridFloor;
|
|
31
|
-
flat out vec4 vWeights;
|
|
39
|
+
flat out vec4 vWeights; // (w00, w10, w01, w11)
|
|
32
40
|
|
|
33
41
|
// Card's TBN basis in view space. The card is oriented so its NORMAL
|
|
34
|
-
// points along the weighted blend of the
|
|
35
|
-
// directions, and TANGENT/BINORMAL line up with the bake
|
|
36
|
-
// right/up
|
|
37
|
-
//
|
|
38
|
-
// direction) usable as a tangent-space height map. flat because the
|
|
39
|
-
// basis is the same for every vertex of the card.
|
|
42
|
+
// points along the weighted blend of the 4 nearest baked view
|
|
43
|
+
// directions, and TANGENT/BINORMAL line up with the *blended* bake
|
|
44
|
+
// camera's right/up. Used by the fragment shader to transform the
|
|
45
|
+
// view-space view-dir into the card's tangent frame.
|
|
40
46
|
flat out vec3 vTangent;
|
|
41
47
|
flat out vec3 vBinormal;
|
|
42
48
|
flat out vec3 vNormal;
|
|
43
49
|
|
|
50
|
+
// Per-frame card-UV -> texture-UV rotation matrices, one per cell
|
|
51
|
+
// corner. Each frame was baked with its own camera right/up (from
|
|
52
|
+
// three.js Camera.lookAt with up=(0,1,0)); near the octahedral pole
|
|
53
|
+
// those right-axes can swing 90° or more between adjacent frames.
|
|
54
|
+
// These matrices rotate the sample-UV into each frame's bake-camera
|
|
55
|
+
// basis so the four corners line up consistently when blended.
|
|
56
|
+
flat out vec4 vFrameXform00;
|
|
57
|
+
flat out vec4 vFrameXform10;
|
|
58
|
+
flat out vec4 vFrameXform01;
|
|
59
|
+
flat out vec4 vFrameXform11;
|
|
60
|
+
|
|
44
61
|
uniform mat4 modelViewMatrix;
|
|
45
62
|
uniform mat4 projectionMatrix;
|
|
46
63
|
|
|
@@ -130,19 +147,41 @@ const shader_vx = `
|
|
|
130
147
|
return normalize(GridToVector(f));
|
|
131
148
|
}
|
|
132
149
|
|
|
133
|
-
|
|
150
|
+
// Build the 2x2 matrix that maps card-centred UV (vUv - 0.5) into the
|
|
151
|
+
// texture-centred UV of a single baked frame. The matrix is just the
|
|
152
|
+
// (tangent_OS, binormal_OS) basis expressed in the frame's own
|
|
153
|
+
// (bake_right, bake_up) basis — i.e. how a step along the card's local
|
|
154
|
+
// axes shows up in the texture the frame was rendered into.
|
|
155
|
+
//
|
|
156
|
+
// bake_right/bake_up follow three.js Camera.lookAt with up=(0,1,0).
|
|
157
|
+
// We mirror its polar nudge so our shader basis matches what the
|
|
158
|
+
// baker actually used when D_frame is parallel to up.
|
|
159
|
+
vec4 ComputeFrameXform(vec3 D_frame, vec3 tangent_OS, vec3 binormal_OS)
|
|
160
|
+
{
|
|
161
|
+
vec3 D = abs(D_frame.y) > 0.99999
|
|
162
|
+
? normalize(D_frame + vec3(0.0, 0.0, 0.0001))
|
|
163
|
+
: D_frame;
|
|
164
|
+
vec3 bake_right = normalize(cross(vec3(0.0, 1.0, 0.0), D));
|
|
165
|
+
vec3 bake_up = cross(D, bake_right);
|
|
166
|
+
return vec4(
|
|
167
|
+
dot(tangent_OS, bake_right),
|
|
168
|
+
dot(binormal_OS, bake_right),
|
|
169
|
+
dot(tangent_OS, bake_up),
|
|
170
|
+
dot(binormal_OS, bake_up)
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Bilinear weights over the 4 corners of the current cell, in the
|
|
175
|
+
// order (w00, w10, w01, w11) matching gridFloor + (0,0)/(1,0)/(0,1)/(1,1).
|
|
176
|
+
vec4 BilinearWeights(vec2 frac_uv)
|
|
134
177
|
{
|
|
135
178
|
vec2 omuv = vec2(1.0) - frac_uv;
|
|
136
|
-
vec4
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
res.z = min(frac_uv.x, frac_uv.y);
|
|
143
|
-
// triangle-half mask: 1 in the lower-right half, 0 in the upper-left
|
|
144
|
-
res.w = clamp(ceil(frac_uv.x - frac_uv.y), 0.0, 1.0);
|
|
145
|
-
return res;
|
|
179
|
+
return vec4(
|
|
180
|
+
omuv.x * omuv.y, // w00
|
|
181
|
+
frac_uv.x * omuv.y, // w10
|
|
182
|
+
omuv.x * frac_uv.y, // w01
|
|
183
|
+
frac_uv.x * frac_uv.y // w11
|
|
184
|
+
);
|
|
146
185
|
}
|
|
147
186
|
|
|
148
187
|
void main() {
|
|
@@ -159,25 +198,28 @@ const shader_vx = `
|
|
|
159
198
|
vec2 framesMinusOne = vec2(uFrames - 1.0);
|
|
160
199
|
vec2 octahedral_uv = clamp(VectorToGrid(pivotToCameraRay) * 0.5 + 0.5, 0.0, 1.0);
|
|
161
200
|
vec2 grid = octahedral_uv * framesMinusOne;
|
|
162
|
-
|
|
163
|
-
|
|
201
|
+
// Clamp gridFloor so the +1 corners never reference past the last
|
|
202
|
+
// valid frame index when grid is at the upper edge.
|
|
203
|
+
vec2 gridFloor = min(floor(grid), framesMinusOne - 1.0);
|
|
204
|
+
vec4 weights = BilinearWeights(grid - gridFloor);
|
|
164
205
|
|
|
165
206
|
vGridFloor = gridFloor;
|
|
166
207
|
vWeights = weights;
|
|
167
208
|
|
|
168
|
-
// 2. Decode each of the
|
|
169
|
-
// bake-time view direction, then blend with the
|
|
209
|
+
// 2. Decode each of the 4 cell-corner frame indices back into its
|
|
210
|
+
// bake-time view direction, then blend with the bilinear weights.
|
|
170
211
|
// projectedRay is the "effective" baked view direction the card
|
|
171
212
|
// is showing — the direction the depth and colour textures we're
|
|
172
213
|
// blending were captured along.
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
vec3
|
|
177
|
-
vec3 ray1 = FrameToRay(frame1, framesMinusOne);
|
|
178
|
-
vec3 ray2 = FrameToRay(frame2, framesMinusOne);
|
|
214
|
+
vec3 ray00 = FrameToRay(gridFloor + vec2(0.0, 0.0), framesMinusOne);
|
|
215
|
+
vec3 ray10 = FrameToRay(gridFloor + vec2(1.0, 0.0), framesMinusOne);
|
|
216
|
+
vec3 ray01 = FrameToRay(gridFloor + vec2(0.0, 1.0), framesMinusOne);
|
|
217
|
+
vec3 ray11 = FrameToRay(gridFloor + vec2(1.0, 1.0), framesMinusOne);
|
|
179
218
|
vec3 projectedRay = normalize(
|
|
180
|
-
|
|
219
|
+
ray00 * weights.x +
|
|
220
|
+
ray10 * weights.y +
|
|
221
|
+
ray01 * weights.z +
|
|
222
|
+
ray11 * weights.w
|
|
181
223
|
);
|
|
182
224
|
|
|
183
225
|
// 3. Build the card's TBN in object-local space.
|
|
@@ -224,6 +266,13 @@ const shader_vx = `
|
|
|
224
266
|
vTangent = normalize(m3 * tangent_OS);
|
|
225
267
|
vBinormal = normalize(m3 * binormal_OS);
|
|
226
268
|
vNormal = normalize(m3 * normal_OS);
|
|
269
|
+
|
|
270
|
+
// 6. Per-frame UV rotation matrices. ComputeFrameXform handles the
|
|
271
|
+
// polar-singularity nudge in three.js's lookAt internally.
|
|
272
|
+
vFrameXform00 = ComputeFrameXform(ray00, tangent_OS, binormal_OS);
|
|
273
|
+
vFrameXform10 = ComputeFrameXform(ray10, tangent_OS, binormal_OS);
|
|
274
|
+
vFrameXform01 = ComputeFrameXform(ray01, tangent_OS, binormal_OS);
|
|
275
|
+
vFrameXform11 = ComputeFrameXform(ray11, tangent_OS, binormal_OS);
|
|
227
276
|
}
|
|
228
277
|
`;
|
|
229
278
|
const shader_fg = `
|
|
@@ -233,20 +282,25 @@ const shader_fg = `
|
|
|
233
282
|
in vec2 vUv;
|
|
234
283
|
in vec3 vViewPos;
|
|
235
284
|
|
|
236
|
-
//
|
|
237
|
-
// vertex shader. flat = no interpolation
|
|
238
|
-
// values and samples the same 3 atlas frames.
|
|
285
|
+
// Cell base + bilinear weights for the 4 corners (w00, w10, w01, w11),
|
|
286
|
+
// computed per-impostor in the vertex shader. flat = no interpolation.
|
|
239
287
|
flat in vec2 vGridFloor;
|
|
240
288
|
flat in vec4 vWeights;
|
|
241
289
|
|
|
242
|
-
// Card's TBN in view space
|
|
243
|
-
//
|
|
244
|
-
//
|
|
245
|
-
// before doing parallax.
|
|
290
|
+
// Card's TBN in view space (perpendicular to the effective bake
|
|
291
|
+
// direction). Used to express the view direction in the card's tangent
|
|
292
|
+
// frame for parallax.
|
|
246
293
|
flat in vec3 vTangent;
|
|
247
294
|
flat in vec3 vBinormal;
|
|
248
295
|
flat in vec3 vNormal;
|
|
249
296
|
|
|
297
|
+
// Per-frame 2x2 rotation matrices (a, b, c, d) that map card-centred
|
|
298
|
+
// UV into each frame's bake-camera basis. Each cell corner has its own.
|
|
299
|
+
flat in vec4 vFrameXform00;
|
|
300
|
+
flat in vec4 vFrameXform10;
|
|
301
|
+
flat in vec4 vFrameXform01;
|
|
302
|
+
flat in vec4 vFrameXform11;
|
|
303
|
+
|
|
250
304
|
out vec4 color_out;
|
|
251
305
|
|
|
252
306
|
uniform sampler2D tBase;
|
|
@@ -254,25 +308,45 @@ const shader_fg = `
|
|
|
254
308
|
uniform float uFrames;
|
|
255
309
|
uniform float uDepthScale;
|
|
256
310
|
|
|
257
|
-
//
|
|
258
|
-
//
|
|
259
|
-
//
|
|
260
|
-
|
|
311
|
+
// Apply a per-frame 2x2 rotation matrix to a card UV, rotating around
|
|
312
|
+
// the texture centre (0.5, 0.5). xform = (a, b, c, d) packs row-major
|
|
313
|
+
// [a b ; c d].
|
|
314
|
+
vec2 apply_frame_xform(vec2 card_uv, vec4 xform)
|
|
261
315
|
{
|
|
316
|
+
vec2 c = card_uv - 0.5;
|
|
317
|
+
return vec2(
|
|
318
|
+
xform.x * c.x + xform.y * c.y,
|
|
319
|
+
xform.z * c.x + xform.w * c.y
|
|
320
|
+
) + 0.5;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Sample the same card-UV from the 4 cell-corner atlas frames, applying
|
|
324
|
+
// each frame's own UV rotation so the textures land in a consistent
|
|
325
|
+
// orientation, then blend with the bilinear weights. Used for both
|
|
326
|
+
// depth and colour.
|
|
327
|
+
vec4 blend_4_frames(
|
|
328
|
+
sampler2D tex, vec2 card_uv,
|
|
329
|
+
vec2 gridFloor, vec4 w,
|
|
330
|
+
vec4 x00, vec4 x10, vec4 x01, vec4 x11
|
|
331
|
+
) {
|
|
262
332
|
vec2 frame_size = vec2(1.0 / uFrames);
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
333
|
+
// Clamp inside the unit square AFTER the per-frame rotation: at
|
|
334
|
+
// sharp angles the rotation can push a corner UV outside [0,1] and
|
|
335
|
+
// bleed into the neighbouring atlas tile (which is a completely
|
|
336
|
+
// different bake direction). Clamping keeps the sample inside the
|
|
337
|
+
// frame it's supposed to belong to.
|
|
338
|
+
vec2 uv00 = clamp(apply_frame_xform(card_uv, x00), 0.0, 1.0);
|
|
339
|
+
vec2 uv10 = clamp(apply_frame_xform(card_uv, x10), 0.0, 1.0);
|
|
340
|
+
vec2 uv01 = clamp(apply_frame_xform(card_uv, x01), 0.0, 1.0);
|
|
341
|
+
vec2 uv11 = clamp(apply_frame_xform(card_uv, x11), 0.0, 1.0);
|
|
342
|
+
vec4 s00 = texture(tex, (gridFloor + vec2(0.0, 0.0) + uv00) * frame_size);
|
|
343
|
+
vec4 s10 = texture(tex, (gridFloor + vec2(1.0, 0.0) + uv10) * frame_size);
|
|
344
|
+
vec4 s01 = texture(tex, (gridFloor + vec2(0.0, 1.0) + uv01) * frame_size);
|
|
345
|
+
vec4 s11 = texture(tex, (gridFloor + vec2(1.0, 1.0) + uv11) * frame_size);
|
|
346
|
+
return s00 * w.x + s10 * w.y + s01 * w.z + s11 * w.w;
|
|
267
347
|
}
|
|
268
348
|
|
|
269
349
|
void main() {
|
|
270
|
-
// 3 nearest frames — flat from vertex shader, identical for every
|
|
271
|
-
// fragment of this impostor card.
|
|
272
|
-
vec2 frame0 = vGridFloor;
|
|
273
|
-
vec2 frame1 = vGridFloor + mix(vec2(0.0, 1.0), vec2(1.0, 0.0), vWeights.w);
|
|
274
|
-
vec2 frame2 = vGridFloor + vec2(1.0, 1.0);
|
|
275
|
-
|
|
276
350
|
// View direction in the card's tangent space. The card is oriented
|
|
277
351
|
// perpendicular to the effective bake direction, not view-aligned,
|
|
278
352
|
// so we project the view-space view-dir onto the (T, B, N) basis we
|
|
@@ -299,7 +373,11 @@ const shader_fg = `
|
|
|
299
373
|
// where V is the view direction in tangent space and h is the
|
|
300
374
|
// surface height above the card plane.
|
|
301
375
|
vec2 base_uv = vUv;
|
|
302
|
-
float depth =
|
|
376
|
+
float depth = blend_4_frames(
|
|
377
|
+
tGeometry, base_uv,
|
|
378
|
+
vGridFloor, vWeights,
|
|
379
|
+
vFrameXform00, vFrameXform10, vFrameXform01, vFrameXform11
|
|
380
|
+
).a;
|
|
303
381
|
base_uv += (view_dir.xy / view_dir.z) * (depth - 0.5) * uDepthScale;
|
|
304
382
|
|
|
305
383
|
// Keep the parallax-shifted sample inside the current frame's tile.
|
|
@@ -307,7 +385,11 @@ const shader_fg = `
|
|
|
307
385
|
// neighbouring atlas frame (a completely different bake direction).
|
|
308
386
|
base_uv = clamp(base_uv, 0.0, 1.0);
|
|
309
387
|
|
|
310
|
-
vec4 texel_color =
|
|
388
|
+
vec4 texel_color = blend_4_frames(
|
|
389
|
+
tBase, base_uv,
|
|
390
|
+
vGridFloor, vWeights,
|
|
391
|
+
vFrameXform00, vFrameXform10, vFrameXform01, vFrameXform11
|
|
392
|
+
);
|
|
311
393
|
|
|
312
394
|
if (texel_color.a <= 0.5) {
|
|
313
395
|
discard;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImpostorShaderWireframeV0.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/graphics/impostors/octahedral/shader/ImpostorShaderWireframeV0.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ImpostorShaderWireframeV0.d.ts","sourceRoot":"","sources":["../../../../../../../src/engine/graphics/impostors/octahedral/shader/ImpostorShaderWireframeV0.js"],"names":[],"mappings":"AA6JA;IACI,cA2DC;IAHG,4CAAyB;CAIhC;kCAlNM,OAAO"}
|