Skip to content

Blog

Post from Jan 12, 2026

Freebird v2.6.0 released. Changes since the last blog post (v2.2.2): - Adds the ability to add and edit Text while inside VR. This is useful for labeling and making notes inside VR, without having to sketch notes by hand. - Adds support for Vulkan and Blender 5. - Shows the scene scale in the controller's panel (below the main menu). This will let you know the zoom level of the scene, for e.g. 1:1 or 1:10 or 15:1, so that you can plan accordingly when working with real-world units.

... continue reading

Post from Oct 31, 2025

The next major version of Freebird (i.e. v3) will use a new internal architecture that's much easier to program with. In some ways, it's an evolution of the architecture used in Freebird v2, but taken to its logical conclusion.

The current version of Freebird (v2) uses a DOM-like model, and borrows a lot of programming patterns from browser-based programming. An underlying runtime abstracts away input events (like trigger_press, drag, enter, leave etc). It follows an event dispatch model (using add_event_listener and dispatch_event). Visual elements like menus, transform handles etc are DOM Nodes, which respond to events like drag and click. It also uses CSS-like styling to provide an easy way to style groups of related elements (like menu buttons).

This programming model was very powerful to use in v2, and allowed me to build a lot of functionality in a decoupled manner (which was a big problem in Freebird v1). New features like 3D grid, Camera Preview etc could be implemented as decoupled scripts that worked with a well-defined programming and event model. Scripts could listen to (or emit) higher-level events like cloned or moved and react to other scripts that emitted events.

But v2 didn't go far enough. It was inspired by the DOM spec, but didn't follow it strictly. It deviated from the DOM spec in a lot of areas and reinvented a lot of concepts (like custom versions of components, styling, UI elements, requestAnimationFrame etc). Often these deviations and reinventions were poorer designs.

This resulted in something that looked and felt a lot like the DOM, but would jarringly break the abstraction when dealing with some of the finer details. That broke the flow often when building new features.

Freebird's v2 has given me sufficient confidence that a DOM-style API for building 3D experiences (in an actual shipping, selling product) is productive and scalable. It's already way more productive and scalable than the spaghetti code of Freebird v1.

So Freebird v3 will take this to the logical conclusion, and use a subset of DOM and CSS, and follow the spec very strictly. Scripts will be loaded using script tags (executing Python instead of Javascript), reusable components will be implemented using Web Components, frame-by-frame processing will be done using requestAnimationFrame instead of a custom Unity-like update() method, and so on.

This will also make it easier to start writing plugins for Freebird, because it will use a mental model that's very familiar to a lot of developers.

There will be a very small number of additions to the DOM/CSS spec, in order to support 3D content and XR controllers. For e.g. native events for XR controller buttons, at par with mouse and keyboard events (instead of the verbose API of WebXR). But these additions will be kept to the bare minimum necessary.

Obviously this v3 redesign is not strictly necessary. I can keep churning out more features on the existing Freebird v2 platform. Infact I will continue doing that in the short term (i.e. adding more user-requested features in Freebird v2), while developing v3 in parallel. But I really believe in the importance of a better development platform for building 3D (especially XR) content, and I think there's a lot of potential in a Web-like development experience for creating 3D/XR content (remember JanusVR?).

... continue reading

Post from Oct 03, 2025

Freebird v2.2.2 released. It now exposes the states/values of the VR buttons (as custom properties) in FB-Controller-Right and FB-Controller-Left (see: XR Tracking Objects).

These values will be updated every frame, when VR is running.

You can use these properties to drive shapekeys, or use them in other scripts: * To drive a shapekey, please right-click a property, e.g. 'trigger', and click Copy as New Driver. Then right-click on your shapekey value, and select Paste Driver. * To use in a script, use the custom property directly. E.g. bpy.data.objects["FB-Controller-Right"]["trigger"]

... continue reading

Post from Sep 29, 2025

Freebird v2.2.0 released - Freebird now exposes the VR headset and controller positions via three empty objects in the scene: FB-Headset, FB-Controller-Right, and FB-Controller-Left.

These three empties live-track the position of the headset and the VR controllers. For e.g. you can attach objects to these empties to animate objects or bones.

... continue reading

Post from Sep 01, 2025

Puppetry v1.2.19 released! It allows you to move the overall armature rig via an external animation, while still controlling the head and hands with the VR controllers. Previously, the head and hands would stay at a fixed place in the world, and not move along with the rig.

For e.g. this is useful if you want to move the character down a corridor (using a script or animation timeline), while using Puppetry's motion capture to animate the head and hands.

Puppetry v1.2.19 also adds sensible offset defaults if Rigify bones are attached, specifically the head, hand_ik.R and hand_ik.L bones. This will help animate these bones in a more comfortable orientation.

... continue reading

Updates from June 2025

Note: Freebird is free for students! If you're a student at a school or college, please feel free to email or message me for a free copy!

June 2025 marked a restart of the Freebird project, after a few months of maintenance-only fixes.

Reliability

My focus in June was on improving Freebird's reliability. A number of long-standing critical bugs have been fixed, broken features have been repaired, and missing documentation has been updated. Basically, anything that crashed Freebird (or was urgently broken) was considered as an immediate priority.

I'm still investigating a Blender crash (that happens occasionally). So please save your work frequently.

