wip(assembler): round L32 -- smooth Gradient interface at full amplitude (no rings, not flat)
Band faces now use signed distance to the displaced solid intervals, continuous across bands, so MC interpolates the interface instead of terracing at density levels. The Gradient amplitude is restored to width/8 (about 4 m peak-to-peak at 16 m). Ring/terrace audit at LOD0-8 on the FI floor and SW ceiling passes; negative controls: L30 (rings) and L31 (flat) both fail. Hole/interface audits, 16 passage rows and 24/24 determinism pass. Evaluator 20. Cost vs L31 SW +1.9%, FI +1.5%. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CSFYgsdW8ejZSyiMf4qRSX
This commit is contained in:
1 parent
28069f0d98
commit
d0158c6019
31 files changed
+2207
-111
No files matched your search
@@ -296,6 +296,7 @@ uniform float uHeightRange;
|
||||
uniform float uTileEdgeWidth;
|
||||
uniform vec3 uLightDirection;
|
||||
uniform int uHeadlamp;
|
||||
uniform int uGrazingLight;
|
||||
uniform int uClipEnabled;
|
||||
uniform vec4 uClipPlane;
|
||||
void main()
|
||||
@@ -315,10 +316,11 @@ void main()
|
||||
float heightT=clamp(0.5+(vHeight-uHeightCenter)/max(uHeightRange,0.001),0.0,1.0);
|
||||
float smoothHeightT=heightT*heightT*(3.0-2.0*heightT);
|
||||
vec3 heightTint=uHeightTint!=0
|
||||
?mix(vec3(0.80,0.91,1.0),vec3(1.0,0.91,0.77),smoothHeightT)
|
||||
?mix(vec3(0.62,0.78,1.0),vec3(1.0,0.82,0.62),smoothHeightT)
|
||||
:vec3(1.0);
|
||||
float diffuse=max(dot(n,normalize(uLightDirection)),0.0);
|
||||
float illumination=uHeadlamp!=0?0.78+0.34*diffuse:0.62+0.38*diffuse;
|
||||
float illumination=uGrazingLight!=0?0.32+1.20*diffuse:
|
||||
uHeadlamp!=0?0.78+0.34*diffuse:0.62+0.38*diffuse;
|
||||
color=vec3(0.64,0.62,0.56)*heightTint*illumination;
|
||||
}
|
||||
if(uTileEdges!=0&&vTileData.z>0.0)
|
||||
@@ -380,8 +382,11 @@ void main()
|
||||
}
|
||||
|
||||
bool Render(FScene& Scene,const std::filesystem::path& Output,int Width,int Height,
|
||||
double HorizontalFovDegrees,bool ReadableMode,bool HeightTint,bool Headlamp,bool TileEdges,
|
||||
double TileEdgeWidthMeters,bool ClipPlaneEnabled,
|
||||
double HorizontalFovDegrees,double HeightRangeMeters,
|
||||
double HeightCenterMeters,bool ReadableMode,
|
||||
bool HeightTint,bool Headlamp,bool TileEdges,
|
||||
double TileEdgeWidthMeters,bool HasLightDirection,
|
||||
const std::array<double,3>& LightDirection,bool ClipPlaneEnabled,
|
||||
const std::array<double,4>& ClipPlane)
|
||||
{
|
||||
EGLDisplay Display=MakeDisplay();
|
||||
@@ -478,19 +483,24 @@ void main()
|
||||
glUniform1i(glGetUniformLocation(Program,"uTileEdges"),TileEdges?1:0);
|
||||
glUniform1i(glGetUniformLocation(Program,"uHeightTint"),HeightTint?1:0);
|
||||
glUniform1f(glGetUniformLocation(Program,"uHeightCenter"),
|
||||
static_cast<float>(Scene.CameraMeters[2]));
|
||||
glUniform1f(glGetUniformLocation(Program,"uHeightRange"),64.0f);
|
||||
static_cast<float>(HeightCenterMeters));
|
||||
glUniform1f(glGetUniformLocation(Program,"uHeightRange"),
|
||||
static_cast<float>(HeightRangeMeters));
|
||||
glUniform1f(glGetUniformLocation(Program,"uTileEdgeWidth"),
|
||||
static_cast<float>(TileEdgeWidthMeters));
|
||||
glUniform1i(glGetUniformLocation(Program,"uClipEnabled"),ClipPlaneEnabled?1:0);
|
||||
glUniform1i(glGetUniformLocation(Program,"uHeadlamp"),Headlamp?1:0);
|
||||
glUniform1i(glGetUniformLocation(Program,"uGrazingLight"),HasLightDirection?1:0);
|
||||
glUniform4f(glGetUniformLocation(Program,"uClipPlane"),
|
||||
static_cast<float>(ClipPlane[0]),static_cast<float>(ClipPlane[1]),
|
||||
static_cast<float>(ClipPlane[2]),static_cast<float>(ClipPlane[3]));
|
||||
const std::array<double,3> ActiveLightDirection=HasLightDirection?LightDirection:
|
||||
Headlamp?std::array<double,3>{-Forward[0],-Forward[1],-Forward[2]}:
|
||||
std::array<double,3>{-0.42,-0.58,0.70};
|
||||
glUniform3f(glGetUniformLocation(Program,"uLightDirection"),
|
||||
Headlamp?static_cast<float>(-Forward[0]):-0.42f,
|
||||
Headlamp?static_cast<float>(-Forward[1]):-0.58f,
|
||||
Headlamp?static_cast<float>(-Forward[2]):0.70f);
|
||||
static_cast<float>(ActiveLightDirection[0]),
|
||||
static_cast<float>(ActiveLightDirection[1]),
|
||||
static_cast<float>(ActiveLightDirection[2]));
|
||||
glDrawElements(GL_TRIANGLES,static_cast<GLsizei>(Scene.Indices.size()),GL_UNSIGNED_INT,nullptr);
|
||||
glFinish();
|
||||
std::vector<std::uint8_t> Pixels(static_cast<std::size_t>(Width)*Height*4);
|
||||
@@ -527,12 +537,14 @@ int main(int argc,char** argv)
|
||||
{
|
||||
if(argc<3)
|
||||
{
|
||||
std::fprintf(stderr,"Usage: %s scene.vfmesh output.png [--size=WIDTHxHEIGHT] [--fov-deg=90] [--camera-m=X,Y,Z] [--yaw-deg=N] [--pitch-deg=N] [--shade=readable|normal] [--height-tint=on|off] [--headlamp=on|off] [--tile-edges=on|off] [--tile-edge-width-m=N] [--clip-plane=NX,NY,NZ,D]\n",argv[0]);
|
||||
std::fprintf(stderr,"Usage: %s scene.vfmesh output.png [--size=WIDTHxHEIGHT] [--fov-deg=90] [--height-range-m=N] [--height-center-m=N] [--camera-m=X,Y,Z] [--yaw-deg=N] [--pitch-deg=N] [--shade=readable|normal] [--height-tint=on|off] [--headlamp=on|off] [--light-direction=X,Y,Z] [--tile-edges=on|off] [--tile-edge-width-m=N] [--clip-plane=NX,NY,NZ,D]\n",argv[0]);
|
||||
return 2;
|
||||
}
|
||||
int Width=2560,Height=1440;double Fov=90.0;
|
||||
int Width=2560,Height=1440;double Fov=90.0,HeightRangeMeters=64.0;
|
||||
double HeightCenterMeters=0.0;bool HasHeightCenter=false;
|
||||
bool HasYaw=false,HasPitch=false;double Yaw=0.0,Pitch=0.0;
|
||||
bool HasCamera=false;std::array<double,3> Camera{};
|
||||
bool HasLightDirection=false;std::array<double,3> LightDirection{};
|
||||
bool ReadableMode=true,HeightTint=true,TileEdges=false,Headlamp=false;double TileEdgeWidthMeters=0.15;
|
||||
bool ClipPlaneEnabled=false;std::array<double,4> ClipPlane{};
|
||||
for(int I=3;I<argc;++I)
|
||||
@@ -550,6 +562,22 @@ int main(int argc,char** argv)
|
||||
if(End==Value.c_str()||*End!='\0'||Fov<=1.0||Fov>=179.0)
|
||||
{std::fprintf(stderr,"Invalid horizontal FOV\n");return 2;}
|
||||
}
|
||||
else if(Arg.starts_with("--height-range-m="))
|
||||
{
|
||||
char* End=nullptr;const std::string Value(Arg.substr(17));
|
||||
HeightRangeMeters=std::strtod(Value.c_str(),&End);
|
||||
if(End==Value.c_str()||*End!='\0'||!std::isfinite(HeightRangeMeters)
|
||||
||HeightRangeMeters<=0.0||HeightRangeMeters>1000000.0)
|
||||
{std::fprintf(stderr,"Invalid height tint range\n");return 2;}
|
||||
}
|
||||
else if(Arg.starts_with("--height-center-m="))
|
||||
{
|
||||
char* End=nullptr;const std::string Value(Arg.substr(18));
|
||||
HeightCenterMeters=std::strtod(Value.c_str(),&End);
|
||||
if(End==Value.c_str()||*End!='\0'||!std::isfinite(HeightCenterMeters))
|
||||
{std::fprintf(stderr,"Invalid height tint center\n");return 2;}
|
||||
HasHeightCenter=true;
|
||||
}
|
||||
else if(Arg.starts_with("--camera-m="))
|
||||
{
|
||||
const std::string Value(Arg.substr(11));
|
||||
@@ -589,6 +617,17 @@ int main(int argc,char** argv)
|
||||
else if(Mode=="off")Headlamp=false;
|
||||
else {std::fprintf(stderr,"Invalid headlamp mode\n");return 2;}
|
||||
}
|
||||
else if(Arg.starts_with("--light-direction="))
|
||||
{
|
||||
const std::string Value(Arg.substr(18));
|
||||
if(std::sscanf(Value.c_str(),"%lf,%lf,%lf",&LightDirection[0],
|
||||
&LightDirection[1],&LightDirection[2])!=3
|
||||
||!std::isfinite(LightDirection[0])||!std::isfinite(LightDirection[1])
|
||||
||!std::isfinite(LightDirection[2])
|
||||
||std::hypot(LightDirection[0],LightDirection[1],LightDirection[2])<=0.0)
|
||||
{std::fprintf(stderr,"Invalid light direction; use X,Y,Z with non-zero length\n");return 2;}
|
||||
HasLightDirection=true;
|
||||
}
|
||||
else if(Arg.starts_with("--tile-edges="))
|
||||
{
|
||||
const std::string_view Mode=Arg.substr(13);
|
||||
@@ -623,13 +662,16 @@ int main(int argc,char** argv)
|
||||
if(HasCamera)Scene.CameraMeters=Camera;
|
||||
if(HasYaw)Scene.YawDegrees=Yaw;
|
||||
if(HasPitch)Scene.PitchDegrees=Pitch;
|
||||
std::printf("[OffscreenScene] voxels_per_meter=%.6f camera_m=(%.3f,%.3f,%.3f) yaw=%.2f pitch=%.2f height_m=%.3f..%.3f shade=%s height_tint=%s tile_edges=%s vertices=%zu triangles=%llu\n",
|
||||
if(!HasHeightCenter)HeightCenterMeters=Scene.CameraMeters[2];
|
||||
std::printf("[OffscreenScene] voxels_per_meter=%.6f camera_m=(%.3f,%.3f,%.3f) yaw=%.2f pitch=%.2f height_m=%.3f..%.3f height_center_m=%.3f shade=%s height_tint=%s tile_edges=%s vertices=%zu triangles=%llu\n",
|
||||
1000000.0/Scene.VoxelSizeMicrons,Scene.CameraMeters[0],Scene.CameraMeters[1],Scene.CameraMeters[2],
|
||||
Scene.YawDegrees,Scene.PitchDegrees,Scene.MinimumHeight,Scene.MaximumHeight,
|
||||
HeightCenterMeters,
|
||||
ReadableMode?"readable":"normal",HeightTint?"on":"off",
|
||||
TileEdges?"on":"off",Scene.Vertices.size(),
|
||||
static_cast<unsigned long long>(Scene.Triangles));
|
||||
return Render(Scene,argv[2],Width,Height,Fov,ReadableMode,HeightTint,Headlamp,TileEdges,
|
||||
TileEdgeWidthMeters,ClipPlaneEnabled,ClipPlane)?0:3;
|
||||
return Render(Scene,argv[2],Width,Height,Fov,HeightRangeMeters,HeightCenterMeters,ReadableMode,
|
||||
HeightTint,Headlamp,TileEdges,
|
||||
TileEdgeWidthMeters,HasLightDirection,LightDirection,ClipPlaneEnabled,ClipPlane)?0:3;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user