feat: screen-space ink edge pass — drawn outlines on everything

New assets/shaders/ink_edge.gdshader: fullscreen depth+normal discontinuity
detection draws thin ink lines over the whole scene — the renderer-level
line pass anime-styled games use. Works on every model regardless of mesh
topology (kit buildings, cars, heroes, characters), with distance fade so
the skyline stays clean. Attached via LevelEnvironment so every map gets
it for whatever camera renders (first-person, third-person, spectator).

Street capture verified: crisp uniform outlines citywide, no artifacts.

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
Nicholas Butzke
2026-07-19 11:54:55 -04:00
co-authored by Claude Fable 5
parent 911066875b
commit 5224a455a6
2 changed files with 71 additions and 0 deletions
+14
View File
@@ -34,6 +34,20 @@ static func add_to(level: Node, sky_variant: String = "day") -> WorldEnvironment
fill.shadow_enabled = false
level.add_child(fill)
# Screen-space ink edge pass: drawn outlines on every model for whatever
# camera renders (fullscreen POSITION-override quad, never culled).
if not level.has_node("InkEdgePost"):
var ink := MeshInstance3D.new()
ink.name = "InkEdgePost"
var quad := QuadMesh.new()
quad.size = Vector2(2, 2)
var ink_mat := ShaderMaterial.new()
ink_mat.shader = load("res://assets/shaders/ink_edge.gdshader")
quad.material = ink_mat
ink.mesh = quad
ink.extra_cull_margin = 16384.0
level.add_child(ink)
# Quiet ambient bed so the arena never sits in dead air.
if not level.has_node("AmbientBed") and ResourceLoader.exists("res://assets/sounds/wind.wav"):
var amb := AudioStreamPlayer.new()