Vav_Labs

joined 4 months ago
 

Google Chrome Labs keeps an Awesome HTML-in-Canvas list of demos for the API, and one of them is a Godot scene of mine.

Here's how the Godot side works. The three panels in the scene are real HTML, drawn straight into textures Godot already owns. You can select text on a tilted panel while the camera moves, Ctrl+C it, Ctrl+F finds it, right-click translate works. (It's real DOM, so it's also in the accessibility tree, which a canvas HUD normally isn't.)

The bit that's useful even if you never touch this API is getting at Godot's own WebGLTexture from GDScript:

  • RenderingServer.texture_get_native_handle(tex.get_rid()) gives you the GL texture id (web export = Compatibility renderer)
  • inside JavaScriptBridge.eval, GL.textures[id] is the actual WebGLTexture (emscripten's lookup table)
  • write to it from JS, then put the GL state back after (active texture, binding, unpack flags). Godot doesn't expect anyone else touching its context

Chrome changed the API this week: texElementImage2D became texElementSubImage2D, panels need a new drawable attribute, and hit testing moved to updateElementGeometry. For a Godot texture the new version fits better actually, Godot already allocated the storage so it's just a sub-image write. I kept the old path behind feature detection since stable Chrome is still mid-transition.

Caveats up front: Chromium only (origin trial on the demo, or the CanvasDrawElement flag). Mozilla and WebKit haven't taken a position yet, both requests are still open. So it's an experiment, not something to ship a game on.

Source (MIT): https://github.com/Vav-Labs/quest-signal Write-up + live demo: https://vav-labs.com/case-studies/quest-signal/

 

TIL NavigationServer3D.map_get_path() in Godot 4 stops searching after 4096 polygons by default. On a big navmesh the path just ends short and looks like a disconnected island.

[–] Vav_Labs@programming.dev 6 points 2 months ago

This looks pretty cool!

[–] Vav_Labs@programming.dev 3 points 3 months ago

32 is a deliberate ceiling for this edition, not a limit of the technique. The design goal was set no compute no buffers one file shapes travel as uniform arrays, and every primitive adds a distance eval to every march step on every pixel, so a fully analytic field doesn't want hundreds anyway. The scaling tricks are exactly the ones you list bake everything static into a precomputed SDF texture and sample it as a single primitive. That's the natural direction for the node based edition if it grows to v2

Hadn't seen the liquids part of that SIGGRAPH talk thanks for the pointer, watching it.

 

Signed distance field raymarching in Godot 4, authored with nodes. Physics-driven metaballs melt into the SDF cubes in one fullscreen pass, and since every CSG op works on (color, distance) pairs, the colors blend along with the shapes.

Two free editions: Standalone shader (CC0): one .gdshader, no scripts paste onto a QuadMesh, edit map(). Godot Shaders https://godotshaders.com/shader/fullscreen-sdf-raymarching-with-smooth-csg-and-depth/

Node-based project (MIT): shapes as Node3D nodes, live editor preview, physics, up to 32 primitives and a write-up. VavLabs Mit
https://vav-labs.com/case-studies/sdf-raymarcher-godot/

Distance functions after Inigo Quilez.

youtube: https://youtu.be/Y1sd9Cx4NAs

[–] Vav_Labs@programming.dev 2 points 4 months ago

Nice transition effect Thanks for sharing!

[–] Vav_Labs@programming.dev 1 points 4 months ago

Nice transition effect Thanks for sharing!

[–] Vav_Labs@programming.dev 3 points 4 months ago

Fair suspicion in 2026. AI can write it! , which is exactly why I built the sandbox instead of leaving this as a wall of advice. The useful part is meant to be testable version specific AStarGrid2D behavior, reproduced gotchas, and an interactive grid you can poke at. If you see a specific mistake, vague claim, or Godot-version mismatch, point me to it and I’ll fix it.

 

Godot's AStarGrid2D is a ten-minute read and a month of gotchas. The API page is small, you skim it, and then your path comes back empty, your units cut through wall corners, or your weighted swamp gets ignored. None of it is a bug. It's the gap between knowing the method names and knowing which handful of settings actually decide the behavior.

The five that get almost everyone:

  • You forget update(). Change the region or cell size, skip the rebuild, and you get an empty array with no error.
  • update() wipes your point data. It clears every solid cell and weight, so you have to set those after you call it.
  • Diagonal corner-cutting. DIAGONAL_MODE_ALWAYS lets units squeeze diagonally between two walls. You usually want ONLY_IF_NO_OBSTACLES.
  • jumping_enabled silently ignores weight scale. Turn on JPS and your weighted terrain stops mattering. It's in the docs. People still lose an afternoon to it.
  • Manhattan overestimates with diagonals. On an 8-direction grid it counts a diagonal as two steps, so your "shortest" path isn't. Reach for Octile.

So I wrote the reference I actually wanted (every property and method, the gotcha attached to each, version-honest across Godot 4.0 → 4.7, checked against the official docs and the C++ source), and built an interactive sandbox for the parts you have to see: drag the goal, paint solid and weighted cells, flip diagonal modes, toggle jumping, and watch the path recompute live. (It's a browser illustration of how AStarGrid2D behaves, not the engine itself running in a tab.)

Full reference and the sandbox: https://vav-labs.com/blog/astargrid2d-complete-reference/

If any of it's wrong or out of date for your version, tell me. The API moved across Godot 4.x, and I'd rather fix it than leave you debugging my mistake.