standalone: per-tile speed at plugin level, streaming like the game, softer lighting
Cause found by profiling: room/SDF graph-cache churn (exact XY bounds + sample order rebuilt it constantly). Region grouping (one LOD3 tile: 1,084 -> 229 builds), taller-tile traversal for LOD6 (36,480 -> 12,160), extent-dependent cache slots, lambdas instead of recursive std::function. Serial ms/tile, 64 nearest tiles per level (before -> after): L0 50.4 -> 50.6, L1 112 -> 110, L2 24 -> 22, L3 223 -> 73, L4 269 -> 134, L5 393 -> 127, L6 283 -> 145. Hashes of all levels unchanged; parity 3,436/3,436 bit-identical. Full clipmap, 16 workers BelowNormal: full detail 66.6 s, all 12,054 tiles 175 s. In-stream L0 tail is high (median 83 ms, mean 198 ms, p95 669 ms) vs 51 ms serial. Streaming: recentre keeps the intersection, generates only missing tiles nearest/finest first; one crossing = exactly 441 new tiles in 6.1 s, no stale results. Lighting: normals already come from the density gradient; the striping was the squared headlamp; broad linear fill + warmer palette. Daytime CPU rule documented in Standalone/README.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MmSoF64BbRFmk9C3p1VsBJ
This commit is contained in:
1 parent
3f300b912a
commit
81b7d6d0ff
24 files changed
+1096
-196
No files matched your search
@@ -8,11 +8,13 @@
|
||||
#include <bit>
|
||||
#include <cassert>
|
||||
#include <chrono>
|
||||
#include <charconv>
|
||||
#include <cctype>
|
||||
#include <cstdarg>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <immintrin.h>
|
||||
@@ -632,8 +634,73 @@ struct FWriteScopeLock { explicit FWriteScopeLock(FRWLock&L):Lock(L.Mutex){} std
|
||||
enum EConsoleVariableFlags { ECVF_Default=0, ECVF_SetByCommandline=1, ECVF_SetByCode=2 };
|
||||
class FAutoConsoleVariableRef { public:FAutoConsoleVariableRef(const char*,int32&,const char*,uint32=0){} FAutoConsoleVariableRef(const char*,float&,const char*,uint32=0){} FAutoConsoleVariableRef(const char*,bool&,const char*,uint32=0){} };
|
||||
template<class T> class TAutoConsoleVariable { public:TAutoConsoleVariable(const char*,T Default,const char*,uint32=0):Value(Default){}T GetValueOnAnyThread()const{return Value.load();}T GetValueOnGameThread()const{return Value.load();}void Set(T V,uint32=0){Value.store(V);} TAutoConsoleVariable*operator->(){return this;}private:std::atomic<T>Value;};
|
||||
struct FCommandLine { static const char* Get(){return "";} };
|
||||
struct FParse { static bool Value(const char*,const char*,int32&){return false;} static bool Value(const char*,const char*,float&){return false;} static bool Value(const char*,const char*,FString&){return false;} static bool Param(const char*,const char*){return false;} };
|
||||
struct FCommandLine
|
||||
{
|
||||
inline static std::string Arguments;
|
||||
static const char* Get(){return Arguments.c_str();}
|
||||
static void Set(std::string_view InArguments){Arguments.assign(InArguments);}
|
||||
};
|
||||
struct FParse
|
||||
{
|
||||
static bool ReadValue(const char* CommandLine,const char* Key,std::string& Out)
|
||||
{
|
||||
if(!CommandLine||!Key||!*Key)return false;
|
||||
const std::string_view Command(CommandLine),Token(Key);
|
||||
std::size_t Position=0;
|
||||
while((Position=Command.find(Token,Position))!=std::string_view::npos)
|
||||
{
|
||||
const bool bTokenStart=Position==0||Command[Position-1]==' '
|
||||
||Command[Position-1]=='\t'||Command[Position-1]=='-';
|
||||
const std::size_t ValueStart=Position+Token.size();
|
||||
if(bTokenStart&&ValueStart<=Command.size())
|
||||
{
|
||||
std::size_t ValueEnd=Command.find_first_of(" \t\r\n",ValueStart);
|
||||
if(ValueEnd==std::string_view::npos)ValueEnd=Command.size();
|
||||
if(ValueEnd>ValueStart)
|
||||
{Out.assign(Command.substr(ValueStart,ValueEnd-ValueStart));return true;}
|
||||
}
|
||||
Position+=Token.size();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
static bool Value(const char* CommandLine,const char* Key,int32& Out)
|
||||
{
|
||||
std::string Text;
|
||||
if(!ReadValue(CommandLine,Key,Text))return false;
|
||||
const auto Result=std::from_chars(Text.data(),Text.data()+Text.size(),Out);
|
||||
return Result.ec==std::errc{}&&Result.ptr==Text.data()+Text.size();
|
||||
}
|
||||
static bool Value(const char* CommandLine,const char* Key,float& Out)
|
||||
{
|
||||
std::string Text;
|
||||
if(!ReadValue(CommandLine,Key,Text))return false;
|
||||
char* End=nullptr;Out=std::strtof(Text.c_str(),&End);
|
||||
return End==Text.c_str()+Text.size();
|
||||
}
|
||||
static bool Value(const char* CommandLine,const char* Key,FString& Out)
|
||||
{
|
||||
std::string Text;
|
||||
if(!ReadValue(CommandLine,Key,Text))return false;
|
||||
Out=FString(Text);return true;
|
||||
}
|
||||
static bool Param(const char* CommandLine,const char* Name)
|
||||
{
|
||||
if(!CommandLine||!Name||!*Name)return false;
|
||||
const std::string_view Command(CommandLine),Token(Name);
|
||||
std::size_t Position=0;
|
||||
while((Position=Command.find(Token,Position))!=std::string_view::npos)
|
||||
{
|
||||
const bool bTokenStart=Position==0||Command[Position-1]==' '
|
||||
||Command[Position-1]=='\t'||Command[Position-1]=='-';
|
||||
const std::size_t End=Position+Token.size();
|
||||
const bool bTokenEnd=End==Command.size()||Command[End]==' '
|
||||
||Command[End]=='\t'||Command[End]=='\r'||Command[End]=='\n';
|
||||
if(bTokenStart&&bTokenEnd)return true;
|
||||
Position=End;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
struct FCrc { static uint32 MemCrc32(const void*Data,int32 Length,uint32 Crc=0){const auto*P=static_cast<const uint8*>(Data);uint32 V=~Crc;for(int32 I=0;I<Length;++I){V^=P[I];for(int J=0;J<8;++J)V=(V>>1)^(0xEDB88320u&static_cast<uint32>(-static_cast<int32>(V&1)));}return ~V;} static uint32 StrCrc32(const char*S,uint32 Crc=0){return MemCrc32(S,static_cast<int32>(std::strlen(S)),Crc);} };
|
||||
template<class T> using TAtomic = std::atomic<T>;
|
||||
class FThreadSafeCounter { public:int32 Increment(){return ++Value;}int32 Decrement(){return --Value;}int32 GetValue()const{return Value.load();}void Reset(){Value.store(0);}private:std::atomic<int32>Value{0};};
|
||||
Reference in new issue
Block a user