Files
workinf_Blender_Wasm/web/protocol/nanovdb-render-golden.ts
mes123456 0fe8d2bb56
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled
Advance M8-M11 parity workflows
2026-08-17 04:37:07 -04:00

91 lines
3.4 KiB
TypeScript

import type { ErrorCode } from "./error";
export const NANOVDB_RENDER_GOLDEN_SCHEMA_VERSION = 1 as const;
export const NANOVDB_GOLDEN_MISMATCH_CODE = "NANOVDB_GOLDEN_MISMATCH" as const satisfies ErrorCode;
export interface NanoVDBRenderGoldenThresholdsIR {
maxChannelError: number;
meanAbsoluteError: number;
rmsError: number;
alphaCoverageDeltaRatio: number;
}
export interface NanoVDBRenderGoldenComparisonIR {
schemaVersion: typeof NANOVDB_RENDER_GOLDEN_SCHEMA_VERSION;
status: "READY" | "BLOCKED";
pixelCount: number;
comparedChannels: number;
maxChannelError: number;
meanAbsoluteError: number;
rmsError: number;
referenceAlphaPixels: number;
actualAlphaPixels: number;
alphaCoverageDeltaRatio: number;
thresholds: NanoVDBRenderGoldenThresholdsIR;
errorCode: typeof NANOVDB_GOLDEN_MISMATCH_CODE | null;
}
function validateThresholds(value: NanoVDBRenderGoldenThresholdsIR): NanoVDBRenderGoldenThresholdsIR {
if (
!Number.isInteger(value.maxChannelError) || value.maxChannelError < 0 || value.maxChannelError > 255 ||
!Number.isFinite(value.meanAbsoluteError) || value.meanAbsoluteError < 0 || value.meanAbsoluteError > 255 ||
!Number.isFinite(value.rmsError) || value.rmsError < 0 || value.rmsError > 255 ||
!Number.isFinite(value.alphaCoverageDeltaRatio) || value.alphaCoverageDeltaRatio < 0 || value.alphaCoverageDeltaRatio > 1
) {
throw new Error("NANOVDB_INVALID_ARGUMENT: render golden thresholds are invalid");
}
return { ...value };
}
export function compareNanoVDBRenderGolden(
reference: Uint8Array,
actual: Uint8Array,
thresholdsValue: NanoVDBRenderGoldenThresholdsIR,
): NanoVDBRenderGoldenComparisonIR {
if (
!(reference instanceof Uint8Array) || !(actual instanceof Uint8Array) ||
reference.byteLength === 0 || reference.byteLength !== actual.byteLength ||
reference.byteLength % 4 !== 0
) {
throw new Error("NANOVDB_INVALID_ARGUMENT: render golden images must be equal non-empty RGBA8 buffers");
}
const thresholds = validateThresholds(thresholdsValue);
let maximum = 0;
let absoluteTotal = 0;
let squaredTotal = 0;
let referenceAlphaPixels = 0;
let actualAlphaPixels = 0;
for (let index = 0; index < reference.byteLength; index++) {
const difference = Math.abs(reference[index] - actual[index]);
maximum = Math.max(maximum, difference);
absoluteTotal += difference;
squaredTotal += difference * difference;
if ((index & 3) === 3) {
if (reference[index] > 0) referenceAlphaPixels++;
if (actual[index] > 0) actualAlphaPixels++;
}
}
const pixelCount = reference.byteLength / 4;
const meanAbsoluteError = absoluteTotal / reference.byteLength;
const rmsError = Math.sqrt(squaredTotal / reference.byteLength);
const alphaCoverageDeltaRatio = Math.abs(referenceAlphaPixels - actualAlphaPixels) / pixelCount;
const matches = maximum <= thresholds.maxChannelError &&
meanAbsoluteError <= thresholds.meanAbsoluteError &&
rmsError <= thresholds.rmsError &&
alphaCoverageDeltaRatio <= thresholds.alphaCoverageDeltaRatio;
return {
schemaVersion: NANOVDB_RENDER_GOLDEN_SCHEMA_VERSION,
status: matches ? "READY" : "BLOCKED",
pixelCount,
comparedChannels: reference.byteLength,
maxChannelError: maximum,
meanAbsoluteError,
rmsError,
referenceAlphaPixels,
actualAlphaPixels,
alphaCoverageDeltaRatio,
thresholds,
errorCode: matches ? null : NANOVDB_GOLDEN_MISMATCH_CODE,
};
}