Rock Generator 2.8.0: Cavity in Vertex-Farben (texturfreier Weg)
Idee kam vom User: die Steine ueber "smart materials" in UE loesen statt ueber gebackene Texturen. Prozedurales Noise/Voronoi im Shader waere zu teuer (laeuft pro Pixel), aber der Kern der Idee traegt - deshalb dieser Weg: Neue Option "Cavity in Vertex-Farben": schreibt Cavity/AO plus optionalen Hoehen-Verlauf in das Farb-Attribut "Cavity" (vertex_color_dirt + eigene Nachbearbeitung fuer Staerke und Verlauf). Das Material braucht damit KEINE Textur: Base Color = Farbton x VertexColor, dazu Kantenlicht und Schattentint. Gegenueber Triplanar sitzen die dunklen Fugen dadurch auf den ECHTEN Kanten des Meshes statt darueberzuschweben - genau das passiert in der Genshin-Referenz. Verifiziert: Attribut wird angelegt, Wertebereich 0.250..0.947 (echter Kontrast), und es ueberlebt den FBX-Roundtrip UNVERAENDERT (gleicher Bereich nach Import). Regler: Cavity-Staerke, Hoehen-Verlauf, Weichzeichnen. Neuer Test tests/test_vertex_cavity.py. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
import bpy, sys, importlib.util, os, tempfile
|
||||
spec=importlib.util.spec_from_file_location("srg", r"A:\eco\stylized_rock_generator\stylized_rock_generator.py")
|
||||
r=importlib.util.module_from_spec(spec); sys.modules["srg"]=r; spec.loader.exec_module(r)
|
||||
try: r.unregister()
|
||||
except Exception: pass
|
||||
r.register()
|
||||
fails=[]
|
||||
for o in list(bpy.data.objects): bpy.data.objects.remove(o,do_unlink=True)
|
||||
s=bpy.context.scene.rock_gen_settings
|
||||
s.batch_count=1; s.subsurf_levels=4; s.use_modal=False
|
||||
s.shading_mode='FLAT'; s.bake_vertex_cavity=True
|
||||
s.name_prefix="Fels"; s.name_form="A"; s.name_class='M'
|
||||
res=bpy.ops.object.generate_rocks_batch()
|
||||
obs=[o for o in bpy.context.scene.objects if o.type=='MESH']
|
||||
ob=obs[0]
|
||||
me=ob.data
|
||||
names=[a.name for a in me.color_attributes]
|
||||
print("FARB-ATTRIBUTE:", names)
|
||||
if "Cavity" not in names: fails.append("kein_attribut")
|
||||
else:
|
||||
vals=[d.color[0] for d in me.color_attributes["Cavity"].data]
|
||||
vals.sort()
|
||||
print("CAVITY min=%.3f p10=%.3f median=%.3f max=%.3f (n=%d)"
|
||||
% (vals[0], vals[len(vals)//10], vals[len(vals)//2], vals[-1], len(vals)))
|
||||
if vals[-1]-vals[0] < 0.05: fails.append("kein_kontrast")
|
||||
# Faceted?
|
||||
sm=sum(1 for p in me.polygons if p.use_smooth)
|
||||
print("Shading: smooth=%d / flat=%d" % (sm, len(me.polygons)-sm))
|
||||
# FBX-Roundtrip: ueberleben die Vertex-Farben?
|
||||
tmp=tempfile.mkdtemp(); fp=os.path.join(tmp,"cav.fbx")
|
||||
for o in bpy.context.selected_objects: o.select_set(False)
|
||||
ob.select_set(True); bpy.context.view_layer.objects.active=ob
|
||||
bpy.ops.export_scene.fbx(filepath=fp, use_selection=True, colors_type='SRGB',
|
||||
mesh_smooth_type='FACE', use_triangles=True)
|
||||
for o in list(bpy.data.objects): bpy.data.objects.remove(o,do_unlink=True)
|
||||
bpy.ops.import_scene.fbx(filepath=fp)
|
||||
imp=[o for o in bpy.data.objects if o.type=='MESH'][0]
|
||||
inames=[a.name for a in imp.data.color_attributes]
|
||||
print("NACH FBX-ROUNDTRIP:", inames, "Tris=%d" % sum(len(p.vertices)-2 for p in imp.data.polygons))
|
||||
if not inames: fails.append("fbx_verliert_farben")
|
||||
else:
|
||||
iv=[d.color[0] for d in imp.data.color_attributes[0].data]
|
||||
print(" Wertebereich nach Import: %.3f .. %.3f" % (min(iv), max(iv)))
|
||||
r.unregister()
|
||||
print("ERGEBNIS:", "ALLE CHECKS OK" if not fails else "FEHLER: "+", ".join(fails))
|
||||
Reference in New Issue
Block a user