Sly 25.10.: „immer noch harte Kanten beim Malen“. Ursache: die Splat-Textur hatte beim feinen 1-m-Raster genau einen Texel je Materialpunkt und wird nearest gesampelt → jede Zelle ein harter Block. - Shader liest die Material-ID-Karte (R8, ein Texel je Punkt, texelFetch) und mischt PRO PIXEL bilinear über die 4 Nachbarpunkte. - Leichter Domain-Warp (Value-Noise in Rasterzellen, eine Oktave) verwackelt die Abtaststelle → keine Rastertreppen, natürliche Kante. - Malen aktualisiert nur noch die Bytes der Karte (kein Splat-Neuberechnen). - TerrainArrays.material_image (Spiegel-Datei, identisch im Client). - Render-Probe tests/probe_mal_weich_render.gd (vorher/nachher geprüft). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
53 lines
2.2 KiB
GDScript
53 lines
2.2 KiB
GDScript
extends SceneTree
|
|
## Render-Probe (Karte 25.10., Sly: „immer noch harte Kanten beim Malen“):
|
|
## 256-m-Karte (feines Raster 257 = 1 m), Sandpfad mit 2-m-Pinsel, top-down
|
|
## auf 40 m Ausschnitt. Misst die größte Helligkeits-Stufe zwischen
|
|
## Nachbarpixeln quer zur Kante — weich = kleine Stufen über mehrere Pixel.
|
|
## Start (BRAUCHT Rendering): godot --path . --rendering-driver opengl3 -s res://tests/probe_mal_weich_render.gd -- <out.png>
|
|
|
|
func _initialize() -> void:
|
|
_run()
|
|
|
|
|
|
func _run() -> void:
|
|
await process_frame
|
|
await process_frame
|
|
var out := OS.get_cmdline_user_args()[0] if OS.get_cmdline_user_args().size() > 0 else "/tmp/mal_weich.png"
|
|
var size := float(OS.get_environment("PROBE_SIZE")) if OS.get_environment("PROBE_SIZE") != "" else 256.0
|
|
var res := 129
|
|
var mres := SvmapIO.material_resolution_for(res, size, size)
|
|
var heights := PackedFloat32Array()
|
|
heights.resize(res * res)
|
|
var mats := PackedByteArray()
|
|
mats.resize(mres * mres)
|
|
for i in 60: # schräger 2-m-Pfad + Kurve
|
|
var t := float(i) / 59.0
|
|
TerrainField.apply_material_brush(mats, mres, size, size,
|
|
-15.0 + 30.0 * t, -10.0 + 8.0 * sin(t * 3.0), 2.0, 1)
|
|
var view := Node3D.new()
|
|
view.set_script(load("res://src/viewport/terrain_mesh.gd"))
|
|
root.add_child(view)
|
|
view.call("update_heights", heights, res, size, size, mats)
|
|
view.call("set_contours", false)
|
|
var cam := Camera3D.new()
|
|
root.add_child(cam)
|
|
cam.projection = Camera3D.PROJECTION_ORTHOGONAL
|
|
cam.size = 40.0
|
|
cam.position = Vector3(0.0, 50.0, -5.0 + 0.01)
|
|
cam.look_at(Vector3(0, 0, -5.0), Vector3(0, 0, -1))
|
|
cam.current = true
|
|
for i in 4:
|
|
await process_frame
|
|
await RenderingServer.frame_post_draw
|
|
var img := root.get_texture().get_image()
|
|
img.save_png(out)
|
|
# Größte Nachbarpixel-Stufe (Luminanz) im Bild — harte Pixelkanten ≈ volle
|
|
# Sand↔Gras-Differenz in EINEM Pixel, weich = über ~Pixel/Meter verteilt.
|
|
var maxstep := 0.0
|
|
for y in range(0, img.get_height(), 2):
|
|
for x in range(1, img.get_width()):
|
|
var a := img.get_pixel(x - 1, y).get_luminance()
|
|
var b := img.get_pixel(x, y).get_luminance()
|
|
maxstep = maxf(maxstep, absf(a - b))
|
|
print("PROBE_MAXSTEP %.4f mres=%d px/m=%.1f -> %s" % [maxstep, mres, float(img.get_width()) / 40.0, out])
|
|
quit(0)
|