# Stylized Asset Generators (Blender Addons) > Dieses Repo liefert **zwei** Extensions ueber **eine** URL: > > | Addon | Panel | Zweck | > |---|---|---| > | **Stylized Rock Generator** | *Rock Gen* | Batch-Rocks + Textur-Bake + FBX/LOD-Export | > | **Stylized Tree Generator** | *Tree Gen* | Baeume/Palmen/Bueschen/Kakteen (Geometry Nodes) mit Wachstums-Stufen | > | **Stylized Grass Generator** | *Grass Gen* | Gras/Blumen/Farne mit Wind-UV fuer `SimpleGrassWind` | > > Ein Blender-Extension-Repo kann mehrere Extensions ausliefern — `server-generate` > listet jedes Zip in `dist/`. Ein „Check for Updates" aktualisiert also beide. --- ## EcoGame-Konventionen (beide Addons) Abgestimmt auf `A:\eco\EcoGame` (UE 5.8). Kurzfassung: **Benennung** - Felsen: `Fels_
_` — Form = Buchstabe (A, B, …), Klasse = `S/M/L/XL`. Die Klasse setzt eine **Basis-Groesse** (S=0.45, M=1.0, L=1.9, XL=3.2) und ist damit ein bewusst anderes Asset — gemessen: S 0.85 m, M 1.9 m, L 3.5 m, XL 6.0 m. Davon strikt getrennt ist die **Zufalls-Streuung** (`scale_min/max`): die variiert nur die FORM und wird von „Gesamtgroesse konstant halten" auf konstantes Volumen normiert (1.11× statt 1.92×), damit sie sich nicht mit den ScaleMin/Max der Engine multipliziert. - Baeume: `__S`, z. B. `Birke_01_S1` … `Birke_01_S4`. Zusatz-Ebenen haengen hinten an: `_Leaf`, `_Frucht`. - Texturen: `_albedo` und `_normal` — mehr nicht. **Textur-Bake** - Nur **Albedo + Normal**. Roughness ist im Master-Material eine **Zahl**, keine Textur. - **AO/Cavity wird ins Albedo multipliziert** (Option „AO ins Albedo einrechnen", Staerke regelbar). Dunkle Ritzen und helle Platten stecken im Farbbild — das traegt den Stylized-Look. Separate Rough-/AO-Paesse sind Default **aus**. - **Plattenstil (Genshin-Referenz):** Die Textur besteht aus **wenigen grossen, fast leeren Platten** mit **schmalen dunklen Fugen** — das Detail steckt in der Fuge, nicht in der Flaeche. Regler: `Plattengroesse` (kleiner = groessere Platten), `Fugenbreite` (klein = harte Fuge, flache Platte), `Platten flach` (1 = Flaeche nahezu einfarbig). Ein dichtes Zellmuster ueber die ganze Oberflaeche erschlaegt die Form und passt NICHT zu diesem Look. - **Vertex-Farb-Layout v2 (kanal-getrennt), Attribut `Cavity`:** | Kanal | Inhalt | |---|---| | **R** | Cavity pur — 1 = offene Flaeche, 0 = tiefe Fuge (**ohne** Hoehen-Verlauf) | | **G** | Moos-/Schmutzmaske — 1 = hier waechst was (Oberseite + Fugennaehe + Noise) | | **B** | Hoehen-Verlauf — 0 = Unterseite, 1 = oben | | **A** | 1 (Reserve) | Getrennt statt eingebacken: der erdige **Boden-Saum** am Stein-Fuss und die **Moosfarbe** werden pro Material-Instanz geregelt, nicht im Mesh festgelegt. Regler: `Cavity-Staerke`, `Weichzeichnen`, `Moos-Menge`, `Moos-Aufbruch`, `Moos-Seed`. Verifiziert: R ohne Hoehenabhaengigkeit (unten 0.62 / oben 0.59), B steigt sauber (0.08 -> 0.92), G oben staerker (0.20 -> 0.57), A konstant 1, Seed aendert die Verteilung, und alle Kanaele ueberleben den FBX-Roundtrip. - **Texturfreie Alternative — Vertex-Cavity:** Statt zu baken laesst sich die Cavity in die **Vertex-Farben** schreiben (Attribut `Cavity`, ueberlebt den FBX-Roundtrip verlustfrei — gemessen 0.250..0.947 vor und nach dem Import). Das Material braucht dann **keine Textur**: `Base Color = Farbton x VertexColor`, dazu Kantenlicht (Fresnel) und Schattentint. Vorteil gegenueber Triplanar: die dunklen Fugen sitzen auf den ECHTEN Kanten des Meshes statt darueberzuschweben. Grenze: die Aufloesung haengt an der Vertex-Dichte — fuer flaechige Platten reicht sie, fuer feine Struktur nicht. - 1024 px reicht fuer stylized Formen. - Tileable (4D-Torus) passt zum triplanar mappenden Master-Material. **Mesh** - Echte Meter, Ursprung unten-mittig, FBX pro Asset bzw. LOD-Gruppe. - **UV1 Lightmap ist Default aus** — EcoGame beleuchtet dynamisch. - Meshes brauchen **keine eigenen Materialien**; in UE bekommt alles die Material-Instanz vom Master. Ein Platzhalter im FBX ist okay. - Scale-Randomisierung nur fuer die **Form** (nicht-uniform) nutzen, nicht fuer die Gesamtgroesse — sonst multipliziert sie sich mit ScaleMin/Max der Engine. --- ## Stylized Grass Generator Gras-, Blumen- und Farn-Bueschel. Der Kern ist die **Wind-UV**: - **UV0.V = 0 an der Wurzel, 1 an der Spitze** — genau die Maske, die UEs `SimpleGrassWind` als *WindWeight* braucht. Ohne sie rutscht der Halm beim Wehen vom Boden weg oder bewegt sich gar nicht. Am Zielmaterial `M_Grass` geprueft: es liest `TextureCoordinate`, aber **keine** `VertexColor` — deshalb liefert der Generator die Maske PRIMAER ueber die UV. Die Assets funktionieren damit **ohne Materialaenderung**. - **Vertex-Farben zusaetzlich** (nicht als einzige Quelle): `R` = Kopie der Windmaske · `G` = Variation je HALM · `B` = AO (unten dunkel). `G` ist die Ebene **unter** dem Biom-Tint, den die Engine ueber `PerInstanceCustomData 0/1` pro Instanz setzt — im Material **multiplizieren**, nicht ersetzen. - Presets: `gras`, `gras_hoch`, `steppengras`, `farn`, `blume`. - Tri-Budget-Warnung (Default 400 laut `ASSETS.md` fuer Gras/Blume). Gemessen: ein Standard-Bueschel mit 14 Halmen = **112 Tris**. - Ursprung unten-mittig (`min_z = 0.0000`), UV und Vertex-Farben ueberleben den FBX-Roundtrip. --- ## Stylized Tree Generator Parametrischer **Geaest**-Generator (Stamm + Aeste + Sub-Aeste) als Geometry-Nodes- Gruppe. Blaetter/Krone macht man selbst — das Addon liefert die Struktur. - **Presets:** `baum`, `palme`, `busch`, `tanne`, `eiche`, `birke`, `weide`, `toter_baum`, `kaktus` — die Silhouette steuert die **Kronenform** (`Crown Taper` / `Crown Bulge`, Idee aus modular_tree / Weber-Penn). - **Tri-Budget:** alle Presets liegen unter dem Projektlimit (Baum ≤2500, Busch ≤800). Stellschrauben: `Detail` (Segmente) und `Sides` / `Branch Sides` / `Sub Sides` (Profilaufloesung je Ebene — Stamm rund, Zweige nur Dreiecke). - **Wachstums-Stufen:** Haken setzen + Anzahl waehlen → Setzling bis ausgewachsen, **gleicher Seed = dieselbe Baum-Identitaet** (fuer Wachstums-Systeme im Spiel). - **Live bearbeiten:** Nach dem Erzeugen liegen alle Regler am Modifier `GN_Tree` — im Viewport ziehen, der Baum aktualisiert sich sofort. - **Blattwerk:** Ein Blatt-/Billboard-Objekt als *Blatt-Card* waehlen (z. B. eine Diamond-Plane mit Alpha-Textur) → der Button streut es auf die **Zweige** und legt das Ergebnis als `_Leaf` mit identischem Ursprung ab. Gefiltert wird ueber den Astradius (`Max Radius`), damit keine Blaetter am Stamm kleben. Ohne Card bleibt `_Leaf` leer zum Selbermodellieren. - **Tri-Budget:** Der Blattwerk-Button meldet `Stamm + Blatt = Summe` und **warnt** bei Ueberschreitung. Default-Dichte 150 haelt auch das schwerste Preset (Eiche, 1428 Tris) mit 2460 von 2500 Tris im Budget. - **Export:** „Modifier anwenden" friert das Ergebnis als normales Mesh ein. **v1.1.0:** Aeste folgen jetzt der Elternkurve (Tangent/Normal aus *Curve to Points*, Goldener Winkel = Phyllotaxis) statt einer aus Weltkoordinaten gerechneten Richtung — Sub-Aeste standen vorher wie Nadeln quer zum Ast. Neu: `Tip Blunt` (Baum laeuft spitz aus, Kaktus endet stumpf). Der `kaktus` nutzt `Droop Curve` fuer den Saguaro-Ellbogen (Arm laeuft flach raus und knickt dann steil hoch). Offen ist dort nur, dass die Rippen (`Ribs`) im Shading kaum sichtbar sind. --- # Stylized Rock Generator (Blender Addon) Batch-Generator fuer stylized Rocks in Blender, ausgelegt auf den Export nach **Unreal Engine 5** ueber FBX. Pipeline pro Rock: Basis-Mesh (Cube / Ico-Sphere) → Subdivision Surface → Displace mit prozeduraler Noise-Textur (Voronoi / Clouds / Distorted Noise) → zweistufiges Decimate → Limited Dissolve → Normalen-Reparatur → UV0 (Smart Project) + UV1 (Lightmap) → optional Bevel/Weighted Normal, Material, LOD-Set, randomisierte Skalierung/Rotation. Getestet mit **Blender 5.1.2** (Minimum laut `bl_info`: 4.2). --- ## Installation 1. `stylized_rock_generator.py` herunterladen. 2. Blender → *Edit → Preferences → Add-ons → Install…* → die `.py` waehlen. 3. Haken bei **Stylized Rock Generator** setzen. 4. Panel: *View3D → Sidebar (N) → Reiter "Rock Gen"*. Update: einfach die neue `.py` erneut installieren (gleicher Modulname) oder das Repo lokal ziehen und den Addon-Pfad in den Preferences auf den Repo-Ordner zeigen lassen. ## Installation als Extension (via URL, mit Auto-Update) Ab Blender 4.2 / 5.x als **Remote-Extension-Repository** – einmal die URL eintragen, danach gehen Updates per Klick. 1. Das Gitea-Repo muss **oeffentlich** sein (sonst kann Blender die Raw-URL nicht ohne Login laden). 2. Blender → *Edit → Preferences → Get Extensions → oben rechts das Dropdown → Repositories → „Add Remote Repository"*. 3. Als URL eintragen: ``` https://git.d4rkst3r.de/D4rkst3r/stylized-rock-generator/raw/branch/main/dist/index.json ``` 4. „Check for Updates" aktivieren, bestaetigen. Die Extension erscheint in der Liste → *Install*. **Updaten (Maintainer-Seite):** 1. `version` in `blender_manifest.toml` (und `bl_info["version"]` in der `.py`) erhoehen. 2. `./build.ps1` (oder `blender --command extension build …` + `… server-generate …`). 3. `git add -A && git commit -m "vX.Y.Z" && git push`. 4. Nutzer: in Blender *Check for Updates* → *Update*. Das gebaute Zip + `index.json` liegen in `dist/` und werden bewusst mitversioniert, damit die Raw-URL sie ausliefert. --- ## Features - **Basis-Formen:** Wuerfel, **Quader** oder Ico-Sphere, einstellbare Subsurf-Stufen. Der Quader hat frei einstellbare `Quader-Proportionen` (X/Y/Z) plus `Proportions-Streuung` — damit entstehen flache **Platten** und langgestreckte **Riegel** statt nur runder Brocken. Gemessen bei Proportion (2.0, 1.5, 0.35): 3.43 / 2.56 / 0.79 m — Z also 23 % von X. Die Proportionen werden auf die MESH-DATEN angewendet, nicht auf das Objekt: der Displace nutzt globale Texturkoordinaten, eine Objekt-Skalierung wuerde das Rauschen mitverzerren statt die Form zu aendern. - **Noise/Displace:** Voronoi / Clouds / Distorted Noise, Scale + Staerke, Seed. Seed-Variation ueber einen moderaten Welt-Offset (±25) vor dem Displace-Apply – Blenders prozedurale Texturen haben keinen echten Seed-Parameter. - **Cleanup:** zweistufiges Decimate + Limited Dissolve, danach `normals_make_consistent` (verhindert eingefallene/dunkle Flaechen). - **UV fuer Unreal:** UV0 (Smart Project) fuer Material-Texturen, UV1 (Lightmap) als separater, nicht ueberlappender Kanal fuer Static-Mesh-Lightmaps. - **Hard-Surface (optional):** Bevel + Weighted Normal fuer einen "clean" Kantenlook. - **Material (Platzhalter):** weist pro Rock ein Material zu und rotiert durch eine kleine Palette (Granite/Basalt/Sandstone/Mossy), damit nichts materiallos exportiert wird. - **LOD-Set:** erzeugt LOD0–LODn als LOD-Gruppe fuer Unreal (siehe unten). - **Presets:** eingebaute Presets (Kleiner Kiesel, Grosser Bruchfels, Lava-Rock) plus eigene Presets als JSON (`rock_presets.json` neben dem Addon). - **Batch:** synchron fuer kleine Mengen, ab `modal_threshold` (Default 25) automatisch **modal mit Progress-Bar** – die UI bleibt bedienbar, ESC bricht ab. - **Robustheit:** Faellt ein einzelner Rock aus (z. B. 0 Faces nach zu aggressivem Decimate), wird nur dieser uebersprungen und aufgeraeumt, der Rest des Batches bleibt erhalten. Fehler landen in der System-Konsole. --- ## LOD-Export nach Unreal Blenders FBX-Exporter kennt **keine** eigene LOD-Option. Unreal erkennt eine LOD-Gruppe aber, wenn das Eltern-**Empty** die Custom Property `fbx_type = "LodGroup"` traegt und die LOD-Meshes in Reihenfolge (LOD0…LODn) darunter geparentet sind. Genau das erzeugt der Generator. Beim FBX-Export darauf achten: - **Custom Properties** aktivieren (sonst geht `fbx_type` verloren). - Nur die LOD-Gruppe (Empty + Kinder) selektieren, `use_selection` an. Beim Import in Unreal: - Im FBX-Import-Dialog **Import LODs** aktivieren. Referenz: [Importing Static Mesh LODs Using FBX (UE Docs)](https://dev.epicgames.com/documentation/en-us/unreal-engine/importing-static-mesh-lods-using-fbx-in-unreal-engine). --- ## Tests ```bash blender --background --python tests/test_rock_gen.py ``` Weitere Suiten (jeweils `blender --background --python `): | Datei | prueft | |---|---| | `tests/test_tree_addon.py` | Tree-Addon: Presets, Wachstums-Stufen, UVs, Modifier-Apply | | `tests/test_ecogame_rock.py` | Fels-Benennung, Bake liefert nur `_albedo`/`_normal`, AO im Albedo | | `tests/test_ecogame_tree.py` | Baum-Benennung `__S`, Ursprung, Lightmap-Default | | `tests/test_randomize.py` | Zufalls-Funktion beider Addons, `_Leaf`/`_Frucht` mit gleichem Ursprung | | `tests/test_leaves.py` | Blattwerk: Streuung, Ursprung, Tri-Budget, leeres `_Leaf` ohne Card | | `tests/test_rock_classes.py` | Groessen-Klassen S/M/L/XL unterscheiden sich, Streuung bleibt formbezogen | Die Suiten erwarten die gebauten Zips in `dist/` bzw. lesen die `.py` direkt. Erzeugt 3 Rocks, prueft je Rock: keine losen Vertices, manifold, Normalen nach aussen (signed volume > 0), UV0 + UV1 vorhanden, und gibt eine Zusammenfassung (Vertex-/Face-Count) aus. Exit-Code 0 = alles bestanden, 1 = Fehler. --- ## Changelog v2.3.0 - **Textur-Bake auf Zell-Look umgestellt:** Voronoi „Distance to Edge" liefert hand-painted Zellen mit dunklen Outlines statt organischem fBm-Rauschen. Neu regelbar: **Grundfarbe** und **Zellgroesse**. Weiterhin nahtlos tileable. ## Changelog v2.2.0 - **Textur-Bake-Button:** backt ein nahtlos **tileables** Stylized-Rock-Set (BaseColor / Normal / Roughness / AO) als PNG. Nahtlos durch **4D-Torus- Projektion** der UV (`cos/sin` von U und V) → tilet in beide Richtungen ohne Naht, ideal fuer **Triplanar** in Unreal. - Anleitung zur UE-Material-Verdrahtung: siehe [docs/UE_Material_Triplanar.md](docs/UE_Material_Triplanar.md). ## Changelog v2.1.0 - **FBX-Export-Button (UE-ready):** exportiert jeden Rock / jede LOD-Gruppe als eigene FBX mit `use_custom_props=True` (fuer `fbx_type=LodGroup`), Triangulate und passendem Smoothing (`EDGE` bei Auto-Smooth, sonst `FACE`). *UE-Import-Tipp:* Normal Import Method auf „Import Normals" stellen, „Import LODs" an. - **Shading-Toggle:** Faceted / Smooth / Auto-Smooth-nach-Winkel. - **Pro-Rock-Varianz:** Noise-Scale & Displace-Staerke zwischen Min/Max plus optionale nicht-uniforme Skalierung → ein Batch wirkt variantenreich. - **Boden abflachen (Bisect) + Origin unten-mittig** → Rocks stehen in UE plan auf. ## Changelog v2.0.0 Gehaertet & erweitert gegenueber v1.0.0: - **Bugfix:** `smart_project(angle_limit=…)` ist in Blender 4.x/5.x in **Radiant** (`[0, 1.5708]`) – der alte Wert `66.0` war ungueltig. Jetzt `radians(66°)`. - **Bugfix:** `dissolve_limited(angle_limit=…)` erwartet **Radiant**; der Grad-Wert wurde ungewandelt durchgereicht → uebermaessiges Dissolve. Jetzt `radians(dissolve_angle)`. - **Bugfix:** Der Lightmap-Kanal wurde vor `lightmap_pack` nicht als aktiver UV-Layer gesetzt → UV0 konnte ueberschrieben werden. Jetzt explizit gesetzt, UV0 danach wieder als Render-Kanal. - Fehlerbehandlung um jeden `bpy.ops.*`-Aufruf; einzelne Rock-Fehler brechen den Batch nicht mehr ab. - Nicht-blockierender modaler Batch-Modus mit Progress-Bar. - Bevel + Weighted Normal als Toggle. - LOD-Set als `fbx_type=LodGroup`-Gruppe. - Preset-System (JSON) mit Panel-Dropdown. - Platzhalter-Material-Zuweisung.