@navaramap/three 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/fontWorker-DaqfXmZf.js +2 -0
- package/dist/assets/fontWorker-DaqfXmZf.js.map +1 -0
- package/dist/assets/index-Dydat1h1.js +25 -0
- package/dist/assets/index-Dydat1h1.js.map +1 -0
- package/dist/assets/{navara_wasm_font_worker_bg-DympKYVX.wasm → navara_wasm_font_worker_bg-XvE_oYPr.wasm} +0 -0
- package/dist/assets/{navara_wasm_worker_bg-Bx_l45cW.wasm → navara_wasm_worker_bg-Dg9fnGLP.wasm} +0 -0
- package/dist/index.d.ts +140 -4
- package/dist/index.js +5385 -5022
- package/dist/index.js.map +1 -1
- package/dist/index.umd.cjs +164 -86
- package/dist/index.umd.cjs.map +1 -1
- package/package.json +12 -12
- package/src/declutter/DeclutterManager.test.ts +65 -0
- package/src/declutter/DeclutterManager.ts +60 -1
- package/src/declutter/types.ts +17 -0
- package/src/event/feature.ts +45 -2
- package/src/event/worker.ts +18 -0
- package/src/index.ts +51 -2
- package/src/layers/effect/TransparentPassEffectDesc.ts +1 -1
- package/src/mesh/nvLineGeometry.test.ts +88 -0
- package/src/mesh/nvLineGeometry.ts +148 -0
- package/src/mesh/polygonOutline.ts +126 -42
- package/src/mesh/sdfText/batchedSdfText.test.ts +377 -0
- package/src/mesh/sdfText/batchedSdfText.ts +192 -21
- package/src/mesh/sdfText/labelVisibility.test.ts +106 -0
- package/src/mesh/sdfText/labelVisibility.ts +131 -0
- package/src/mesh/sdfText/pendingSettlement.test.ts +151 -0
- package/src/mesh/sdfText/pendingSettlement.ts +68 -0
- package/src/pick/pickTerrain.ts +22 -18
- package/src/terrain/sampleTerrainMostDetailed.test.ts +236 -0
- package/src/terrain/sampleTerrainMostDetailed.ts +447 -0
- package/dist/assets/fontWorker-JfTCpd38.js +0 -2
- package/dist/assets/fontWorker-JfTCpd38.js.map +0 -1
- package/dist/assets/index-B3U_DvcP.js +0 -25
- package/dist/assets/index-B3U_DvcP.js.map +0 -1
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Box3,
|
|
3
|
+
InstancedInterleavedBuffer,
|
|
4
|
+
InterleavedBufferAttribute,
|
|
5
|
+
Sphere,
|
|
6
|
+
Vector3,
|
|
7
|
+
} from "three";
|
|
8
|
+
import { LineGeometry, LineSegmentsGeometry } from "three-stdlib";
|
|
9
|
+
|
|
10
|
+
export class NvLineGeometry extends LineGeometry {
|
|
11
|
+
setPositions(
|
|
12
|
+
array: Float32Array,
|
|
13
|
+
skipIdx: Uint32Array = new Uint32Array(),
|
|
14
|
+
): this {
|
|
15
|
+
const positions: number[] = [];
|
|
16
|
+
const skipSet = new Set(skipIdx);
|
|
17
|
+
|
|
18
|
+
for (let i = 0; i < array.length - 3; i += 3) {
|
|
19
|
+
const currentIndex = i / 3;
|
|
20
|
+
if (skipSet.has(currentIndex)) {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// segment start
|
|
25
|
+
positions.push(array[i], array[i + 1], array[i + 2]);
|
|
26
|
+
// segment end
|
|
27
|
+
positions.push(array[i + 3], array[i + 4], array[i + 5]);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const points = new Float32Array(positions);
|
|
31
|
+
|
|
32
|
+
// This function is used to override LineGeometry's setPositions,
|
|
33
|
+
// so we don't call super.setPositions.
|
|
34
|
+
LineSegmentsGeometry.prototype.setPositions.call(this, points);
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Attach RTE high/low positions as per-segment instanced attributes.
|
|
40
|
+
*
|
|
41
|
+
* Mirrors the segment expansion (and skip handling) of `setPositions` and
|
|
42
|
+
* the interleaved layout of `LineSegmentsGeometry.setPositions`
|
|
43
|
+
* (stride 6: start xyz at offset 0, end xyz at offset 3). The RTE shader
|
|
44
|
+
* reads only these attributes, so callers skip `setPositions` entirely —
|
|
45
|
+
* no unused `instanceStart`/`instanceEnd` buffer is uploaded to the GPU.
|
|
46
|
+
* Because `LineSegmentsGeometry.computeBoundingBox/Sphere` read
|
|
47
|
+
* `instanceStart`/`instanceEnd`, the bounds are computed here instead,
|
|
48
|
+
* from the reconstructed absolute (high + low) positions.
|
|
49
|
+
*/
|
|
50
|
+
setPositionsHighLow(
|
|
51
|
+
high: Float32Array,
|
|
52
|
+
low: Float32Array,
|
|
53
|
+
skipIdx: Uint32Array = new Uint32Array(),
|
|
54
|
+
): this {
|
|
55
|
+
const highSegments: number[] = [];
|
|
56
|
+
const lowSegments: number[] = [];
|
|
57
|
+
const skipSet = new Set(skipIdx);
|
|
58
|
+
|
|
59
|
+
const box = new Box3();
|
|
60
|
+
const point = new Vector3();
|
|
61
|
+
|
|
62
|
+
for (let i = 0; i < high.length - 3; i += 3) {
|
|
63
|
+
const currentIndex = i / 3;
|
|
64
|
+
if (skipSet.has(currentIndex)) {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// segment start + end
|
|
69
|
+
highSegments.push(
|
|
70
|
+
high[i],
|
|
71
|
+
high[i + 1],
|
|
72
|
+
high[i + 2],
|
|
73
|
+
high[i + 3],
|
|
74
|
+
high[i + 4],
|
|
75
|
+
high[i + 5],
|
|
76
|
+
);
|
|
77
|
+
lowSegments.push(
|
|
78
|
+
low[i],
|
|
79
|
+
low[i + 1],
|
|
80
|
+
low[i + 2],
|
|
81
|
+
low[i + 3],
|
|
82
|
+
low[i + 4],
|
|
83
|
+
low[i + 5],
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
box.expandByPoint(
|
|
87
|
+
point.set(
|
|
88
|
+
high[i] + low[i],
|
|
89
|
+
high[i + 1] + low[i + 1],
|
|
90
|
+
high[i + 2] + low[i + 2],
|
|
91
|
+
),
|
|
92
|
+
);
|
|
93
|
+
box.expandByPoint(
|
|
94
|
+
point.set(
|
|
95
|
+
high[i + 3] + low[i + 3],
|
|
96
|
+
high[i + 4] + low[i + 4],
|
|
97
|
+
high[i + 5] + low[i + 5],
|
|
98
|
+
),
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const highBuffer = new InstancedInterleavedBuffer(
|
|
103
|
+
new Float32Array(highSegments),
|
|
104
|
+
6,
|
|
105
|
+
1,
|
|
106
|
+
);
|
|
107
|
+
const lowBuffer = new InstancedInterleavedBuffer(
|
|
108
|
+
new Float32Array(lowSegments),
|
|
109
|
+
6,
|
|
110
|
+
1,
|
|
111
|
+
);
|
|
112
|
+
this.setAttribute(
|
|
113
|
+
"instanceStartHigh",
|
|
114
|
+
new InterleavedBufferAttribute(highBuffer, 3, 0),
|
|
115
|
+
);
|
|
116
|
+
this.setAttribute(
|
|
117
|
+
"instanceEndHigh",
|
|
118
|
+
new InterleavedBufferAttribute(highBuffer, 3, 3),
|
|
119
|
+
);
|
|
120
|
+
this.setAttribute(
|
|
121
|
+
"instanceStartLow",
|
|
122
|
+
new InterleavedBufferAttribute(lowBuffer, 3, 0),
|
|
123
|
+
);
|
|
124
|
+
this.setAttribute(
|
|
125
|
+
"instanceEndLow",
|
|
126
|
+
new InterleavedBufferAttribute(lowBuffer, 3, 3),
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
// Exact-radius sphere (same behavior as LineSegmentsGeometry's own
|
|
130
|
+
// computeBoundingSphere, which cannot run without instanceStart/End).
|
|
131
|
+
this.boundingBox = box;
|
|
132
|
+
const sphere = this.boundingSphere ?? new Sphere();
|
|
133
|
+
const center = box.getCenter(sphere.center);
|
|
134
|
+
let maxRadiusSq = 0;
|
|
135
|
+
for (let i = 0; i < highSegments.length; i += 3) {
|
|
136
|
+
point.set(
|
|
137
|
+
highSegments[i] + lowSegments[i],
|
|
138
|
+
highSegments[i + 1] + lowSegments[i + 1],
|
|
139
|
+
highSegments[i + 2] + lowSegments[i + 2],
|
|
140
|
+
);
|
|
141
|
+
maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(point));
|
|
142
|
+
}
|
|
143
|
+
sphere.radius = Math.sqrt(maxRadiusSq);
|
|
144
|
+
this.boundingSphere = sphere;
|
|
145
|
+
|
|
146
|
+
return this;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
@@ -2,19 +2,25 @@ import {
|
|
|
2
2
|
PolygonMesh as NavaraPolygonMesh,
|
|
3
3
|
PolygonMaterial,
|
|
4
4
|
} from "@navaramap/engine";
|
|
5
|
+
import { RTE_ONE_UNIFORM } from "@navaramap/three-api";
|
|
5
6
|
import BatchTextureParsVertex from "@shaders/glsl/chunks/batch_texture_pars_vertex.glsl";
|
|
6
7
|
import BranchFreeTernary from "@shaders/glsl/chunks/branchFreeTernary.glsl";
|
|
7
8
|
import ExtrudedHeightParsVertex from "@shaders/glsl/chunks/extruded_height_pars_vertex.glsl";
|
|
8
9
|
import ExtrudedHeightVertex from "@shaders/glsl/chunks/extruded_height_vertex.glsl";
|
|
9
10
|
import HeightParsVertex from "@shaders/glsl/chunks/height_pars_vertex.glsl";
|
|
10
11
|
import HeightVertex from "@shaders/glsl/chunks/height_vertex.glsl";
|
|
11
|
-
import { Color, type DataTexture, InstancedBufferAttribute } from "three";
|
|
12
12
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
Color,
|
|
14
|
+
type DataTexture,
|
|
15
|
+
InstancedBufferAttribute,
|
|
16
|
+
type Intersection,
|
|
17
|
+
Matrix4,
|
|
18
|
+
type Object3D,
|
|
19
|
+
type Raycaster,
|
|
20
|
+
Vector3,
|
|
21
|
+
Vector4,
|
|
22
|
+
} from "three";
|
|
23
|
+
import { Line2, LineGeometry, LineMaterial } from "three-stdlib";
|
|
18
24
|
|
|
19
25
|
import type { EventContext } from "../event/context";
|
|
20
26
|
import { setupMaterialForMRT } from "../material";
|
|
@@ -23,39 +29,14 @@ import { createReplacer } from "../utils/replacer";
|
|
|
23
29
|
import { POLYGON_BATCH_TEXTURE_ROWS } from "./batchedFeature";
|
|
24
30
|
import { initBatchedMaterial } from "./batchTexture";
|
|
25
31
|
import type { FeatureMesh } from "./featureMesh";
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
setPositions(
|
|
29
|
-
array: Float32Array,
|
|
30
|
-
skipIdx: Uint32Array = new Uint32Array(),
|
|
31
|
-
): this {
|
|
32
|
-
const positions: number[] = [];
|
|
33
|
-
const skipSet = new Set(skipIdx);
|
|
34
|
-
|
|
35
|
-
for (let i = 0; i < array.length - 3; i += 3) {
|
|
36
|
-
const currentIndex = i / 3;
|
|
37
|
-
if (skipSet.has(currentIndex)) {
|
|
38
|
-
continue;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// segment start
|
|
42
|
-
positions.push(array[i], array[i + 1], array[i + 2]);
|
|
43
|
-
// segment end
|
|
44
|
-
positions.push(array[i + 3], array[i + 4], array[i + 5]);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const points = new Float32Array(positions);
|
|
48
|
-
|
|
49
|
-
// This function is used to override LineGeometry's setPositions,
|
|
50
|
-
// so we don't call super.setPositions.
|
|
51
|
-
LineSegmentsGeometry.prototype.setPositions.call(this, points);
|
|
52
|
-
return this;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
32
|
+
import { NvLineGeometry } from "./nvLineGeometry";
|
|
33
|
+
import { setupRTECallback } from "./rtcRteHelper";
|
|
55
34
|
|
|
56
35
|
export class PolygonOutlineMesh extends Line2 implements FeatureMesh {
|
|
57
36
|
readonly ctx: EventContext;
|
|
58
37
|
private resizeEventUnsubscribe?: () => void;
|
|
38
|
+
/** True when the geometry carries RTE high/low positions (GeoJSON path). */
|
|
39
|
+
private useRTE = false;
|
|
59
40
|
|
|
60
41
|
constructor(ctx: EventContext, mesh: NavaraPolygonMesh) {
|
|
61
42
|
super(new NvLineGeometry(), new LineMaterial());
|
|
@@ -64,6 +45,13 @@ export class PolygonOutlineMesh extends Line2 implements FeatureMesh {
|
|
|
64
45
|
this.initMaterial(mesh);
|
|
65
46
|
}
|
|
66
47
|
|
|
48
|
+
raycast(raycaster: Raycaster, intersects: Intersection[]): void {
|
|
49
|
+
// RTE geometry carries no instanceStart/End attributes, which
|
|
50
|
+
// LineSegments2.raycast requires — picking is GPU-based, so skip.
|
|
51
|
+
if (this.useRTE) return;
|
|
52
|
+
super.raycast(raycaster, intersects);
|
|
53
|
+
}
|
|
54
|
+
|
|
67
55
|
private initGeometry(mesh: NavaraPolygonMesh) {
|
|
68
56
|
const g = mesh.outline_geometry;
|
|
69
57
|
if (!g || !g.position) {
|
|
@@ -74,6 +62,15 @@ export class PolygonOutlineMesh extends Line2 implements FeatureMesh {
|
|
|
74
62
|
return;
|
|
75
63
|
}
|
|
76
64
|
|
|
65
|
+
const position3dHigh =
|
|
66
|
+
g.position_3d_high && g.position_3d_high.size > 0
|
|
67
|
+
? this.ctx.buf.removeF32(g.position_3d_high.data)
|
|
68
|
+
: undefined;
|
|
69
|
+
const position3dLow =
|
|
70
|
+
g.position_3d_low && g.position_3d_low.size > 0
|
|
71
|
+
? this.ctx.buf.removeF32(g.position_3d_low.data)
|
|
72
|
+
: undefined;
|
|
73
|
+
|
|
77
74
|
const scale_normal_and_cap = g.scale_normal_and_cap
|
|
78
75
|
? this.ctx.buf.removeF32(g.scale_normal_and_cap.data)
|
|
79
76
|
: undefined;
|
|
@@ -88,7 +85,17 @@ export class PolygonOutlineMesh extends Line2 implements FeatureMesh {
|
|
|
88
85
|
|
|
89
86
|
// Convert position buffer to Line2 format
|
|
90
87
|
const lineGeometry = this.geometry as NvLineGeometry;
|
|
91
|
-
|
|
88
|
+
|
|
89
|
+
if (position3dHigh && position3dLow) {
|
|
90
|
+
// RTE mode: upload only the high/low pairs — the RTE shader never
|
|
91
|
+
// reads instanceStart/End, so calling setPositions would leave an
|
|
92
|
+
// unused buffer resident on the GPU. setPositionsHighLow also sets
|
|
93
|
+
// the bounds that setPositions would have computed.
|
|
94
|
+
lineGeometry.setPositionsHighLow(position3dHigh, position3dLow, skipIdx);
|
|
95
|
+
this.useRTE = true;
|
|
96
|
+
} else {
|
|
97
|
+
lineGeometry.setPositions(position, skipIdx);
|
|
98
|
+
}
|
|
92
99
|
|
|
93
100
|
// Add scale_normal_and_cap attributes if available
|
|
94
101
|
if (g.scale_normal_and_cap && scale_normal_and_cap) {
|
|
@@ -192,6 +199,47 @@ export class PolygonOutlineMesh extends Line2 implements FeatureMesh {
|
|
|
192
199
|
batchLength: 0,
|
|
193
200
|
});
|
|
194
201
|
|
|
202
|
+
if (this.useRTE) {
|
|
203
|
+
material.userData.defines ??= {};
|
|
204
|
+
material.userData.defines.USE_RTE = true;
|
|
205
|
+
material.userData.modelViewMatrixRTE = { value: new Matrix4() };
|
|
206
|
+
material.userData.uCameraPositionHigh = { value: new Vector3() };
|
|
207
|
+
material.userData.uCameraPositionLow = { value: new Vector3() };
|
|
208
|
+
|
|
209
|
+
// The outline mesh sits directly in the scene with an identity
|
|
210
|
+
// matrixWorld (positions are absolute ECEF), so pass identity matrices
|
|
211
|
+
// like PolylineMesh does.
|
|
212
|
+
const rteCallback = setupRTECallback(
|
|
213
|
+
this,
|
|
214
|
+
(modelViewMatrixRTE, cameraPositionHigh, cameraPositionLow) => {
|
|
215
|
+
material.userData.modelViewMatrixRTE.value.copy(modelViewMatrixRTE);
|
|
216
|
+
material.userData.uCameraPositionHigh.value.copy(cameraPositionHigh);
|
|
217
|
+
material.userData.uCameraPositionLow.value.copy(cameraPositionLow);
|
|
218
|
+
},
|
|
219
|
+
new Matrix4(),
|
|
220
|
+
new Matrix4(),
|
|
221
|
+
);
|
|
222
|
+
// LineSegments2.prototype.onBeforeRender refreshes the `resolution`
|
|
223
|
+
// uniform from the viewport every frame; assigning our own callback
|
|
224
|
+
// shadows it, so replicate that update here — otherwise resolution
|
|
225
|
+
// stays at the (1,1) default and line widths blow up to viewport size.
|
|
226
|
+
const updateRTE: Object3D["onBeforeRender"] = rteCallback;
|
|
227
|
+
const viewport = new Vector4();
|
|
228
|
+
this.onBeforeRender = (renderer, scene, camera, geometry, mat, group) => {
|
|
229
|
+
renderer.getViewport(viewport);
|
|
230
|
+
material.resolution.set(viewport.z, viewport.w);
|
|
231
|
+
updateRTE(renderer, scene, camera, geometry, mat, group);
|
|
232
|
+
};
|
|
233
|
+
this.onBeforeShadow = rteCallback;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// The defines are stamped in onBeforeCompile (not via material.defines),
|
|
237
|
+
// so they must be part of the program cache key — otherwise RTE and
|
|
238
|
+
// non-RTE outlines (or different batch-define sets) would share one
|
|
239
|
+
// compiled program.
|
|
240
|
+
material.customProgramCacheKey = () =>
|
|
241
|
+
`nvr-polygon-outline:${JSON.stringify(material.userData.defines ?? {})}`;
|
|
242
|
+
|
|
195
243
|
material.onBeforeCompile = (shader) => {
|
|
196
244
|
// Merge user-defined defines (batch texture, color/show, height, etc.)
|
|
197
245
|
shader.defines ??= {};
|
|
@@ -206,6 +254,17 @@ export class PolygonOutlineMesh extends Line2 implements FeatureMesh {
|
|
|
206
254
|
shader.uniforms.batchDataTexture = material.userData.batchDataTexture;
|
|
207
255
|
}
|
|
208
256
|
|
|
257
|
+
// RTE uniforms (updated per-frame via setupRTECallback)
|
|
258
|
+
if (material.userData.defines?.USE_RTE) {
|
|
259
|
+
shader.uniforms.modelViewMatrixRTE =
|
|
260
|
+
material.userData.modelViewMatrixRTE;
|
|
261
|
+
shader.uniforms.u_cameraPositionHigh =
|
|
262
|
+
material.userData.uCameraPositionHigh;
|
|
263
|
+
shader.uniforms.u_cameraPositionLow =
|
|
264
|
+
material.userData.uCameraPositionLow;
|
|
265
|
+
shader.uniforms.u_rteOne = RTE_ONE_UNIFORM;
|
|
266
|
+
}
|
|
267
|
+
|
|
209
268
|
shader.vertexShader = createReplacer(shader.vertexShader)
|
|
210
269
|
.replace(
|
|
211
270
|
"attribute vec3 instanceEnd;",
|
|
@@ -215,6 +274,16 @@ export class PolygonOutlineMesh extends Line2 implements FeatureMesh {
|
|
|
215
274
|
attribute vec4 scaleNormalAndCapEnd;
|
|
216
275
|
varying float nvr_vShow;
|
|
217
276
|
uniform vec2 uMinMaxHeight;
|
|
277
|
+
#ifdef USE_RTE
|
|
278
|
+
attribute vec3 instanceStartHigh;
|
|
279
|
+
attribute vec3 instanceStartLow;
|
|
280
|
+
attribute vec3 instanceEndHigh;
|
|
281
|
+
attribute vec3 instanceEndLow;
|
|
282
|
+
uniform vec3 u_cameraPositionHigh;
|
|
283
|
+
uniform vec3 u_cameraPositionLow;
|
|
284
|
+
uniform float u_rteOne;
|
|
285
|
+
uniform mat4 modelViewMatrixRTE;
|
|
286
|
+
#endif
|
|
218
287
|
${ExtrudedHeightParsVertex}
|
|
219
288
|
${HeightParsVertex}
|
|
220
289
|
${BranchFreeTernary}
|
|
@@ -243,25 +312,40 @@ export class PolygonOutlineMesh extends Line2 implements FeatureMesh {
|
|
|
243
312
|
#endif
|
|
244
313
|
#endif
|
|
245
314
|
|
|
246
|
-
vec3
|
|
247
|
-
adjustedInstanceStart.xyz += scaleNormalAndCapStart.xyz * nvr_branchFreeTernary(
|
|
315
|
+
vec3 nvr_heightOffsetStart = scaleNormalAndCapStart.xyz * nvr_branchFreeTernary(
|
|
248
316
|
scaleNormalAndCapStart.w == 0.0,
|
|
249
317
|
uMinMaxHeight.x + addHeight,
|
|
250
318
|
uMinMaxHeight.y + addExtrudedHeight
|
|
251
319
|
);
|
|
252
|
-
|
|
320
|
+
#ifdef USE_RTE
|
|
321
|
+
// Reconstruct the camera-relative position from high/low pairs to
|
|
322
|
+
// avoid f32 jitter at globe scale. u_rteOne (always 1.0) blocks
|
|
323
|
+
// fast-math reassociation of the high-difference term.
|
|
324
|
+
vec3 nvr_startHighDiff = (instanceStartHigh - u_cameraPositionHigh) * u_rteOne;
|
|
325
|
+
vec3 nvr_startLowDiff = instanceStartLow - u_cameraPositionLow;
|
|
326
|
+
vec4 start = modelViewMatrixRTE * vec4( nvr_startHighDiff + nvr_startLowDiff + nvr_heightOffsetStart, 1.0 );
|
|
327
|
+
#else
|
|
328
|
+
vec3 adjustedInstanceStart = instanceStart + nvr_heightOffsetStart;
|
|
329
|
+
vec4 start = modelViewMatrix * vec4( adjustedInstanceStart, 1.0 );
|
|
330
|
+
#endif
|
|
253
331
|
`,
|
|
254
332
|
)
|
|
255
333
|
.replace(
|
|
256
334
|
"vec4 end = modelViewMatrix * vec4( instanceEnd, 1.0 );",
|
|
257
335
|
`
|
|
258
|
-
vec3
|
|
259
|
-
adjustedInstanceEnd.xyz += scaleNormalAndCapEnd.xyz * nvr_branchFreeTernary(
|
|
336
|
+
vec3 nvr_heightOffsetEnd = scaleNormalAndCapEnd.xyz * nvr_branchFreeTernary(
|
|
260
337
|
scaleNormalAndCapEnd.w == 0.0,
|
|
261
338
|
uMinMaxHeight.x + addHeight,
|
|
262
339
|
uMinMaxHeight.y + addExtrudedHeight
|
|
263
340
|
);
|
|
264
|
-
|
|
341
|
+
#ifdef USE_RTE
|
|
342
|
+
vec3 nvr_endHighDiff = (instanceEndHigh - u_cameraPositionHigh) * u_rteOne;
|
|
343
|
+
vec3 nvr_endLowDiff = instanceEndLow - u_cameraPositionLow;
|
|
344
|
+
vec4 end = modelViewMatrixRTE * vec4( nvr_endHighDiff + nvr_endLowDiff + nvr_heightOffsetEnd, 1.0 );
|
|
345
|
+
#else
|
|
346
|
+
vec3 adjustedInstanceEnd = instanceEnd + nvr_heightOffsetEnd;
|
|
347
|
+
vec4 end = modelViewMatrix * vec4( adjustedInstanceEnd, 1.0 );
|
|
348
|
+
#endif
|
|
265
349
|
`,
|
|
266
350
|
).source;
|
|
267
351
|
|