feat(environment): add painterly skies and living meadows
@@ -38,11 +38,11 @@ spawn is a next integration.
|
||||
`JajceWorld` owns reversible High, Balanced, and Low presentation profiles with
|
||||
instance-local mutable environment/grass resources and viewport-scale ownership.
|
||||
|
||||
| Profile | 3D scale | Shadow distance | Volumetric/glow | Grass |
|
||||
| Profile | 3D scale / MSAA | Shadow distance | Volumetric/glow | Grass |
|
||||
| --- | ---: | ---: | --- | --- |
|
||||
| High | authored | authored (currently 180 m) | authored when renderer supports it | authored density/interactors |
|
||||
| Balanced (default) | 0.85 cap | 120 m cap | authored ordinary lookdev; unsupported volumetric disabled | reduced spacing/interactors/update rate |
|
||||
| Low | 0.70 cap | 80 m, orthogonal | volumetric/glow/adjustment disabled; ordinary fog retained | hidden/stopped, emitters off, shader interactors zero |
|
||||
| High | authored / authored 4× | authored (currently 180 m) | authored when renderer supports it | authored density/interactors |
|
||||
| Balanced (default) | 0.85 cap / 2× cap | 120 m cap | authored ordinary lookdev; unsupported volumetric disabled | reduced spacing/interactors/update rate |
|
||||
| Low | 0.70 cap / off | 80 m, orthogonal | volumetric/glow/adjustment disabled; ordinary fog retained | hidden/stopped, emitters off, shader interactors zero |
|
||||
|
||||
UI remains at native resolution. High/Low switches restore captured authored
|
||||
values; viewport scale restoration is guarded by the current quality owner so a
|
||||
@@ -103,7 +103,7 @@ profession tint, velocity-driven motion, inventory cues and death through the
|
||||
existing presentation controllers. No saved state or navigation changes.
|
||||
|
||||
Characters and buildings use soft cel bands; tree crowns retain the shared
|
||||
breeze with painted color patches. A static procedural cloud sky, cooler
|
||||
breeze with painted color patches. A painted cloud panorama, cooler
|
||||
ambient fill and warm sunlight follow the simulation day/night clock. The
|
||||
cloud shader adds no volumetric pass, outline pass or screen-space postprocess.
|
||||
See [the asset contract and rebuild commands](../assets/storybook/README.md).
|
||||
@@ -161,3 +161,85 @@ ledger, not brittle cross-machine CI thresholds.
|
||||
|
||||
See [the benchmark ledger](benchmarks/README.md), [regional contract](REGIONAL_SIMULATION.md),
|
||||
and [the build-in-public visual plan](BUILD_IN_PUBLIC_PLAN.md).
|
||||
|
||||
## Painterly environment pass — September 2026
|
||||
|
||||
The reference study highlighted flat cloud bands, primitive tree silhouettes,
|
||||
sparse ground cover, opaque green water, and a sun arc offset from daytime
|
||||
brightness. The current pass addresses those through shared presentation assets:
|
||||
|
||||
- The WorldEnvironment uses cool blue ambient fill, warm sunlight, restrained
|
||||
glow and ordinary aerial fog. The solar arc now peaks at noon and the warm
|
||||
transitions overlap dawn/dusk. An original painted cloud panorama supplies
|
||||
layered cumulus shapes; a static sky shader remaps the artwork, blends its
|
||||
seam/horizon, and tints it from the simulation clock. It adds no TIME-driven
|
||||
cubemap updates or volumetric cloud pass. Generation provenance and the exact
|
||||
prompt are in [the asset guide](../assets/painterly/README.md).
|
||||
- Original Blender broadleaf crowns/trunks and layered conifers replace the
|
||||
primitive foliage. Seventeen decorative edge trees form a woodland backdrop.
|
||||
The four village tree placeholders now use `HarvestableTreePresentation`,
|
||||
retaining their existing IDs, amounts, interaction points and resource count.
|
||||
Full/low/depleted state and restored crowns still derive from real amounts.
|
||||
- `PainterlyMeadow` creates at most 1,680 decorative flower clumps in four
|
||||
MultiMesh batches, with cream daisies, pink cosmos, buttercups and lavender.
|
||||
Local seeded drifts follow terrain and exclude houses, paths, work sites and
|
||||
resource approach points. High/Balanced/Low expose at most 1,680/1,092/536
|
||||
clumps, with shorter distance fading in cheaper profiles. Flowers share the
|
||||
prevailing breeze; the existing grass and berry contact field remains intact.
|
||||
Explicit white instance colors preserve the painted GLB palette when custom
|
||||
instance data is enabled in Compatibility; native review caught and verified
|
||||
that renderer-specific regression.
|
||||
Flowers have no collision, harvesting, actor-contact deformation or saved
|
||||
state. See [mesh sources and budgets](../assets/meadow/README.md).
|
||||
- The blue/turquoise river follows actual centerline terrain heights, keeps
|
||||
level cross-sections, and clips dry edges at the shoreline. The pool and its
|
||||
outlet meet without overlapping coplanar transparent sheets. Broken foam,
|
||||
subtle flowing strokes and painted reflection patches replace the hard ring
|
||||
and featureless surface. These reflections are stylized procedural patches
|
||||
plus ordinary sky specular response, not exact reflected scene geometry,
|
||||
screen-space reflections, refraction or depth sampling. Water obeys scene
|
||||
lighting at night and adds no per-frame scripts.
|
||||
- MSAA follows the existing viewport ownership rules: High preserves authored
|
||||
4×, Balanced caps at 2×, and Low disables it. Closing an inactive world cannot
|
||||
overwrite the active world's antialiasing or an external viewport override.
|
||||
|
||||
The editable Blender sources live under `art/painterly/` and `art/meadow/`,
|
||||
protected by `.gdignore`; runtime consumes portable GLBs. The broadleaf is
|
||||
5,350 triangles / five surfaces and the conifer is 1,580 / two. All flower
|
||||
clumps together are capped at 362,880 triangles / four surfaces before
|
||||
quality and distance reduction. No scene collision, navigation bake, terrain
|
||||
heightmap, simulation rule or save schema was changed.
|
||||
|
||||
`tools/capture_painterly_environment.gd -- --label=after` captures the running
|
||||
main scene with paused simulation, fixed daytime presentation and hidden HUD,
|
||||
including the normal gameplay camera, valley, lower village view and night.
|
||||
The valley/near-village `painterly_before_*` and `painterly_after_*`
|
||||
images are matched cameras; `after_gameplay` fixes the normal rig at its default
|
||||
yaw/zoom with mouse input disabled, and `after_vista` is an additional review angle.
|
||||
The tool also records static-camera profile samples in
|
||||
`painterly_after_metrics.json`; wall-frame latency includes vsync and is not
|
||||
isolated GPU time or weak-PC proof. Runtime camera defaults are unchanged.
|
||||
|
||||
Remaining visual work is primarily authored terrain/shoreline detail and the
|
||||
blockout-like building/fortress forms. This pass improves atmosphere and
|
||||
foliage without treating those assets as finished film-quality environments.
|
||||
|
||||
Validation for this pass: the full macOS Godot 4.7 gate passed, including all
|
||||
headless scenarios, the Compatibility quality scenario, and 182 GUT tests /
|
||||
2,279 assertions. Main-scene headless startup passed the gate's existing exact
|
||||
diagnostic allowlist. Native Metal daytime/gameplay/valley/night images were
|
||||
reviewed at 1600×900, with a separate native Compatibility capture confirming
|
||||
colored petals after the instance-buffer fix. The presentation-quality scenario
|
||||
also passed with native Compatibility, including white instance-color readback
|
||||
(the headless dummy renderer cannot provide that readback).
|
||||
The static M1 Max sample reports approximately 16.7 ms
|
||||
median wall-frame time in all three profiles; see its JSON for p95, draw calls
|
||||
and primitives. This includes vsync and does not establish GPU headroom.
|
||||
|
||||
Native renderer shutdown still reports the particle shader/material RID
|
||||
retention previously documented in the storybook/foliage pass; the headless
|
||||
allowlist was not expanded. Compatibility has different color/tonemapping and
|
||||
its existing particle/texture shutdown diagnostics. Metal is the color
|
||||
reference for the saved art-review images.
|
||||
The native multi-world quality scenario additionally logged a transient macOS
|
||||
OpenGL cubemap-unloadable diagnostic; the final main-scene captures did not.
|
||||
|
||||
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.3 MiB |
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"device": "Apple M1 Max (Apple7)",
|
||||
"renderer": "metal",
|
||||
"resolution": "1600x900",
|
||||
"samples": [
|
||||
{
|
||||
"active_npcs": 6,
|
||||
"draw_calls": 825.0,
|
||||
"meadow": {
|
||||
"flower_clump_count": 1680,
|
||||
"multimesh_batch_count": 4,
|
||||
"visible_flower_clump_count": 1680
|
||||
},
|
||||
"msaa_enum": 2,
|
||||
"primitives": 1070038.0,
|
||||
"profile": "high",
|
||||
"render_scale": 1.0,
|
||||
"wall_frame_p50_ms": 16.649,
|
||||
"wall_frame_p95_ms": 17.327
|
||||
},
|
||||
{
|
||||
"active_npcs": 6,
|
||||
"draw_calls": 710.0,
|
||||
"meadow": {
|
||||
"flower_clump_count": 1680,
|
||||
"multimesh_batch_count": 4,
|
||||
"visible_flower_clump_count": 1092
|
||||
},
|
||||
"msaa_enum": 1,
|
||||
"primitives": 810830.0,
|
||||
"profile": "balanced",
|
||||
"render_scale": 0.850000023841858,
|
||||
"wall_frame_p50_ms": 16.672,
|
||||
"wall_frame_p95_ms": 17.06
|
||||
},
|
||||
{
|
||||
"active_npcs": 6,
|
||||
"draw_calls": 657.0,
|
||||
"meadow": {
|
||||
"flower_clump_count": 1680,
|
||||
"multimesh_batch_count": 4,
|
||||
"visible_flower_clump_count": 536
|
||||
},
|
||||
"msaa_enum": 0,
|
||||
"primitives": 645010.0,
|
||||
"profile": "low",
|
||||
"render_scale": 0.699999988079071,
|
||||
"wall_frame_p50_ms": 16.676,
|
||||
"wall_frame_p95_ms": 17.069
|
||||
}
|
||||
],
|
||||
"workload": "Paused main scene, static valley camera; wall time includes vsync"
|
||||
}
|
||||
|
After Width: | Height: | Size: 709 KiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 815 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.6 MiB |
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"device": "Apple M1 Max",
|
||||
"renderer": "opengl3",
|
||||
"resolution": "1600x900",
|
||||
"samples": [
|
||||
{
|
||||
"active_npcs": 6,
|
||||
"draw_calls": 1304.0,
|
||||
"meadow": {
|
||||
"flower_clump_count": 1680,
|
||||
"multimesh_batch_count": 4,
|
||||
"visible_flower_clump_count": 1680
|
||||
},
|
||||
"msaa_enum": 2,
|
||||
"primitives": 1070038.0,
|
||||
"profile": "high",
|
||||
"render_scale": 1.0,
|
||||
"wall_frame_p50_ms": 22.166,
|
||||
"wall_frame_p95_ms": 23.467
|
||||
},
|
||||
{
|
||||
"active_npcs": 6,
|
||||
"draw_calls": 1166.0,
|
||||
"meadow": {
|
||||
"flower_clump_count": 1680,
|
||||
"multimesh_batch_count": 4,
|
||||
"visible_flower_clump_count": 1092
|
||||
},
|
||||
"msaa_enum": 1,
|
||||
"primitives": 810758.0,
|
||||
"profile": "balanced",
|
||||
"render_scale": 0.850000023841858,
|
||||
"wall_frame_p50_ms": 17.903,
|
||||
"wall_frame_p95_ms": 26.363
|
||||
},
|
||||
{
|
||||
"active_npcs": 6,
|
||||
"draw_calls": 1084.0,
|
||||
"meadow": {
|
||||
"flower_clump_count": 1680,
|
||||
"multimesh_batch_count": 4,
|
||||
"visible_flower_clump_count": 536
|
||||
},
|
||||
"msaa_enum": 0,
|
||||
"primitives": 645010.0,
|
||||
"profile": "low",
|
||||
"render_scale": 0.699999988079071,
|
||||
"wall_frame_p50_ms": 13.533,
|
||||
"wall_frame_p95_ms": 16.623
|
||||
}
|
||||
],
|
||||
"workload": "Paused main scene, static valley camera; wall time includes vsync"
|
||||
}
|
||||
|
After Width: | Height: | Size: 469 KiB |