extends SceneTree
## Render the density field's NORMALS as an image, at several world scales.
##
## Not a gate -- a picture, so the shading can be judged by eye before any of it
## is wired into a map. The probe shaders are painted on a 1 m cube and a 4 m
## quad, which sample one flat spot of a 60 km world and correctly produce one
## flat colour; that is why they look like nothing. This maps UV across a real
## world span instead.
##
## DISPLAY=:0 "$HYPER_TPS_GODOT" --path . --rendering-driver vulkan \
## --script res://scenes/test/density_preview.gd
const N := 1024
var _spans := [20000.0, 20000.0]
var _views := [4, 2]
var _i := 0
var _frames := 0
var _vp: SubViewport
var _mat: ShaderMaterial
func _initialize() -> void:
_vp = SubViewport.new()
_vp.size = Vector2i(N, N)
_vp.render_target_update_mode = SubViewport.UPDATE_ALWAYS
var mi := MeshInstance3D.new()
var q := QuadMesh.new(); q.size = Vector2(2, 2)
mi.mesh = q
mi.extra_cull_margin = 1e5
_mat = ShaderMaterial.new()
_mat.shader = load("res://shaders/density_probe.gdshader")
_mat.set_shader_parameter("probe_taps", 4)
_mat.set_shader_parameter("probe_view", _views[0])
_mat.set_shader_parameter("probe_world_y", 0.0)
_mat.set_shader_parameter("probe_world_span", _spans[0])
mi.material_override = _mat
_vp.add_child(mi)
var cam := Camera3D.new(); cam.position = Vector3(0, 0, 1.0); cam.current = true
_vp.add_child(cam)
root.add_child(_vp)
print("PREVIEW: %dx%d, 4-tap normals from the real density function" % [N, N])
func _process(_d: float) -> bool:
_frames += 1
if _frames < 12:
return false
var img := _vp.get_texture().get_image()
var path := "/tmp/density_preview_%dm_v%d.png" % [int(_spans[_i]), _views[_i]]
img.save_png(path)
print(" wrote %s (world span %.0f m, %.1f m/px)"
% [path, _spans[_i], _spans[_i] / float(N)])
_i += 1
_frames = 0
if _i >= _spans.size():
quit(0); return true
_mat.set_shader_parameter("probe_world_span", _spans[_i])
_mat.set_shader_parameter("probe_view", _views[_i])
return false