mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-15 15:52:21 +00:00
Draw Navara world meshes in the overlay pass after tone mapping
Meshes now go through the same overlay as sprites and lines, so their colours are the ones asked for without undoing the view's exposure. The contract suite no longer carries the mesh colour check as a known failure on Navara.
This commit is contained in:
1 parent
a90407d547
commit
28f3030c31
7 files changed
+129
-107
No files matched your search
@@ -538,9 +538,10 @@ Cesium draws a synchronous Primitive with a flat material, no back-face
|
|||||||
culling and no depth writes. Colour, image and visibility changes retain the
|
culling and no depth writes. Colour, image and visibility changes retain the
|
||||||
primitive; geometry, pick-id and depth-test changes replace it. The engine
|
primitive; geometry, pick-id and depth-test changes replace it. The engine
|
||||||
requests frames while the primitive or its image is preparing. Navara draws
|
requests frames while the primitive or its image is preparing. Navara draws
|
||||||
local coordinates relative to a double-precision world origin in its
|
local coordinates relative to a double-precision world origin in the shared
|
||||||
transparent scene pass after tone mapping, with scene depth and triangle
|
overlay pass after tone mapping and anti-aliasing, the pass that draws sprites
|
||||||
picking. Their authored colours are blended in display space.
|
and lines, with scene depth and triangle picking. Their authored colours are
|
||||||
|
blended in display space.
|
||||||
Both engines own geometry, material and texture disposal. The fake engine
|
Both engines own geometry, material and texture disposal. The fake engine
|
||||||
keeps the same state and tests triangle intersections for picks.
|
keeps the same state and tests triangle intersections for picks.
|
||||||
|
|
||||||
|
|||||||
@@ -237,12 +237,6 @@ async function runOn(browser, kind) {
|
|||||||
outcome.push({ name, skipped: owner[1] });
|
outcome.push({ name, skipped: owner[1] });
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const knownFailure =
|
|
||||||
engine.kind === 'navara' &&
|
|
||||||
name ===
|
|
||||||
'meshes.createMesh: a single colour draws as asked within 10 per channel'
|
|
||||||
? 'Meshes are drawn before tone mapping'
|
|
||||||
: null;
|
|
||||||
try {
|
try {
|
||||||
await run();
|
await run();
|
||||||
outcome.push({ name, ok: true });
|
outcome.push({ name, ok: true });
|
||||||
@@ -250,10 +244,6 @@ async function runOn(browser, kind) {
|
|||||||
outcome.push({
|
outcome.push({
|
||||||
name,
|
name,
|
||||||
ok: false,
|
ok: false,
|
||||||
...(knownFailure &&
|
|
||||||
String(error?.message).startsWith(
|
|
||||||
'mesh colour within 10 per channel',
|
|
||||||
) && { knownFailure }),
|
|
||||||
error: String(error?.message ?? error),
|
error: String(error?.message ?? error),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ export async function createNavaraGlobe({ container, search, hd = false }) {
|
|||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
lines: createNavaraLines(view, { overlay }),
|
lines: createNavaraLines(view, { overlay }),
|
||||||
meshes: (parts) => createNavaraMeshes(view, { MeshDesc, ...parts }),
|
meshes: (parts) => createNavaraMeshes(view, { overlay, ...parts }),
|
||||||
ground: createNavaraGround(view, {
|
ground: createNavaraGround(view, {
|
||||||
createPass: createGroundPass,
|
createPass: createGroundPass,
|
||||||
pulseField: (options) =>
|
pulseField: (options) =>
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import {
|
|||||||
BufferAttribute,
|
BufferAttribute,
|
||||||
BufferGeometry,
|
BufferGeometry,
|
||||||
CanvasTexture,
|
CanvasTexture,
|
||||||
Color,
|
|
||||||
DoubleSide,
|
DoubleSide,
|
||||||
Group,
|
Group,
|
||||||
Mesh,
|
Mesh,
|
||||||
@@ -14,39 +13,11 @@ import {
|
|||||||
} from 'three';
|
} from 'three';
|
||||||
import { createMeshRegistry } from '../meshes.js';
|
import { createMeshRegistry } from '../meshes.js';
|
||||||
import { cartesian3 } from '../../geo/index.js';
|
import { cartesian3 } from '../../geo/index.js';
|
||||||
import { attachSceneDepth, createSceneDepthTest } from './sceneDepth.js';
|
import { createSceneDepthTest } from './sceneDepth.js';
|
||||||
|
|
||||||
const KIND = 'gevWorldMesh';
|
|
||||||
const NEAR_SURFACE_M = 2;
|
const NEAR_SURFACE_M = 2;
|
||||||
const registered = new WeakSet();
|
|
||||||
|
|
||||||
export function createNavaraMeshes(view, { MeshDesc, camera, picker }) {
|
export function createNavaraMeshes(view, { overlay, camera, picker }) {
|
||||||
if (!registered.has(view)) {
|
|
||||||
view.registerMesh(
|
|
||||||
KIND,
|
|
||||||
class extends MeshDesc {
|
|
||||||
constructor(owner, ctx, config) {
|
|
||||||
super(owner, ctx, config);
|
|
||||||
this.resource = config[KIND];
|
|
||||||
}
|
|
||||||
// Transparent, drawn after the effects: the colours are the ones
|
|
||||||
// asked for (as Cesium draws them), not tone-mapped with the look.
|
|
||||||
// The scene-depth test hides a mesh behind terrain, tiles and Earth.
|
|
||||||
getPassKey() {
|
|
||||||
return 'transparent';
|
|
||||||
}
|
|
||||||
createMesh() {
|
|
||||||
attachSceneDepth(this.resource.group, this.ctx);
|
|
||||||
return this.resource.group;
|
|
||||||
}
|
|
||||||
onDestroy() {
|
|
||||||
this.resource.dispose();
|
|
||||||
super.onDestroy();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
registered.add(view);
|
|
||||||
}
|
|
||||||
const registry = createMeshRegistry(
|
const registry = createMeshRegistry(
|
||||||
(state) => {
|
(state) => {
|
||||||
const group = new Group();
|
const group = new Group();
|
||||||
@@ -60,18 +31,14 @@ export function createNavaraMeshes(view, { MeshDesc, camera, picker }) {
|
|||||||
const mesh = new Mesh(geometry, material);
|
const mesh = new Mesh(geometry, material);
|
||||||
const sceneDepth = createSceneDepthTest();
|
const sceneDepth = createSceneDepthTest();
|
||||||
sceneDepth.material(material);
|
sceneDepth.material(material);
|
||||||
sceneDepth.object(group);
|
|
||||||
sceneDepth.object(mesh);
|
sceneDepth.object(mesh);
|
||||||
let depthFree = false;
|
let depthFree = false;
|
||||||
const pigment = new Color();
|
|
||||||
const bindDepth = mesh.onBeforeRender;
|
const bindDepth = mesh.onBeforeRender;
|
||||||
mesh.onBeforeRender = function onBeforeRender(...args) {
|
mesh.onBeforeRender = function onBeforeRender(...args) {
|
||||||
|
// The overlay context can arrive after the mesh is created.
|
||||||
|
sceneDepth.attach(overlay.ctx);
|
||||||
bindDepth.apply(this, args);
|
bindDepth.apply(this, args);
|
||||||
if (depthFree) sceneDepth.uniforms.uGevSceneDepthOn.value = 0;
|
if (depthFree) sceneDepth.uniforms.uGevSceneDepthOn.value = 0;
|
||||||
// The pass still scales by the view's exposure: undo it.
|
|
||||||
material.color
|
|
||||||
.copy(pigment)
|
|
||||||
.multiplyScalar(1 / Math.max(1, view.toneMappingExposure ?? 1));
|
|
||||||
};
|
};
|
||||||
group.frustumCulled = mesh.frustumCulled = false;
|
group.frustumCulled = mesh.frustumCulled = false;
|
||||||
group.add(mesh);
|
group.add(mesh);
|
||||||
@@ -116,17 +83,15 @@ export function createNavaraMeshes(view, { MeshDesc, camera, picker }) {
|
|||||||
material.needsUpdate = true;
|
material.needsUpdate = true;
|
||||||
} else if (texture && !texture.isVideoTexture && 'image' in patch)
|
} else if (texture && !texture.isVideoTexture && 'image' in patch)
|
||||||
texture.needsUpdate = true;
|
texture.needsUpdate = true;
|
||||||
pigment.setRGB(...next.color.slice(0, 3), SRGBColorSpace);
|
material.color.setRGB(...next.color.slice(0, 3), SRGBColorSpace);
|
||||||
material.color.copy(pigment);
|
|
||||||
material.opacity = next.color[3];
|
material.opacity = next.color[3];
|
||||||
depthFree = next.depthTest === 'always';
|
depthFree = next.depthTest === 'always';
|
||||||
material.depthTest = !depthFree;
|
material.depthTest = !depthFree;
|
||||||
group.visible = next.show;
|
group.visible = next.show;
|
||||||
}
|
}
|
||||||
let holder;
|
|
||||||
try {
|
try {
|
||||||
update(state, state);
|
update(state, state);
|
||||||
holder = view.addMesh({ [KIND]: { group, dispose } });
|
overlay.add(group);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispose();
|
dispose();
|
||||||
throw error;
|
throw error;
|
||||||
@@ -137,7 +102,7 @@ export function createNavaraMeshes(view, { MeshDesc, camera, picker }) {
|
|||||||
update,
|
update,
|
||||||
destroy() {
|
destroy() {
|
||||||
try {
|
try {
|
||||||
holder.delete();
|
overlay.remove(group);
|
||||||
} finally {
|
} finally {
|
||||||
dispose();
|
dispose();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
import assert from 'node:assert/strict';
|
import assert from 'node:assert/strict';
|
||||||
import test from 'node:test';
|
import test from 'node:test';
|
||||||
import { Group, Vector3 } from 'three';
|
import {
|
||||||
|
Color,
|
||||||
|
Group,
|
||||||
|
RGBADepthPacking,
|
||||||
|
ShaderLib,
|
||||||
|
SRGBColorSpace,
|
||||||
|
Vector3,
|
||||||
|
} from 'three';
|
||||||
import * as Cesium from 'cesium';
|
import * as Cesium from 'cesium';
|
||||||
import { createNavaraMeshes } from './meshes.js';
|
import { createNavaraMeshes } from './meshes.js';
|
||||||
import { createCctvMeshes } from '../../layers/cctv/render/meshes.js';
|
import { createCctvMeshes } from '../../layers/cctv/render/meshes.js';
|
||||||
@@ -8,40 +15,30 @@ import { viewshedColors } from '../../data/cctvViewshed.js';
|
|||||||
|
|
||||||
function harness() {
|
function harness() {
|
||||||
const scene = new Group();
|
const scene = new Group();
|
||||||
const kinds = new Map();
|
|
||||||
const handles = new Set();
|
const handles = new Set();
|
||||||
let requests = 0;
|
let requests = 0;
|
||||||
let fail = false;
|
let fail = false;
|
||||||
let failedGeometryDisposals = 0;
|
let failedGeometryDisposals = 0;
|
||||||
class MeshDesc {
|
|
||||||
onDestroy() {}
|
|
||||||
}
|
|
||||||
const view = {
|
const view = {
|
||||||
forceUpdate: () => requests++,
|
forceUpdate: () => requests++,
|
||||||
registerMesh: (kind, desc) => kinds.set(kind, desc),
|
toneMappingExposure: 1,
|
||||||
addMesh(config) {
|
};
|
||||||
|
const overlay = {
|
||||||
|
ctx: null,
|
||||||
|
add(object) {
|
||||||
if (fail) {
|
if (fail) {
|
||||||
config.gevWorldMesh.group.children[0].geometry.addEventListener(
|
object.children[0].geometry.addEventListener(
|
||||||
'dispose',
|
'dispose',
|
||||||
() => failedGeometryDisposals++,
|
() => failedGeometryDisposals++,
|
||||||
);
|
);
|
||||||
throw new Error('descriptor failed');
|
throw new Error('overlay failed');
|
||||||
}
|
}
|
||||||
const kind = Object.keys(config)[0];
|
|
||||||
const desc = new (kinds.get(kind))(view, {}, config);
|
|
||||||
// After the effects, depth-tested against the scene's packed depth.
|
|
||||||
assert.equal(desc.getPassKey(), 'transparent');
|
|
||||||
const object = desc.createMesh();
|
|
||||||
scene.add(object);
|
scene.add(object);
|
||||||
const handle = {
|
handles.add(object);
|
||||||
delete() {
|
},
|
||||||
handles.delete(handle);
|
remove(object) {
|
||||||
scene.remove(object);
|
scene.remove(object);
|
||||||
desc.onDestroy();
|
handles.delete(object);
|
||||||
},
|
|
||||||
};
|
|
||||||
handles.add(handle);
|
|
||||||
return handle;
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const pickers = new Set();
|
const pickers = new Set();
|
||||||
@@ -57,7 +54,7 @@ function harness() {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
const port = createNavaraMeshes(view, {
|
const port = createNavaraMeshes(view, {
|
||||||
MeshDesc,
|
overlay,
|
||||||
camera: engine.camera,
|
camera: engine.camera,
|
||||||
picker: engine.picker,
|
picker: engine.picker,
|
||||||
});
|
});
|
||||||
@@ -66,6 +63,8 @@ function harness() {
|
|||||||
return {
|
return {
|
||||||
owner,
|
owner,
|
||||||
port,
|
port,
|
||||||
|
view,
|
||||||
|
overlay,
|
||||||
drawn: () => scene.children.at(-1)?.children[0],
|
drawn: () => scene.children.at(-1)?.children[0],
|
||||||
engine,
|
engine,
|
||||||
scene,
|
scene,
|
||||||
@@ -82,6 +81,83 @@ const positions = { capCenter: { x: 6378137, y: 1234, z: 5678 } };
|
|||||||
const identity = { x: 0, y: 0, z: 0, w: 1 };
|
const identity = { x: 0, y: 0, z: 0, w: 1 };
|
||||||
const canvas = () => ({ width: 8, height: 8, tagName: 'CANVAS' });
|
const canvas = () => ({ width: 8, height: 8, tagName: 'CANVAS' });
|
||||||
|
|
||||||
|
test('solid and textured overlay meshes keep authored colours through landscape exposure changes', () => {
|
||||||
|
const h = harness();
|
||||||
|
for (const image of [null, canvas()]) {
|
||||||
|
const handle = h.engine.meshes.createMesh({
|
||||||
|
id: image ? 'textured' : 'solid',
|
||||||
|
positions: [6378137, 0, 0, 6378137, 10, 0, 6378137, 0, 10],
|
||||||
|
indices: [0, 1, 2],
|
||||||
|
uv: [0, 0, 1, 0, 0, 1],
|
||||||
|
image,
|
||||||
|
});
|
||||||
|
const mesh = h.drawn();
|
||||||
|
assert.equal(mesh.parent.parent, h.scene);
|
||||||
|
assert.equal(mesh.material.toneMapped, false);
|
||||||
|
assert.equal(mesh.material.transparent, true);
|
||||||
|
assert.equal(mesh.material.depthWrite, false);
|
||||||
|
if (image) assert.equal(mesh.material.map.colorSpace, SRGBColorSpace);
|
||||||
|
for (const color of [
|
||||||
|
[0, 1, 0, 1],
|
||||||
|
[0.25, 0.5, 0.75, 0.4],
|
||||||
|
]) {
|
||||||
|
handle.update({ color });
|
||||||
|
const expected = new Color().setRGB(...color.slice(0, 3), SRGBColorSpace);
|
||||||
|
for (const exposure of [1, 10, 1]) {
|
||||||
|
h.view.toneMappingExposure = exposure;
|
||||||
|
mesh.onBeforeRender({});
|
||||||
|
assert.deepEqual(mesh.material.color, expected);
|
||||||
|
assert.equal(mesh.material.opacity, color[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handle.destroy();
|
||||||
|
assert.equal(h.scene.children.length, 0);
|
||||||
|
}
|
||||||
|
h.port.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('overlay meshes bind late and replaced scene depth and honour depth-test updates', () => {
|
||||||
|
const h = harness();
|
||||||
|
const plane = h.owner.createPlane(
|
||||||
|
'depth',
|
||||||
|
h.owner.createMaterial(canvas()),
|
||||||
|
shape,
|
||||||
|
positions,
|
||||||
|
identity,
|
||||||
|
);
|
||||||
|
const mesh = h.drawn();
|
||||||
|
const shader = {
|
||||||
|
uniforms: {},
|
||||||
|
fragmentShader: ShaderLib.basic.fragmentShader,
|
||||||
|
};
|
||||||
|
mesh.material.onBeforeCompile(shader, null);
|
||||||
|
assert.match(shader.fragmentShader, /packedDepthOccluded/);
|
||||||
|
const renderer = { getRenderTarget: () => ({ width: 640, height: 360 }) };
|
||||||
|
const { tGevSceneDepth, uGevSceneDepthOn, uGevTargetSize } = shader.uniforms;
|
||||||
|
mesh.onBeforeRender(renderer);
|
||||||
|
assert.equal(uGevSceneDepthOn.value, 0);
|
||||||
|
const mrt = { depthBuffer: {}, depthBufferPacking: RGBADepthPacking };
|
||||||
|
h.overlay.ctx = { findEffect: (key) => (key === 'mrt' ? mrt : null) };
|
||||||
|
mesh.onBeforeRender(renderer);
|
||||||
|
assert.equal(tGevSceneDepth.value, mrt.depthBuffer);
|
||||||
|
assert.equal(uGevSceneDepthOn.value, 1);
|
||||||
|
assert.deepEqual(uGevTargetSize.value.toArray(), [640, 360]);
|
||||||
|
plane.mesh.update({ depthTest: 'always' });
|
||||||
|
mesh.onBeforeRender(renderer);
|
||||||
|
assert.equal(uGevSceneDepthOn.value, 0);
|
||||||
|
assert.equal(mesh.material.depthTest, false);
|
||||||
|
plane.mesh.update({ depthTest: 'normal' });
|
||||||
|
mrt.depthBuffer = {};
|
||||||
|
mesh.onBeforeRender({ getDrawingBufferSize: (size) => size.set(1280, 720) });
|
||||||
|
assert.equal(tGevSceneDepth.value, mrt.depthBuffer);
|
||||||
|
assert.equal(uGevSceneDepthOn.value, 1);
|
||||||
|
assert.equal(mesh.material.depthTest, true);
|
||||||
|
assert.deepEqual(uGevTargetSize.value.toArray(), [1280, 720]);
|
||||||
|
h.owner.destroy();
|
||||||
|
h.port.destroy();
|
||||||
|
assert.equal(h.scene.children.length, 0);
|
||||||
|
});
|
||||||
|
|
||||||
test('Navara CCTV plane preserves native rotated geometry, UVs and metre precision', (t) => {
|
test('Navara CCTV plane preserves native rotated geometry, UVs and metre precision', (t) => {
|
||||||
const h = harness();
|
const h = harness();
|
||||||
t.after(() => {
|
t.after(() => {
|
||||||
@@ -213,7 +289,7 @@ test('world meshes release replaced images and video callbacks exactly once', ()
|
|||||||
assert.equal(finalDisposed, 1);
|
assert.equal(finalDisposed, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('world mesh descriptor failure releases geometry and rejects later creates after teardown', () => {
|
test('world mesh overlay failure releases geometry and rejects later creates after teardown', () => {
|
||||||
const h = harness();
|
const h = harness();
|
||||||
h.fail();
|
h.fail();
|
||||||
assert.throws(
|
assert.throws(
|
||||||
@@ -225,7 +301,7 @@ test('world mesh descriptor failure releases geometry and rejects later creates
|
|||||||
positions,
|
positions,
|
||||||
identity,
|
identity,
|
||||||
),
|
),
|
||||||
/descriptor failed/,
|
/overlay failed/,
|
||||||
);
|
);
|
||||||
assert.equal(h.failedGeometryDisposals(), 1);
|
assert.equal(h.failedGeometryDisposals(), 1);
|
||||||
assert.equal(h.handles.size, 0);
|
assert.equal(h.handles.size, 0);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// gev's screen overlays on Navara: sprites, points and lines (engine.movers
|
// gev's screen overlays on Navara: sprites, points, lines and world meshes
|
||||||
// and engine.lines) drawn into the frame after Navara's tone mapping,
|
// (engine.movers, engine.lines and engine.meshes) drawn after tone mapping,
|
||||||
// anti-aliasing (SMAA/FXAA) and the gev sharpening, so their
|
// anti-aliasing (SMAA/FXAA) and the gev sharpening, so their
|
||||||
// colours are the colours asked for (as Cesium draws billboards and
|
// colours are the colours asked for (as Cesium draws billboards and
|
||||||
// polylines), not tone-mapped or graded with the look. A public Navara
|
// polylines), not tone-mapped or graded with the look. A public Navara
|
||||||
|
|||||||
@@ -78,34 +78,25 @@ test('the test binds the MRT pass packed depth before each draw, and only packed
|
|||||||
assert.equal(depth.uniforms.tGevSceneDepth.value, null);
|
assert.equal(depth.uniforms.tGevSceneDepth.value, null);
|
||||||
});
|
});
|
||||||
|
|
||||||
/** A Navara view that builds each descriptor as the SDK does. */
|
/** An overlay that exposes the scene's packed depth to its meshes. */
|
||||||
function fakeView() {
|
function fakeView() {
|
||||||
const kinds = new Map();
|
|
||||||
const created = [];
|
const created = [];
|
||||||
const mrt = {
|
const mrt = {
|
||||||
depthBuffer: new DataTexture(),
|
depthBuffer: new DataTexture(),
|
||||||
depthBufferPacking: RGBADepthPacking,
|
depthBufferPacking: RGBADepthPacking,
|
||||||
};
|
};
|
||||||
const ctx = { findEffect: (key) => (key === 'mrt' ? mrt : undefined) };
|
const ctx = { findEffect: (key) => (key === 'mrt' ? mrt : undefined) };
|
||||||
class MeshDesc {
|
|
||||||
constructor(view, context, config) {
|
|
||||||
this.ctx = context;
|
|
||||||
this.config = config;
|
|
||||||
}
|
|
||||||
onDestroy() {}
|
|
||||||
}
|
|
||||||
const view = {
|
const view = {
|
||||||
forceUpdate() {},
|
forceUpdate() {},
|
||||||
registerMesh: (kind, desc) => kinds.set(kind, desc),
|
|
||||||
addMesh(config) {
|
|
||||||
const kind = Object.keys(config)[0];
|
|
||||||
const desc = new (kinds.get(kind))(view, ctx, config);
|
|
||||||
const object = desc.createMesh();
|
|
||||||
created.push({ kind, pass: desc.getPassKey(), object });
|
|
||||||
return { delete: () => desc.onDestroy() };
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
return { view, MeshDesc, created, mrt };
|
const overlay = {
|
||||||
|
ctx,
|
||||||
|
add(object) {
|
||||||
|
created.push(object);
|
||||||
|
},
|
||||||
|
remove() {},
|
||||||
|
};
|
||||||
|
return { view, overlay, created, mrt };
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Every renderable under an object compiles with the test and binds depth. */
|
/** Every renderable under an object compiles with the test and binds depth. */
|
||||||
@@ -141,11 +132,11 @@ function assertTested(object, mrt) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test('pack meshes stay transparent and test the scene depth', () => {
|
test('pack meshes draw in the overlay and test the scene depth', () => {
|
||||||
const packs = fakeView();
|
const packs = fakeView();
|
||||||
const owned = [];
|
const owned = [];
|
||||||
const port = createNavaraMeshes(packs.view, {
|
const port = createNavaraMeshes(packs.view, {
|
||||||
MeshDesc: packs.MeshDesc,
|
overlay: packs.overlay,
|
||||||
camera: {},
|
camera: {},
|
||||||
picker: { registerMeshPicker: () => () => {} },
|
picker: { registerMeshPicker: () => () => {} },
|
||||||
});
|
});
|
||||||
@@ -156,9 +147,8 @@ test('pack meshes stay transparent and test the scene depth', () => {
|
|||||||
{ own: (fn) => owned.push(fn) },
|
{ own: (fn) => owned.push(fn) },
|
||||||
);
|
);
|
||||||
assert.equal(packs.created.length, 1);
|
assert.equal(packs.created.length, 1);
|
||||||
assert.equal(packs.created[0].pass, 'transparent');
|
assertTested(packs.created[0], packs.mrt);
|
||||||
assertTested(packs.created[0].object, packs.mrt);
|
assert.equal(packs.created[0].children[0].material.depthTest, true);
|
||||||
assert.equal(packs.created[0].object.children[0].material.depthTest, true);
|
|
||||||
for (const release of owned) release();
|
for (const release of owned) release();
|
||||||
port.destroy();
|
port.destroy();
|
||||||
});
|
});
|
||||||
Reference in new issue
Block a user