I moved my compass out of the HUD and into the ocean shader. Here's the breakdown.
Early development footage from the sailing game I'm making solo in Godot 4. My first compass sat in the corner of the screen, and every time I checked it, I stopped looking at the sea. Which is a problem in a game called Seagazer... So i moved it onto the water!
Before: I had a placeholder dial. Nothing fancy. Just a white CylinderMesh with four Label3D letters, filmed by an orthographic camera into a 600 × 400 SubViewport in the corner. Dots on top showed each find/ Points of interest: their angle was its bearing, and their distance from the center was how far off it was.
After: no new mesh. The dial still does the tracking, with its SubViewport set to UPDATE_DISABLED. Each frame a HUD script takes the nearest four signals and publishes them as uniforms on the ocean material, and an include in the ocean's fragment shader draws the ring and the pulses.
The ring is a standing ripple. Its crest tilts the water's normal, so it catches the sky like the rest of the sea, with a thin painted line on top. North is fixed to the world, so in a turn the boat swings inside it.
Pulses (like sonar) leave the hull every 4 s at the edge of range and every 1.8 s close in, gold on the side facing the find. They're centered on the hull and travel with it, because a ripple left in the water would fall behind at full sail.
And last the tricky one. Where the stern wake crosses the ring, the script asks the wake trail where its ribbon crosses, and the shader sweeps the ring's ends aside along its edge. With the ring down and no pulse in flight, the shader returns at once.
Feedback on the ring is very welcome!