measure(perf): per-component ablation of the TunnelNetwork path; exact worms restored
Round (Codex; reviewed by me against PERF-SAMPLED.md). Revert: voxel.WormNoiseMode / voxel.WormLatticeStep, their storage and their switches are REMOVED. VoxelWormField has one path again, exact Perlin with the N1 short circuit. Kept: bEnableWorms (asset), WormsForceOff (measurement only), the exact block skip (default 0). Ablation instrument: 14 development-only, world-changing force-off bits (voxel.TunnelAblate*), applied on the fused, op-stack/classifier, cached SDF/core and modifier/floor paths. They resolve once per process, are hashed into the generation fingerprint, and are compiled to zero in UE_BUILD_SHIPPING (VoxelDensityAblation.cpp). They are a measurement instrument, never a gameplay or multiplayer switch. Defaults exact: canonical export OBJ b3e5f4c3..9b377, worms-region 311CA42C / 75,482 triangles, capability 20,830 / 10,909, and 841/841 keyed tiles identical to NextHeadStaticTrace_20260913. Static worker seconds saved by removing ONE component (two off runs vs the interleaved all-on 33.06 s; baseline noise 0.27%): tunnel SDF 11.4%, cave warp 10.3%, passage carving 10.1%, landing posts 9.9%, passage structural posts 5.6%, worms 2.4%, native floor 2.2%, origin spine 1.6%, room SDF 1.6%, everything else <= 1.1% Moving (2+2 runs each) confirms the top five at 6.0-11.6%. Tunnel SDF off cuts LOD0 generation p95 104 -> 83 ms: it owns the slow tail. The positive savings sum to 58% of the static total; the other 42% is shared. The rows are not additive. Unexplained: tunnel-core OFF made the static total 2.9x SLOWER (95.5 s) while LOD0 generation got faster (p50 64.7 -> 60.6 ms) and triangles fell. The report blames the changed field, which does not fit; more likely a slow fallback path in coarse tiles. That row is not a cost measurement. Ledger: every Unreal process exited 0 and verified the loaded DLL; two PowerShell parser errors happened before any process started. No crashes or retries. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TaFdXhTdYMkW1xrV6ApT6Y
This commit is contained in:
1 parent
c132243b30
commit
6ccf3718ff
12 files changed
+833
-695
No files matched your search
@@ -142,56 +142,6 @@ FORCEINLINE float Perlin3D(const FVector3f& P)
|
||||
return Perlin3D(P.X, P.Y, P.Z);
|
||||
}
|
||||
|
||||
// A smooth, deterministic value-noise sample for the worm-only cost experiment. It keeps the
|
||||
// same unit lattice and quintic interpolation as Perlin3D, but uses one seeded scalar hash per
|
||||
// corner instead of the eight gradient selections and dot products. It is intentionally not used
|
||||
// by the terrain's other noise fields; WormNoiseMode gates it as an explicit world-changing test.
|
||||
FORCEINLINE uint32 ValueNoiseHash(int32 X, int32 Y, int32 Z, uint32 Seed, uint32 Salt)
|
||||
{
|
||||
uint32 H = Detail::HashCorner(X, Y, Z) ^ Seed ^ Salt;
|
||||
H ^= H >> 16;
|
||||
H *= 0x7FEB352Du;
|
||||
H ^= H >> 15;
|
||||
return H;
|
||||
}
|
||||
|
||||
FORCEINLINE float ValueNoise3D(const FVector3f& P, uint32 Seed, uint32 Salt)
|
||||
{
|
||||
const float XFloor = FMath::FloorToFloat(P.X);
|
||||
const float YFloor = FMath::FloorToFloat(P.Y);
|
||||
const float ZFloor = FMath::FloorToFloat(P.Z);
|
||||
const int32 X = static_cast<int32>(XFloor);
|
||||
const int32 Y = static_cast<int32>(YFloor);
|
||||
const int32 Z = static_cast<int32>(ZFloor);
|
||||
const float Fx = P.X - XFloor;
|
||||
const float Fy = P.Y - YFloor;
|
||||
const float Fz = P.Z - ZFloor;
|
||||
const float Sx = Detail::Fade(Fx);
|
||||
const float Sy = Detail::Fade(Fy);
|
||||
const float Sz = Detail::Fade(Fz);
|
||||
constexpr float HashToSigned = 2.0f / 16777216.0f;
|
||||
const auto Sample = [Seed, Salt, HashToSigned](int32 IX, int32 IY, int32 IZ) -> float
|
||||
{
|
||||
return static_cast<float>(ValueNoiseHash(IX, IY, IZ, Seed, Salt) & 0x00FFFFFFu)
|
||||
* HashToSigned - 1.0f;
|
||||
};
|
||||
const float V000 = Sample(X, Y, Z);
|
||||
const float V100 = Sample(X + 1, Y, Z);
|
||||
const float V010 = Sample(X, Y + 1, Z);
|
||||
const float V110 = Sample(X + 1, Y + 1, Z);
|
||||
const float V001 = Sample(X, Y, Z + 1);
|
||||
const float V101 = Sample(X + 1, Y, Z + 1);
|
||||
const float V011 = Sample(X, Y + 1, Z + 1);
|
||||
const float V111 = Sample(X + 1, Y + 1, Z + 1);
|
||||
const float X00 = Detail::Lerp(V000, V100, Sx);
|
||||
const float X10 = Detail::Lerp(V010, V110, Sx);
|
||||
const float X01 = Detail::Lerp(V001, V101, Sx);
|
||||
const float X11 = Detail::Lerp(V011, V111, Sx);
|
||||
const float Y0 = Detail::Lerp(X00, X10, Sy);
|
||||
const float Y1 = Detail::Lerp(X01, X11, Sy);
|
||||
return Detail::Lerp(Y0, Y1, Sz);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// LIPSCHITZ BOUND FOR THE ACTUAL 3D FIELD
|
||||
//=============================================================================
|
||||
|
||||
Reference in new issue
Block a user