mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 02:43:44 +00:00
feat(ugc): hidden faces removed as LU Toolbox's Remove Hidden Faces decides them
The 42 depth renders only saw faces in direct view, so faces reached only by bounced light (interiors, recesses, rooms seen through openings) were removed. UgcHsr traces the paths LU Toolbox's Cycles bake traces, directly from points on each opaque triangle, and removes a triangle only when none of its paths reaches the sky: - points in rows along the triangle's longest side, hsr_sample_spacing apart (0.1143, 7 x 7 on a stud-sized square), at least hsr_min_points (28, the texels LU Toolbox bakes for a triangle), at most 4096 - hsr_samples (8) paths from each point, at most hsr_bounces (8) bounces, as Cycles 3.1 samples the bake material (Principled BSDF defaults: Burley diffuse and GGX specular, defensive sampling, Filter Glossy, 4 glossy bounces, Russian roulette from the second bounce, ensure_valid_reflection); no direct sky sampling (Cycles doesn't sample a flat world as a light) - hsr_ground_plane: LU Toolbox's black box under LDD's floor - decided per triangle, deterministic per model; triangles without area removed - the VC pre-pass isn't done Checked against LU Toolbox's operator in Blender 3.1.2 on the same meshes (27 models, 937,814 triangles): 501,362 removed there, 501,172 here, differences as large as LU Toolbox's own between seeds. optimize_resolution is retired; remove_hidden_faces=0 makes the same files as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -135,9 +135,10 @@ and the notices (see Threads). Cars and rockets are made once per combination of
|
||||
0.025) either way, times the color's own amount (black 0.4, orange 1.5, ...), clamped and taken back; hue and
|
||||
saturation stay. The random number comes from the model's id, the brick's index and the material, so making a
|
||||
model again gives the same colors, and every LOD the same (LU Toolbox restarts its random sequence per LOD).
|
||||
4. Faces nobody can see are removed from the opaque bricks (they're rendered from 42 directions and triangles that
|
||||
never show are dropped; transparent bricks hide nothing and aren't touched). `hsr_ground_plane=1` also drops what
|
||||
can only be seen from below.
|
||||
4. Faces nobody can see are removed from the opaque bricks as LU Toolbox's Remove Hidden Faces decides it: paths are
|
||||
traced from points on each triangle, bouncing off the model, and a triangle none of whose paths reaches the sky is
|
||||
removed (see "Hidden faces" below). Transparent bricks hide nothing and aren't touched. `hsr_ground_plane=1` also
|
||||
drops what can only be seen from below.
|
||||
5. Ambient occlusion is baked like LU Toolbox's Bake Lighting with AO Only: 64 rays per vertex (`ao_samples`) over
|
||||
the hemisphere around the vertex normal (cosine weighted, the same pattern every time, so a model made again comes
|
||||
out the same), each blocked when it hits an opaque triangle within 5 (`ao_distance`); the vertex's occlusion is the
|
||||
@@ -209,7 +210,7 @@ and the notices (see Threads). Cars and rockets are made once per combination of
|
||||
| Transparent Opacity 58.82% | Same (`transparent_opacity`) |
|
||||
| Vertex color layers Col, Lit, Alpha (1), Glow | One color set: Col times Lit (glow added to Lit); alpha is the opacity |
|
||||
| Setup Bake Material (VertexColor / VertexColorTransparent) | Equivalent: white NiMaterialProperty, vertex colors as ambient and diffuse, NiAlphaProperty on transparent shapes |
|
||||
| Remove Hidden Faces: Cycles bakes with an overexposed world (VC pre-pass 32 samples, tris to quads, 5 pixels between vertices, 8 samples, threshold 0.01), autoremove, transparent bricks hidden | Same result by other means: depth renders from 42 directions (`optimize_resolution`), transparent bricks hidden and untouched; the pre-pass, quads and samples are details of Blender's baking |
|
||||
| Remove Hidden Faces: Cycles bakes with an overexposed world (VC pre-pass 32 samples, tris to quads, 5 pixels between vertices, 8 samples, threshold 0.01), autoremove, transparent bricks hidden | The same paths traced directly from points on the triangles, no texture (`hsr_samples` 8, `hsr_bounces` 8, `hsr_min_points` 28, `hsr_sample_spacing`); decided per triangle, not per joined quad; no VC pre-pass (see "Hidden faces") |
|
||||
| Use Ground Plane off | Same (`hsr_ground_plane=0`) |
|
||||
| Split objects over 65536 vertices (divide_mesh, along the longest side, linked parts together) | Same, also keeping each shape under 65535 triangles (the format's limit) |
|
||||
| Setup LOD data: SceneNode, NiLODNode per shape name, LOD nodes, near/far by the levels there are, `S01_Opaque_`/`S01_Alpha_` names cut at 60 | Same (`lod_distance_0..3`, `lod_cull`, `shader_opaque`); LU Toolbox's glow, metal and superemissive shader settings are unused by it too; the UGC server's own metal and glow groups are opt in (see below) |
|
||||
@@ -222,6 +223,56 @@ and the notices (see Threads). Cars and rockets are made once per combination of
|
||||
| Icon scene BrickBuild / Car: 50 mm lens, camera 53.4 / 19.5 degrees, sun at 21 / 50.3, 128 px, framing 1.03, transparent film | Same framing (`icon_*`); the light is brighter, to match the game's icons |
|
||||
| Icon scene Rocket: 35 mm lens, other angles, two suns | Not built in; a preset for the rocket build type can be set in the icon editor |
|
||||
|
||||
### Hidden faces
|
||||
|
||||
`UgcHsr::RemoveHiddenFaces` (`remove_hidden_faces=1`, default) traces the paths LU Toolbox's Remove Hidden Faces
|
||||
bakes, directly from points on the triangles, without its UV layout and texture. Each LOD's opaque mesh is done on its
|
||||
own, on the job's worker thread.
|
||||
|
||||
* What blocks: the LOD's opaque triangles (LU Toolbox hides the transparent bricks while it bakes). With
|
||||
`hsr_ground_plane=1`, LU Toolbox's ground plane: a black box 1000 x 1000 x 100 whose top is at LDD y 0; a path that
|
||||
hits it ends.
|
||||
* Points: on each triangle, rows parallel to its longest side `hsr_sample_spacing` apart (default 0.1143 LDD units, 7
|
||||
x 7 points on a stud-sized square), with points the same distance apart along each row. A triangle that gets fewer
|
||||
than `hsr_min_points` (default 28, the texels LU Toolbox bakes for every triangle) gets its rows and points closer
|
||||
together until it has that many; at most 4096 (bigger triangles get them further apart). Triangles without area
|
||||
draw nothing and are removed (LU Toolbox's bake leaves them dark too).
|
||||
* Paths: `hsr_samples` (default 8, LU Toolbox's Samples) from each point, each as Cycles 3.1 traces LU Toolbox's
|
||||
diffuse bake: the point is looked at along its vertex normal (the side it faces is baked; a triangle wound the other
|
||||
way is baked from its back, as Cycles does); the bake material (a new material's Principled BSDF: base color 0.8,
|
||||
specular 0.5, roughness 0.5, GGX) picks its diffuse part (Burley) or its specular part (GGX, Fresnel of IOR 1.5) by
|
||||
Cycles' sample weights (at the first point each weight is raised to an eighth of their sum; the specular part is
|
||||
blurred by Filter Glossy 1 after the first bounce) and the path bounces in the direction drawn. A bounce ray that
|
||||
hits nothing has reached the sky. A triangle hit from behind is lit on its back. At most `hsr_bounces` (default 8, the bake's Max Bounces) bounces, 4 of them
|
||||
glossy; from the second bounce on the path goes on with probability sqrt(throughput) (Russian roulette). The sky
|
||||
isn't sampled directly: Cycles doesn't sample a world of one flat color as a light, so only rays leaving the model
|
||||
count.
|
||||
* Decision: a triangle is kept as soon as one of its paths reaches the sky, removed when none does. LU Toolbox's
|
||||
threshold (0.01 of the baked average) means the same: its world's strength 100000 saturates every texel a path
|
||||
reaches.
|
||||
* The same every time: each path's random numbers come from the model's id, the triangle, the point and the sample.
|
||||
* Differences from LU Toolbox: triangles are decided on their own. LU Toolbox joins triangles into quads first (Tris
|
||||
to Quads) and keeps both halves of a quad when either is seen, so it keeps some triangles this removes. Big triangles
|
||||
get more points than LU Toolbox's fixed 7 x 7 texels. The VC pre-pass isn't done (below).
|
||||
* Cost: the paths from triangles that are seen stop at the first that leaves, so the time goes to the hidden ones
|
||||
(`hsr_min_points` x `hsr_samples` paths each at least). `hsr_min_points` and `hsr_samples` trade time for how
|
||||
reliably faces only just seen are kept. The long loop calls UgcThrottle's checkpoint. Measured (one thread, CPU
|
||||
time, LOD 0): 6 s for 69 bricks, 74 to 86 s for 250 to 330 bricks, 129 s for 883 bricks (the 42 depth renders used
|
||||
before took 1 to 4 s; LU Toolbox 3, 24 to 29 and 91 s on 8 threads).
|
||||
|
||||
Checked against LU Toolbox's operator in Blender 3.1.2 on the same meshes (VC pre-pass off, Tris to Quads off so it
|
||||
also decides per triangle; 27 models: a closed box, a house with a doorway, a room with a window, a tube, a cup and
|
||||
stacked plates built for it, 5 test LXFMLs and 16 player models of 1 to 883 bricks, 937,814 triangles): it removed
|
||||
501,362 triangles and the UGC server 501,172, with 9,370 only there and 9,180 only here, per model as far apart as
|
||||
LU Toolbox is from itself with another random seed. With the ground plane the same (5 models). The depth renders used
|
||||
before removed 191,900 triangles LU Toolbox keeps (faces reached only by bounced light).
|
||||
|
||||
LU Toolbox's VC pre-pass (on by default there, not done here): before the texture bake it bakes vertex colors (32
|
||||
samples, 12 bounces) and leaves out of the texture bake every face with a corner above the threshold. Those faces are
|
||||
kept without the texture bake's test, so with it LU Toolbox keeps somewhat more (for example 1865 instead of 2529
|
||||
triangles removed from a 61-brick model); it saves LU Toolbox baking texels for faces that are seen, which the paths
|
||||
here already stop early for.
|
||||
|
||||
### Metal and glow (on by default, not how live looked)
|
||||
|
||||
Live's models, LU Toolbox's exports and the client's own builder (`LUNifBuilder_BK`, which writes only `S01_Opaque`
|
||||
@@ -574,7 +625,7 @@ of old items' `.sd0` icons and checksums and of builds' combination ids runs on
|
||||
Settings in `ugcconfig.ini` (and the dashboard's settings page), picked up while running when the config is reloaded:
|
||||
|
||||
* `worker_threads` (restart): how many models are made at once.
|
||||
* `max_cpu_percent`: the workers together average at most this share of all CPU cores. The long loops (the renders
|
||||
* `max_cpu_percent`: the workers together average at most this share of all CPU cores. The long loops (the paths
|
||||
for hidden faces, the occlusion rays, icons) account each thread's CPU time every few milliseconds against a budget
|
||||
that fills at that rate and sleep while it's overdrawn (UgcThrottle), so it holds for long jobs too and whatever
|
||||
`worker_threads` is. Short bursts (a quarter second) aren't slowed. 0: no limit.
|
||||
|
||||
Reference in New Issue
Block a user