86 lines
3.7 KiB
JavaScript
86 lines
3.7 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import { readFile } from 'node:fs/promises';
|
|
|
|
const shader = await readFile(new URL('../src/shaders/mosaic.frag', import.meta.url), 'utf8');
|
|
|
|
// This is a source/math-only regression. It mirrors the bounded scoring contract
|
|
// used by REGION_ATLAS; it does not claim to execute GLSL or prove browser visuals.
|
|
assert.match(shader, /regionAtlasProbe/,
|
|
'REGION_ATLAS must expose the bounded probe path before this regression can pass');
|
|
assert.match(shader, /regionAtlasEvidence/,
|
|
'atlas probes must score RGB and front-depth evidence in the atlas pass');
|
|
|
|
const smoothstep = (edge0, edge1, value) => {
|
|
const t = Math.max(0, Math.min(1, (value - edge0) / (edge1 - edge0)));
|
|
return t * t * (3 - 2 * t);
|
|
};
|
|
const luminance = color => color[0] * 0.299 + color[1] * 0.587 + color[2] * 0.114;
|
|
const darkEvidence = (color, frontDepth, valid = true) => valid
|
|
? smoothstep(0.8, 0.95, frontDepth) * (1 - smoothstep(0.10, 0.20, luminance(color)))
|
|
: 0;
|
|
|
|
function baselinePointSample(fixture) {
|
|
return { color: fixture.center.color, evidence: fixture.center.evidence };
|
|
}
|
|
|
|
function atlasRepresentative(fixture) {
|
|
const centerColor = fixture.center.color;
|
|
const centerEvidence = fixture.center.evidence;
|
|
const centerLuma = luminance(centerColor);
|
|
let bestColor = centerColor;
|
|
let bestEvidence = centerEvidence;
|
|
let bestBlend = 0;
|
|
|
|
for (const probe of fixture.probes.slice(0, 4)) {
|
|
const evidence = darkEvidence(probe.color, probe.frontDepth, probe.valid);
|
|
const evidenceGain = evidence - centerEvidence;
|
|
const darkGain = centerLuma - luminance(probe.color);
|
|
let blend = 0;
|
|
if (evidence > 0.05 && evidenceGain > 0.02 && darkGain > 0.015) {
|
|
blend = Math.min(0.4, evidenceGain * 2) * Math.min(1, Math.max(0, darkGain * 4));
|
|
}
|
|
if (blend > bestBlend) {
|
|
bestColor = centerColor.map((value, index) => value * (1 - blend) + probe.color[index] * blend);
|
|
bestEvidence = Math.max(centerEvidence, evidence);
|
|
bestBlend = blend;
|
|
}
|
|
}
|
|
return { color: bestColor, evidence: bestEvidence };
|
|
}
|
|
|
|
const missedEye = {
|
|
center: { color: [0.62, 0.62, 0.62], evidence: 0 },
|
|
probes: [
|
|
{ color: [0.035, 0.035, 0.035], frontDepth: 0.92, valid: true },
|
|
{ color: [0.62, 0.62, 0.62], frontDepth: 0.92, valid: true },
|
|
{ color: [0.62, 0.62, 0.62], frontDepth: 0.92, valid: true },
|
|
{ color: [0.62, 0.62, 0.62], frontDepth: 0.92, valid: true },
|
|
],
|
|
};
|
|
const oldPoint = baselinePointSample(missedEye);
|
|
const revised = atlasRepresentative(missedEye);
|
|
assert.ok(luminance(oldPoint.color) > 0.5, 'baseline point sampling must miss the narrow dark feature');
|
|
assert.ok(luminance(revised.color) < 0.5, 'atlas evidence must pull the representative toward the dark feature');
|
|
assert.ok(revised.evidence > 0.5, 'the valid front-depth dark probe must carry evidence into atlas fitting');
|
|
|
|
for (const [name, fixture] of [
|
|
['far', {
|
|
center: { color: [0.62, 0.62, 0.62], evidence: 0 },
|
|
probes: [{ color: [0.035, 0.035, 0.035], frontDepth: 0.79, valid: true }],
|
|
}],
|
|
['invalid', {
|
|
center: { color: [0.62, 0.62, 0.62], evidence: 0 },
|
|
probes: [{ color: [0.035, 0.035, 0.035], frontDepth: 0.92, valid: false }],
|
|
}],
|
|
['uniform', {
|
|
center: { color: [0.42, 0.42, 0.42], evidence: 0 },
|
|
probes: Array.from({ length: 4 }, () => ({ color: [0.42, 0.42, 0.42], frontDepth: 0.92, valid: true })),
|
|
}],
|
|
]) {
|
|
const before = baselinePointSample(fixture);
|
|
const after = atlasRepresentative(fixture);
|
|
assert.deepEqual(after, before, `${name} fixture must remain identical to center sampling`);
|
|
}
|
|
|
|
console.log('Region atlas dark sampling source/math-only regression passed: phase-offset narrow feature, far/invalid/uniform invariants, and four-probe bounded scoring contract.');
|