I'm sure Freebird still has undetected bugs, so please let me know on #support if Freebird crashes for you. But a number of those crashes were fixed in June, and a focused effort has been made to improve the reliability.

Features

In terms of features, Free Extrude is back, and the transform gizmos now support moving/rotating/resize along specific planes. The transform gizmos now also support mode-specific transforms, i.e. the ability to move without rotating/resizing, rotate without moving/resizing, or resize without moving/rotating.

Tools to help improve reliability

To help investigate difficult-to-recreate bugs, I added an event record/replay developer tool in Freebird. If Freebird crashes at any point while running (on my PC), I can replay those exact button presses and movements any number of times, and check Freebird's code while running it. I've fixed a few difficult-to-recreate bugs using this tool. Note: This tool is disabled by default for users, so Freebird isn't recording your actions.

Another improvement was to run Freebird's automated tests in a random order, using pytest-random-order. Freebird already runs over 600 automated tests (which check various aspects of Freebird before a new version is released). But those tests used to run in a fixed order previously. Since I can't predict the order in which a user will use Freebird's tools, I'm now running the tests in a random order. This helps ensure that Freebird is reliable regardless of the order in which you use the various tools. This change has already revealed a couple of hidden bugs (that have been fixed).

Community

The Discord community has grown to nearly 1200 members, and it is active at trying out new Early-Access features and providing valuable feedback!

Some user experiments using Freebird:

Did I miss any? Please send me your cool "made with Freebird" videos!

Next

Lots more to come. The focus, as always, remains on making VR a part of your daily design workflow.

Thanks!

... continue reading

Post from Jan 02, 2025

Really need to figure out a way to render standard HTML elements (styled with CSS and modified with JS) in a 3D scene. Reinventing excellent libraries like PrimeVue again inside 3D (for rendering in VR) is just wasteful.

There have been attempts, e.g. A-Frame, but we really need to view the webpage in 3D. Just regular HTML elements. The regular DOM renderer. The pieces feel like they're there conceptually, but the implementation gap is probably big enough (that it hasn't happened yet).

For e.g. Freebird (Blender VR plugin) had to reinvent everything from scratch - UI buttons were rectangles drawn using shaders, grid layouts had to be reimplemented from scratch. I abstracted it into a sensible framework (heavily mimicking HTML/CSS/JS, because it makes sense!). But obviously this is all very wasteful, and results in poor quality UIs, because building a UI framework isn't the primary focus of Freebird (it's 3D modeling in VR).

... continue reading

Post from Dec 12, 2024

Freebird is finally out on sale - https://freebirdxr.com/buy

It's still called an Early Access version, since it needs more work to feel like a cohesive product. It's already got quite a lot of features, and it's definitely useful. But I think it's still missing a few key features, and needs an overall "fine-tuning" of the user experience and interface.

So yeah, lots more to do. But it feels good to get something out on sale after nearly 4 years of development. Freebird has already spent 2 years in free public beta, so quite a number of people have already used it.

Freebird sold its first few copies since it went on sale last night. The main emotion is a sense of relief I think.

... continue reading

Post from Oct 30, 2024

tl;dr - Today I shipped the ability to see the desktop screen in VR (while using Freebird). And fixed a few user-reported bugs in Freebird.

Performance

The performance is still a bit laggy. The actual screencapture code now runs in a separate process, and copies data over a SharedMemory buffer (which works pretty well for sharing data between two separate processes). That helps avoid Python's GIL while performing numpy operations on large arrays.

But the main performance bottleneck is the inability to update an existing texture using Blender's gpu module. The current implementation in Blender forces me to create a new texture each frame, which is pretty slow. And this has to be done on the main thread, otherwise Blender crashes with a null context error.

So I update the screen just two times per second. For now, the usability is adequate IMO. But if it becomes important, I can maybe look at the Blender codebase and see if there's anything that can be proposed as a solution. Like right now, doing video is impossible at decent framerates using the gpu module. Maybe I missed something, but I really searched a lot (and tried a lot of approaches).

Illusion of responsiveness

To create an illusion of responsiveness, the mouse cursor is updated every frame (72fps), while the actual screen updates twice per second (2fps).

Custom code to avoid dependencies

And thanks to ChatGPT/Claude, I got a custom Windows-only implementation for taking screenshots and getting the mouse cursor location. It's a bit faster than mss/pyautogui and works fine for my purpose.

The main reason was to avoid depending on external libraries (tricky to install them, being a blender addon). With AI codegen tools, it might actually be a good tradeoff, since the generated code is reasonably straightforward and maintainable (and uses well-supported Windows APIs). And I didn't spend much time on them.

Let's see how it performs during actual usage. It's now in early-access on Freebird. Hopefully it won't crash!

... continue reading

Post from Oct 23, 2024

Built an initial prototype of showing the desktop window screencapture inside VR (while in Freebird), using the mss library. Freebird will have to install it using subprocess.run([sys.executable, '-m', 'pip', 'install', 'mss']).

It works, but is currently a bit laggy. The capture and processing happens on a thread, and a timer modal calls the actual GPU texture assignment. The GPU texture assignment takes about 2 ms, but the XR view is still juddering (way more than it would with an extra 2ms of latency). Still need to investigate and smoothen the performance.

But it seems to work well overall. I even drew a tiny placeholder cursor, and it casts the entire screen, so it's possible to switch to other programs while in VR in Freebird. Promising.

... continue reading