feat(environment): add painterly skies and living meadows

This commit is contained in:
Rijad Zuzo
2026-09-05 20:27:09 +02:00
parent 7899d36f03
commit ec16e2f2ca
71 changed files with 2280 additions and 213 deletions
+59
View File
@@ -0,0 +1,59 @@
# Painterly valley assets
Original broadleaf and evergreen meshes created in Blender for The Steward.
Scalloped crowns, painted vertex variation, crooked forks and root flares replace
the primitive tree silhouettes. Editable sources are in `art/painterly/`;
`.gdignore` keeps Blender outside Godot's runtime import dependencies. The two
portable GLBs use opaque geometry without textures or alpha cards.
## Rebuild and mesh budget
From the project root, using Blender 5.1 and Godot 4.7:
```sh
"$BLENDER_BIN" --background --python tools/art/build_painterly_trees.py
"$GODOT_BIN" --headless --editor --path "$PWD" --import
```
Use the isolated Godot profile configured by `tools/quality.sh` for headless
validation. Runtime consumes the GLBs directly; no mesh-extraction step is
needed. Preserve their `.import` files when updating exports.
| Geometry | Triangles | Surfaces |
| --- | ---: | ---: |
| Shared broadleaf crown | 1,236 | 1 |
| Joined broadleaf trunk, forks and roots | 406 | 1 |
| Complete broadleaf: four crowns plus trunk | 5,350 | 5 |
| Complete conifer: boughs plus trunk | 1,580 | 2 |
`tree_mesh_budget.json` records these export counts. The broadleaf GLB is
45,676 bytes; the conifer GLB is 40,836 bytes and stands 3.10 m before placement
scaling. A separate temporary rebuild with Blender 5.1.2 produced byte-identical
copies of both GLBs and the budget JSON. This establishes generator
reproducibility with that Blender version, not identical `.blend` serialization
across versions.
`StylizedTree` shares imported meshes and isolates crown tint/wind materials.
Its four direct `Canopy*` children retain the existing thinning and stump
presentation contract. `PainterlyConifer` shares imported bough/trunk meshes.
Both use the same world-direction breeze and explicit painted bark colors;
neither adds simulation state, collision or per-frame GDScript work.
## Painted sky provenance
`painted_sky.png` is an original 1774 × 887 image generated with the built-in
ImageGen tool, rather than a CLI generator. The prompt asks for a painted
cumulus panorama with warm ivory cloud tops, cool turquoise cloud shadows and
a clear blue summer atmosphere. Film references informed the color and mood;
no external film image was copied into the texture. The exact generation
prompt is recorded in [sky_prompt.md](sky_prompt.md).
`storybook_sky.gdshader` maps the panorama's horizon at 69% of its height onto
the upper hemisphere, repeats the painted band twice around the azimuth to
retain cloud proportions, blends its seam/edge into haze, and follows the existing
day/night palette. The image supplies the sky backdrop only; it does not paint
terrain or create volumetric clouds.
Final renderer QA and the complete project quality gate belong to the
integrated environment review. See the [presentation guide](../../docs/FEATURE_PRESENTATION_PERFORMANCE.md)
for current verification evidence and remaining hardware limits.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

+40
View File
@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dmkubk6dhhyis"
path="res://.godot/imported/painted_sky.png-9888802278aff2f83effdab2649f1f05.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/painterly/painted_sky.png"
dest_files=["res://.godot/imported/painted_sky.png-9888802278aff2f83effdab2649f1f05.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.
@@ -0,0 +1,45 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://clcvatvbyixma"
path="res://.godot/imported/painterly_conifer.glb-596d48094a6a072cfc85374d478c7bbe.scn"
[deps]
source_file="res://assets/painterly/painterly_conifer.glb"
dest_files=["res://.godot/imported/painterly_conifer.glb-596d48094a6a072cfc85374d478c7bbe.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
mesh_library/use_node_names_as_mesh_names=false
array_mesh/deduplicate_surfaces=true
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1
gltf/texture_map_mode=1
Binary file not shown.
@@ -0,0 +1,45 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://blu5r5vupqvpd"
path="res://.godot/imported/painterly_tree.glb-12cb20acdabe08bb0fe06cba12958067.scn"
[deps]
source_file="res://assets/painterly/painterly_tree.glb"
dest_files=["res://.godot/imported/painterly_tree.glb-12cb20acdabe08bb0fe06cba12958067.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
mesh_library/use_node_names_as_mesh_names=false
array_mesh/deduplicate_surfaces=true
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
gltf/naming_version=2
gltf/embedded_image_handling=1
gltf/texture_map_mode=1
+35
View File
@@ -0,0 +1,35 @@
# Painted sky provenance
Created for this project with the built-in imagegen tool on 2026-09-05.
Original output: 1774 × 887 PNG, copied without pixel editing to
`assets/painterly/painted_sky.png`. The sky shader samples the upper portion
and blends its horizon into the simulation-driven day/night palette.
No film frame or downloaded artwork is used as a runtime texture.
## Generation prompt
Use case: stylized-concept. Asset type: original 360-degree panoramic sky
texture for a Godot game, 2:1 equirectangular landscape, ideally 3072x1536.
Create ONLY SKY, absolutely no ground, hills, buildings, ocean, objects, text
or sun disk. Art direction: exquisitely hand-painted Japanese animation
background, Studio Ghibli inspired summer pastoral fantasy, gouache brush
texture, saturated clear turquoise-blue atmosphere, towering luminous cumulus
clouds with creamy warm sunlit edges, intricate scalloped billowing forms,
pale cyan and slate blue softly painted shadow volumes. Composition is a full
spherical sky environment texture: upper half of image shows the upward
hemisphere, zenith at top is mostly deep clean blue, large beautiful cumulus
towers occupy the upper middle band between y=15% and y=44%, and the horizon
at exactly image vertical halfway is uniform pale atmospheric aqua. Lower
half is entirely an unobtrusive smooth pale aqua color gradient, with NO
landscape. Cloud coverage about 40% of upper hemisphere, generous varied blue
gaps, asymmetrical naturally spaced cloud masses. Left and right edges must
wrap seamlessly in color and shape, keep thin strips at far left/right clear
sky to avoid seam. No photographic cloud noise, no 3D render or vector
outlines, no flat cartoon circles. Painterly refined layered brushwork like a
cinematic animated film background, not a flat gradient. Use only original
cloud shapes; no copied film imagery.
The returned image does not exactly meet the requested resolution or horizon
position. The runtime shader uses its actual dimensions and remaps the painted
horizon at 69% image height. Blender mesh assets are deterministic rebuilds;
this generated image is a pinned art asset, not a deterministic generator output.
+24
View File
@@ -0,0 +1,24 @@
{
"Canopy": {
"triangles": 1236,
"surfaces": 1,
"vertices": 712
},
"Trunk": {
"triangles": 406,
"surfaces": 1,
"vertices": 221
},
"runtime_tree": {
"triangles": 5350,
"surfaces": 5,
"shared_meshes": 2
},
"glb_bytes": 45676,
"conifer": {
"triangles": 1580,
"surfaces": 2,
"height_m": 3.1,
"glb_bytes": 40836
}
}