wip(standalone): GPU step 12 -- far evaluator cold use 1704 -> 3 ms; near detail now the floor

Split ordinary far evaluation from near-detail evaluation; [loop] in connector
refinement and skirt clipping. Cold first use: EvaluateFarField 1704 -> 3.3 ms,
connector rings 775 -> 630, skirt emit 948 -> 909, near detail 1783 ms (the
floor). Warm-up still ~2.2 s; whole view CPU 1.351 s vs hybrid 3.210 s.
Output-slot reuse fixed: crossing probe 1/1, 2,226/2,226 tiles. Audits: 0
topology/protected/thin diffs vs CPU and WARP, hashes + walk unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-10-07 06:51:53 +02:00
1 parent 7f64e2e0aa
commit 05b1523c54
24 files changed
+1033 -66

No files matched your search

@@ -464,73 +464,85 @@ void EvaluateFarFieldCS(uint3 dispatchId : SV_DispatchThreadID)
+ float3(int(x) - 1, int(y) - 1, int(z) - 1) * StepVoxels;
float density;
uint distanceEvaluations=0;
float nearNormalDensity=0.0f;
if(NearFieldMode!=0)
const FarFieldSpatialBin range = FarFieldFindBin(position);
float cave = 100000.0f, overlay = -100000.0f;
[loop]
for(uint item=0;item<range.count;++item)
{
nearNormalDensity=NearFieldDensityAt(position,0,distanceEvaluations);
density=nearNormalDensity;
if(abs(density)<0.05f)
density=density<0.0f?-0.05f:(density>0.0f?0.05f:-0.05f);
const uint packedProxy=FarNearPackedProxy[index];
if(packedProxy!=0xffffffffu)
const VF_FieldPrimitive shape=FarShapes[FarSpatialBinShapeIds[range.offset+item]];
if((shape.flags&VF_FIELD_PRIMITIVE_CARVE)!=0)
{
// The CPU uploads sparse interpolation magnitudes. The GPU decides
// ordinary signs, except for the one-quantum band where float sign
// noise can flip an entire cell against the packed CPU cache.
const bool packedSignOverride=(packedProxy&0x40000000u)!=0u;
const bool packedRockSign=(packedProxy&0x80000000u)!=0u;
const uint magnitudeQ=packedProxy&0x3fffffffu;
const float magnitude=magnitudeQ==0u?4.125f:(float)magnitudeQ*(1.0f/256.0f);
const bool negative=packedSignOverride?packedRockSign:(density<=0.0f);
density=negative?-magnitude:magnitude;
if(position.x<shape.minVoxel[0]-6||position.x>shape.maxVoxel[0]+6
||position.y<shape.minVoxel[1]-6||position.y>shape.maxVoxel[1]+6
||position.z<shape.minVoxel[2]-6||position.z>shape.maxVoxel[2]+6)continue;
float distance=VF_FieldPrimitiveDistance(shape,position.x,position.y,position.z);
++distanceEvaluations;
if((shape.flags&VF_FIELD_PRIMITIVE_HAS_FLOOR)!=0)
{
const float floorZ=VF_FieldPrimitiveFloorAt(shape,position.x,position.y);
distance=VF_FieldSmoothMax(distance,floorZ-position.z,shape.floorBlendRadius);
}
cave=VF_FieldSmoothMin(cave,distance,shape.blendRadius);
}
else if(position.x>=shape.minVoxel[0]&&position.x<=shape.maxVoxel[0]
&&position.y>=shape.minVoxel[1]&&position.y<=shape.maxVoxel[1]
&&position.z>=shape.minVoxel[2]&&position.z<=shape.maxVoxel[2])
{
overlay=max(overlay,-VF_FieldPrimitiveDistance(shape,position.x,position.y,position.z));
++distanceEvaluations;
}
}
else
{
const FarFieldSpatialBin range=FarFieldFindBin(position);
float cave=100000.0f,overlay=-100000.0f;
[loop]
for(uint item=0;item<range.count;++item)
{
const VF_FieldPrimitive shape=FarShapes[FarSpatialBinShapeIds[range.offset+item]];
if((shape.flags&VF_FIELD_PRIMITIVE_CARVE)!=0)
{
if(position.x<shape.minVoxel[0]-6||position.x>shape.maxVoxel[0]+6
||position.y<shape.minVoxel[1]-6||position.y>shape.maxVoxel[1]+6
||position.z<shape.minVoxel[2]-6||position.z>shape.maxVoxel[2]+6)continue;
float distance=VF_FieldPrimitiveDistance(shape,position.x,position.y,position.z);
++distanceEvaluations;
if((shape.flags&VF_FIELD_PRIMITIVE_HAS_FLOOR)!=0)
{
const float floorZ=VF_FieldPrimitiveFloorAt(shape,position.x,position.y);
distance=VF_FieldSmoothMax(distance,floorZ-position.z,shape.floorBlendRadius);
}
cave=VF_FieldSmoothMin(cave,distance,shape.blendRadius);
}
else if(position.x>=shape.minVoxel[0]&&position.x<=shape.maxVoxel[0]
&&position.y>=shape.minVoxel[1]&&position.y<=shape.maxVoxel[1]
&&position.z>=shape.minVoxel[2]&&position.z<=shape.maxVoxel[2])
{
overlay=max(overlay,-VF_FieldPrimitiveDistance(shape,position.x,position.y,position.z));
++distanceEvaluations;
}
}
const float base=min(position.z-FarStrataLo,FarStrataHi-position.z);
const float rockDistance=VF_FieldSmoothMin(base,max(cave,overlay),FarStrataBlend);
const float rawDensity=-rockDistance;
const float magnitude=max(abs(rawDensity),0.05f);
density=rockDistance>=0.0f?-magnitude:magnitude;
}
const float base=min(position.z-FarStrataLo,FarStrataHi-position.z);
const float rockDistance=VF_FieldSmoothMin(base,max(cave,overlay),FarStrataBlend);
const float rawDensity=-rockDistance;
const float magnitude=max(abs(rawDensity),0.05f);
density=rockDistance>=0.0f?-magnitude:magnitude;
const uint protectedAir = (FarProtectedAir[index >> 5] >> (index & 31)) & 1;
const uint protectedSolid = (FarProtectedSolid[index >> 5] >> (index & 31)) & 1;
const float protectedMinimum=NearFieldMode!=0?1.0f/256.0f:0.05f;
if(protectedAir!=0)density=max(abs(density),protectedMinimum);
else if(protectedSolid!=0)density=-max(abs(density),protectedMinimum);
if(protectedAir!=0)density=max(abs(density),0.05f);
else if(protectedSolid!=0)density=-max(abs(density),0.05f);
FarFieldDensity[index] = density;
FarNearNormalDensityOutput[index]=nearNormalDensity;
FarNearNormalDensityOutput[index]=0.0f;
if (FarEvalCounterEnabled != 0) FarFieldEvalCounters[index] = distanceEvaluations;
}
[numthreads(64,1,1)]
void EvaluateNearFieldCS(uint3 dispatchId : SV_DispatchThreadID)
{
const uint index=dispatchId.x;
if(index>=FarSampleCount)return;
const uint x=index%SampleDim;
const uint y=(index/SampleDim)%SampleDim;
const uint z=index/(SampleDim*SampleDim);
const float3 position=float3(OriginX,OriginY,OriginZ)
+float3(int(x)-1,int(y)-1,int(z)-1)*StepVoxels;
uint distanceEvaluations=0;
const float nearNormalDensity=NearFieldDensityAt(position,0,distanceEvaluations);
float density=nearNormalDensity;
if(abs(density)<0.05f)
density=density<0.0f?-0.05f:(density>0.0f?0.05f:-0.05f);
const uint packedProxy=FarNearPackedProxy[index];
if(packedProxy!=0xffffffffu)
{
// The CPU uploads sparse interpolation magnitudes. The GPU decides
// ordinary signs, except for the one-quantum band where float sign
// noise can flip an entire cell against the packed CPU cache.
const bool packedSignOverride=(packedProxy&0x40000000u)!=0u;
const bool packedRockSign=(packedProxy&0x80000000u)!=0u;
const uint magnitudeQ=packedProxy&0x3fffffffu;
const float magnitude=magnitudeQ==0u?4.125f:(float)magnitudeQ*(1.0f/256.0f);
const bool negative=packedSignOverride?packedRockSign:(density<=0.0f);
density=negative?-magnitude:magnitude;
}
const uint protectedAir=(FarProtectedAir[index>>5]>>(index&31))&1;
const uint protectedSolid=(FarProtectedSolid[index>>5]>>(index&31))&1;
if(protectedAir!=0)density=max(abs(density),1.0f/256.0f);
else if(protectedSolid!=0)density=-max(abs(density),1.0f/256.0f);
FarFieldDensity[index]=density;
FarNearNormalDensityOutput[index]=nearNormalDensity;
if(FarEvalCounterEnabled!=0)FarFieldEvalCounters[index]=distanceEvaluations;
}
float FarRockDistanceAt(float3 position,int3 cachedBinCoord,FarFieldSpatialBin cachedRange)
{
float cave = 100000.0f;
@@ -632,7 +644,7 @@ void FarSkirtClipTriangle(FarSkirtVertex a,FarSkirtVertex b,FarSkirtVertex c,
{
FarSkirtVertex input[3];input[0]=a;input[1]=b;input[2]=c;
polygonCount=0;
[unroll]
[loop]
for(uint edge=0;edge<3;++edge)
{
FarSkirtVertex start=input[edge];
@@ -778,7 +790,7 @@ float FarConnectorRadius(float3 center, float3 direction, float nominalRadius)
residual=FarRockDistanceAt(center+direction*radius,cachedBinCoord,cachedRange);
converged=abs(residual)<=1.0f;
}
[unroll]
[loop]
for(uint refine=0;refine<2&&!converged;++refine)
{
const float distance=residual;
@@ -807,7 +819,7 @@ float FarConnectorRadius(float3 center, float3 direction, float nominalRadius)
{
float lo=previous,hi=distance;
const bool previousSolid=previousDistance>=0.0f;
[unroll]
[loop]
for(uint refine=0;refine<8;++refine)
{
const float mid=(lo+hi)*0.5f;