<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>Die Dubiose Dev</title>
      <link>https://dubiose.dev</link>
      <description>Random thoughts, projects, mini projects, and ideas.</description>
      <generator>Zola</generator>
      <language>en</language>
      <atom:link href="https://dubiose.dev/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Sat, 07 Mar 2026 00:00:00 +0000</lastBuildDate>
      <item>
          <title>Bevy glTF Considerations</title>
          <pubDate>Sat, 07 Mar 2026 00:00:00 +0000</pubDate>
          <author>Caitlin Sar Campbell</author>
          <link>https://dubiose.dev/misc/bevy-gltf-considerations/</link>
          <guid>https://dubiose.dev/misc/bevy-gltf-considerations/</guid>
          <description xml:base="https://dubiose.dev/misc/bevy-gltf-considerations/">&lt;h1 id=&quot;the-situation-at-hand&quot;&gt;The situation at hand.&lt;&#x2F;h1&gt;
&lt;p&gt;The amount of work that has been put into the Bevy glTF system is clear and evident. There is a ton of functionality that works really well and helps the engine shine.&lt;&#x2F;p&gt;
&lt;p&gt;In working on my game and continuing to learn the Bevy codebase, there is an issue that I think, while not threatening now, will only continue to grow into a larger and larger problem as time goes on.&lt;&#x2F;p&gt;
&lt;p&gt;This is the state of the &lt;code&gt;gltf-rs&lt;&#x2F;code&gt; dependency that Bevy uses in the &lt;code&gt;bevy-gltf&lt;&#x2F;code&gt; crate.&lt;&#x2F;p&gt;
&lt;p&gt;This crate is not well maintained, to the point where the same issue has been submitted multiple times over the years.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;2023 - https:&#x2F;&#x2F;github.com&#x2F;gltf-rs&#x2F;gltf&#x2F;pull&#x2F;392&lt;&#x2F;li&gt;
&lt;li&gt;2025 - https:&#x2F;&#x2F;github.com&#x2F;gltf-rs&#x2F;gltf&#x2F;pull&#x2F;456&lt;&#x2F;li&gt;
&lt;li&gt;2026 - https:&#x2F;&#x2F;github.com&#x2F;gltf-rs&#x2F;gltf&#x2F;pull&#x2F;467&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;All three of these are for the same issue, adding &lt;code&gt;KHR_texture_basisu&lt;&#x2F;code&gt; support, and in my opinion all three were&#x2F;are clean implementations against the existing &lt;code&gt;gltf&lt;&#x2F;code&gt; codebase.&lt;&#x2F;p&gt;
&lt;p&gt;If you look at the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;gltf-rs&#x2F;gltf&#x2F;pulls&quot;&gt;outstanding PRs&lt;&#x2F;a&gt;, most of them are for adding one or another of the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;KhronosGroup&#x2F;glTF&#x2F;tree&#x2F;main&#x2F;extensions&quot;&gt;Ratified Khronos Extensions
&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This is where the fundamental issue arises. While these extensions are not part of the core glTF 2.0 specification, they are de facto needed in order to use glTF as a modern 3D asset standard, particularly where glTF&#x2F;GLB is the primary and preferred asset format.&lt;&#x2F;p&gt;
&lt;p&gt;As Bevy becomes more and more widely recognized as a game engine, it will become stranger and stranger that the only real options for textures are JPEG and PNG, both with their own issues and non-native GPU deficiencies.&lt;&#x2F;p&gt;
&lt;p&gt;Even worse, in my book, is telling current and future Bevy developers that &quot;Bevy sort of hacks in KTX2 texture support in glTF files, but you need to use a special tool that turns your compliant glTF file into a non-compliant one BUT IT WORKS IN BEVY!&quot;&lt;&#x2F;p&gt;
&lt;h1 id=&quot;what-should-we-aim-for&quot;&gt;What should we aim for?&lt;&#x2F;h1&gt;
&lt;p&gt;Before continuing to consider resolutions, I think considering what would be desirable is worth doing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;long-term&quot;&gt;Long Term&lt;&#x2F;h2&gt;
&lt;p&gt;From a developer perspective, the ideal goal would be to make the glTF&#x2F;GLB experience a first-class one.&lt;&#x2F;p&gt;
&lt;p&gt;The developer should be able to use glTF&#x2F;GLB files without fear, without worrying about compatibility or the need to hack things in, in the same way that a Unity developer imports &lt;code&gt;.unity&lt;&#x2F;code&gt; assets knowing things will go smoothly.&lt;&#x2F;p&gt;
&lt;p&gt;Technologically speaking, I think this means we aim for FULL compatibility with all &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;KhronosGroup&#x2F;glTF&#x2F;tree&#x2F;main&#x2F;extensions&quot;&gt;ratified Khronos extensions&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;This is less daunting than it may seem. We already handle a good amount of these, and just need to parse the glTF JSON to hand it off to the relevant existing Bevy code.&lt;&#x2F;p&gt;
&lt;p&gt;Others are already in progress.&lt;&#x2F;p&gt;
&lt;p&gt;Others will need new code in Bevy or elsewhere.&lt;&#x2F;p&gt;
&lt;p&gt;In addition, I would propose that we consider adding selected vendor extensions including &lt;code&gt;EXT_texture_webp&lt;&#x2F;code&gt; and &lt;code&gt;EXT_texture_avif&lt;&#x2F;code&gt; (if we have AVIF support in the engine already). These are less important, but would lean into the first-class developer experience.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;short-term&quot;&gt;Short Term&lt;&#x2F;h2&gt;
&lt;p&gt;In looking at what level of expanded glTF support we see in other game engines, we see this:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Extension&lt;&#x2F;th&gt;&lt;th&gt;Godot&lt;&#x2F;th&gt;&lt;th&gt;Unity&lt;&#x2F;th&gt;&lt;th&gt;Bevy&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_animation_pointer&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_draco_mesh_compression&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;X&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_lights_punctual&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;X&lt;&#x2F;td&gt;&lt;td&gt;X&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_anisotropy&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;X&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_clearcoat&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;X&lt;&#x2F;td&gt;&lt;td&gt;X&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_diffuse_transmission&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_dispersion&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_emissive_strength&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;X&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_ior&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;atteneder&#x2F;glTFast&#x2F;issues?q=is%3Aissue+is%3Aopen+KHR_materials_ior&quot;&gt;in progress&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;X&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_iridescence&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_sheen&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;atteneder&#x2F;glTFast&#x2F;issues?q=is%3Aissue+is%3Aopen+KHR_materials_sheen&quot;&gt;in progress&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_specular&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;atteneder&#x2F;glTFast&#x2F;issues?q=is%3Aissue+is%3Aopen+KHR_materials_specular&quot;&gt;in progress&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;X&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_transmission&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;atteneder&#x2F;glTFast&#x2F;issues&#x2F;111&quot;&gt;in progress&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;X&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_unlit&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;X&lt;&#x2F;td&gt;&lt;td&gt;X&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_variants&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;X&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_volume&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;atteneder&#x2F;glTFast&#x2F;issues&#x2F;209&quot;&gt;in progress&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;X&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_mesh_quantization&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;X&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_texture_basisu&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;X&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_texture_transform&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;X&lt;&#x2F;td&gt;&lt;td&gt;X&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_xmp_json_ld&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;EXT_lights_image_based&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;atteneder&#x2F;glTFast&#x2F;issues&#x2F;108&quot;&gt;in progress&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;EXT_mesh_gpu_instancing&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;X&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;EXT_meshopt_compression&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;X&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;EXT_texture_webp&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;KHR_materials_pbrSpecularGlossiness&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;td&gt;X*&lt;&#x2F;td&gt;&lt;td&gt;partial&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;*&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;search?q=repo%3Agodotengine%2Fgodot%20KHR_&amp;amp;type=code&quot;&gt;Godot docs don&#x27;t list supported and unsupported extensions, but looking through the source I found nothing missing.&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;atteneder&#x2F;glTFast&#x2F;blob&#x2F;openupm&#x2F;Documentation~&#x2F;features.md&quot;&gt;Unity imports via glTFast&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;I propose that, short term, we aim to be a superset of Unity, focusing on supporting the extensions they have that we don&#x27;t.&lt;&#x2F;p&gt;
&lt;p&gt;Short term, we may consider adding &lt;code&gt;EXT_texture_webp&lt;&#x2F;code&gt; as well, since this would be trivial once we decide on an approach.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;potential-resolutions&quot;&gt;Potential Resolutions&lt;&#x2F;h1&gt;
&lt;p&gt;There are several resolutions I could foresee. BUT the only resolution that I think would be actively harmful would be to continue to base &lt;code&gt;bevy_gltf&lt;&#x2F;code&gt; on &lt;code&gt;gltf-rs&lt;&#x2F;code&gt; without a long-term plan.&lt;&#x2F;p&gt;
&lt;p&gt;We should not pull a Warhammer 40k and build an empire around a slowly rotting corpse of a project. Not without a plan to lean less on the corpse at least.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;best-case-gltf-rs-revival&quot;&gt;Best Case - gltf-rs revival&lt;&#x2F;h2&gt;
&lt;p&gt;If we can revive the project, either through a maintainer of &lt;code&gt;gltf-rs&lt;&#x2F;code&gt; becoming active or through the project adding a Bevy-vouched-for approver, this would be the best case.&lt;&#x2F;p&gt;
&lt;p&gt;With an understanding that the &lt;code&gt;gltf-rs&lt;&#x2F;code&gt; project owners may have certain requirements, we could agree to only make changes that do not interfere with those requirements.&lt;&#x2F;p&gt;
&lt;p&gt;This requires some buy-in from the &lt;code&gt;gltf-rs&lt;&#x2F;code&gt; owners, which may be impossible.&lt;&#x2F;p&gt;
&lt;p&gt;This would allow us to make these changes to benefit Bevy and the community as a whole.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;case-2-gltf-rs-fork&quot;&gt;Case 2 - gltf-rs fork&lt;&#x2F;h2&gt;
&lt;p&gt;Another option is for a group of people to maintain a fork of the existing project. It will be more work, but the crate is well documented and has a test suite that could be expanded to reduce future labor.&lt;&#x2F;p&gt;
&lt;p&gt;Here we could start by cherry-picking the relevant existing PRs, and we would be halfway done with our long-term goals.&lt;&#x2F;p&gt;
&lt;p&gt;The advantage here is that we could use upstream labor in our efforts to maintain the crate. The whole wider community benefits.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;case-3-do-raw-gltf-i-o-in-house-as-part-of-bevy-gltf&quot;&gt;Case 3 - do raw glTF I&#x2F;O in-house as part of bevy-gltf&lt;&#x2F;h2&gt;
&lt;p&gt;This is less bad than one might think. Right now we use &lt;code&gt;gltf-rs&lt;&#x2F;code&gt; and wrap our &quot;user space&quot; &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;bevyengine&#x2F;bevy&#x2F;blob&#x2F;162a7080911dc8b782475553fef8888c8d103655&#x2F;crates&#x2F;bevy_gltf&#x2F;src&#x2F;loader&#x2F;extensions&#x2F;mod.rs#L62&quot;&gt;GltfExtensionHandler trait&lt;&#x2F;a&gt; around it.&lt;&#x2F;p&gt;
&lt;p&gt;There are some existing extensions that are implemented in-house, namely &lt;code&gt;khr_materials_anisotropy&lt;&#x2F;code&gt;, &lt;code&gt;khr_materials_clearcoat&lt;&#x2F;code&gt;, and &lt;code&gt;khr_materials_specular&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I think this approach is valid. My primary concern here is that we are still wrapping the code around a slowly rotting corpse. My secondary concern is that we lose out on upstream efforts.&lt;&#x2F;p&gt;
&lt;p&gt;I think there is a path forward if we take this approach.&lt;&#x2F;p&gt;
&lt;p&gt;In addition to adding all the extensions that make for a predictable first-class glTF experience, we slowly handle the core glTF features as well using the same code paths.&lt;&#x2F;p&gt;
&lt;p&gt;We have the &lt;code&gt;khr_materials_anisotropy&lt;&#x2F;code&gt; extension, but we could then add &lt;code&gt;core_node_hierarchy&lt;&#x2F;code&gt; that would handle a core glTF 2.0 feature.&lt;&#x2F;p&gt;
&lt;p&gt;We could do this slowly over time, one piece at a time, replacing one core feature at a time until we have &lt;code&gt;core_*&lt;&#x2F;code&gt;, where all glTF 2.0 core functionality is handled and wrapped around nothing.&lt;&#x2F;p&gt;
&lt;p&gt;This would let us slowly migrate away without replacing the world.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;conclusion-key-points&quot;&gt;Conclusion &#x2F; Key Points&lt;&#x2F;h1&gt;
&lt;ol&gt;
&lt;li&gt;If glTF is our preferred asset format, we should make using it a first-class experience.&lt;&#x2F;li&gt;
&lt;li&gt;The root cause of the existing glTF problems is &lt;code&gt;gltf-rs&lt;&#x2F;code&gt; not being well maintained.&lt;&#x2F;li&gt;
&lt;li&gt;We can fix this root cause by reviving the core project, forking it, or bringing it in-house.&lt;&#x2F;li&gt;
&lt;li&gt;No matter which way we go, we SHOULD &amp;amp; MUST not build an empire on a rotting corpse.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</description>
      </item>
      <item>
          <title>Kungsfors Protector Sleeve</title>
          <pubDate>Thu, 19 Feb 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://dubiose.dev/mini-projects/kungsfors-protector-sleeve/</link>
          <guid>https://dubiose.dev/mini-projects/kungsfors-protector-sleeve/</guid>
          <description xml:base="https://dubiose.dev/mini-projects/kungsfors-protector-sleeve/">&lt;p&gt;This protective sleeve was designed to fit over the IKEA Kungsfors magnetic knife holder. The sleeve prevents knife edges from making direct contact with the metal surface, reducing the risk of chipping when placing or removing knives. The design slides over the holder and stays in place during normal use.&lt;&#x2F;p&gt;</description>
      </item>
      <item>
          <title>Learning Engrammer</title>
          <pubDate>Mon, 05 May 2025 00:00:00 +0000</pubDate>
          <author>Caitlin Sar Campbell</author>
          <link>https://dubiose.dev/blog/new-keyboard-new-layout/</link>
          <guid>https://dubiose.dev/blog/new-keyboard-new-layout/</guid>
          <description xml:base="https://dubiose.dev/blog/new-keyboard-new-layout/">&lt;h1 id=&quot;new-keyboard-new-layout&quot;&gt;New Keyboard New Layout&lt;&#x2F;h1&gt;
&lt;p&gt;I recently decided to buy a new keyboard after my the pleather shedding issue with trusty Microsoft ergonomic keyboard became too severe to ignore. As well as that keyboard has served me, when it started polluting my home something needed to be done.&lt;&#x2F;p&gt;
&lt;p&gt;After some research I landed on Keycron’s Q10 Max. The build quality is excellent, and the Alice style layout lets me stay in an ergonomic, but not too radical (i.e. split) form factor.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;blog&#x2F;new_keyboard_new_layout&#x2F;desktop.avif&quot; alt=&quot;Picture of the author&amp;#39;s desk.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The Q10 Max being wireless let me continue on my path towards a clean, clutter free, and wire free desktop.&lt;&#x2F;p&gt;
&lt;p&gt;I decided that, while I was at it I should consider alternative keyboard layouts. After all a new keyboard requires relearning muscle memory, why not double down?&lt;&#x2F;p&gt;
&lt;p&gt;I considered a few layouts, namely &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rdavison&#x2F;graphite-layout&quot;&gt;Graphite&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;engram.dev&quot;&gt;Engram&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;GalileoBlues&#x2F;Gallium&quot;&gt;Gallium&lt;&#x2F;a&gt;, and &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sites.google.com&#x2F;alanreiser.com&#x2F;handsdown&quot;&gt;Hands Down&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;An important thing I learned in my research is that there seems to be a definitive break between post and pre covid layouts, with post covid layouts being substantially more well designed.&lt;&#x2F;p&gt;
&lt;p&gt;I ended up going with Engram variant because I liked the emphasis on roll-ins, and the inner column punctuation.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;blog&#x2F;new_keyboard_new_layout&#x2F;engrammer.webp&quot; alt=&quot;Engrammer Layout Digram&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I went with the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sunaku&#x2F;engrammer&quot;&gt;Engrammer&lt;&#x2F;a&gt; because the brace and bracket locations in Engram where not great for software development.  Engrammer has the same letter layout as engram, except with a more programmer centric symbol layout.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;what-i-did-and-how-i-learned&quot;&gt;What I Did And How I Learned&lt;&#x2F;h1&gt;
&lt;p&gt;Learning Engram was extremely painful. I committed to a cold turkey approach and switched both my laptop and desktop layout to use Engrammer on day one.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;blog&#x2F;new_keyboard_new_layout&#x2F;keybr_cal.avif&quot; alt=&quot;Keybr.com Calendar showing one month of work.&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I also did 30 minutes of daily keyboarding practice on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.keybr.com&quot;&gt;keybr.com&lt;&#x2F;a&gt; (which has many alternative layouts build in, including engram build in) daily for one month.&lt;&#x2F;p&gt;
&lt;p&gt;The learing process went something like this:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;week-1&quot;&gt;Week 1&lt;&#x2F;h2&gt;
&lt;p&gt;Pure Agony. If I worked a traditional job I surely would have been fired. My productivity dropped to like 5% on normal.&lt;&#x2F;p&gt;
&lt;p&gt;I couldn’t even play video games normally. I had to remap every game I played to use the new layout. (I know I could have switched back for games, but I wanted to commit 100%.)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;week-2&quot;&gt;Week 2&lt;&#x2F;h2&gt;
&lt;p&gt;Very painful. Posable to code but barely.&lt;&#x2F;p&gt;
&lt;p&gt;Wondered why I decided to do such a dumb thing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;week-3&quot;&gt;Week 3&lt;&#x2F;h2&gt;
&lt;p&gt;Slow, but I can work.&lt;&#x2F;p&gt;
&lt;p&gt;At this point it felt like things where starting to come together.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;week-4&quot;&gt;Week 4&lt;&#x2F;h2&gt;
&lt;p&gt;Feeling slow but better.&lt;&#x2F;p&gt;
&lt;p&gt;Over the hump for sure.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;blog&#x2F;new_keyboard_new_layout&#x2F;speed_chart.avif&quot; alt=&quot;Keybr.com Speed Progress Chart. Shows slow progress&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The main thing that helped was consistency. I practiced every day even if it was the only thing I did that day. My life basically revolves around typing in one form or another so even on bad days I had some motivation.&lt;&#x2F;p&gt;
&lt;p&gt;If I had one tip for people who want to learn a new key layout it would be to practice every day.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;impact&quot;&gt;Impact&lt;&#x2F;h1&gt;
&lt;p&gt;It&#x27;s been just over a month and I continue to practice daily. Thing get better daily. This blog post probably only took 20% longer to type than it would have if I used QWERTY&#x2F;Z.&lt;&#x2F;p&gt;
&lt;p&gt;Funny thing is that I now struggle with QWERTY&#x2F;Z.&lt;&#x2F;p&gt;
&lt;p&gt;Overall typing feels better now and I am happy.&lt;&#x2F;p&gt;
&lt;p&gt;Would I recommend learning a new layout? Yes, but only if you can commit hard. Otherwise the productivity drop would be too drastic for too long.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Box Fan Privacy Screen</title>
          <pubDate>Sat, 05 Apr 2025 00:00:00 +0000</pubDate>
          <author>Caitin Sar Campbell</author>
          <link>https://dubiose.dev/mini-projects/box-fan-privacy-screen/</link>
          <guid>https://dubiose.dev/mini-projects/box-fan-privacy-screen/</guid>
          <description xml:base="https://dubiose.dev/mini-projects/box-fan-privacy-screen/">&lt;p&gt;This privacy screen was designed to provide privacy by replacing the front grate of a box fan. It allows air to flow threw without allowing look in. Perfect if you want cool air and privacy! The grate was designed for a Lasko box fan but should work with other box fans.&lt;&#x2F;p&gt;</description>
      </item>
      <item>
          <title>280mm x 150mm Crate</title>
          <pubDate>Fri, 04 Apr 2025 00:00:00 +0000</pubDate>
          <author>Caitin Sar Campbell</author>
          <link>https://dubiose.dev/mini-projects/crate/</link>
          <guid>https://dubiose.dev/mini-projects/crate/</guid>
          <description xml:base="https://dubiose.dev/mini-projects/crate/">&lt;p&gt;This 280mm x 150mm robust crate was designed to hold root vegetables, but could be used for any heavy goods. This is being released as one of many simpler designs I made over the years.&lt;&#x2F;p&gt;</description>
      </item>
      <item>
          <title>Nasal Strip Holder</title>
          <pubDate>Thu, 03 Apr 2025 00:00:00 +0000</pubDate>
          <author>Caitin Sar Campbell</author>
          <link>https://dubiose.dev/mini-projects/nasal-strip-holder/</link>
          <guid>https://dubiose.dev/mini-projects/nasal-strip-holder/</guid>
          <description xml:base="https://dubiose.dev/mini-projects/nasal-strip-holder/">&lt;p&gt;This simple nasal strip holder was designed to be placed on a nightstand and keep things organized. The design is simple and trivial to change. This is being released as one of many simpler designs I made over the years.&lt;&#x2F;p&gt;</description>
      </item>
      <item>
          <title>Roller Blind Window Clip</title>
          <pubDate>Sat, 28 May 2022 00:00:00 +0000</pubDate>
          <author>Caitin Sar Campbell</author>
          <link>https://dubiose.dev/mini-projects/roller-blind-window-clip/</link>
          <guid>https://dubiose.dev/mini-projects/roller-blind-window-clip/</guid>
          <description xml:base="https://dubiose.dev/mini-projects/roller-blind-window-clip/">&lt;p&gt;This roller blind window clip was designed to be compatible with Gardinia. This clip was designed after the original one was broken and a replacement was needed. This design is definitively stronger than the original design.&lt;&#x2F;p&gt;</description>
      </item>
      <item>
          <title>PanelDue 7i Case for the Railcore II </title>
          <pubDate>Tue, 24 Mar 2020 00:00:00 +0000</pubDate>
          <author>Caitin Sar Campbell</author>
          <link>https://dubiose.dev/mini-projects/paneldue-7i-case-railcore/</link>
          <guid>https://dubiose.dev/mini-projects/paneldue-7i-case-railcore/</guid>
          <description xml:base="https://dubiose.dev/mini-projects/paneldue-7i-case-railcore/">&lt;p&gt;This is my simple PanelDue 7i case for the Railcore II.&lt;&#x2F;p&gt;</description>
      </item>
      <item>
          <title>Secret Hitler Name Plaques</title>
          <pubDate>Sun, 17 Nov 2019 00:00:00 +0000</pubDate>
          <author>Caitin Sar Campbell</author>
          <link>https://dubiose.dev/mini-projects/secret-hitler-name-plaques/</link>
          <guid>https://dubiose.dev/mini-projects/secret-hitler-name-plaques/</guid>
          <description xml:base="https://dubiose.dev/mini-projects/secret-hitler-name-plaques/">&lt;p&gt;A quick multi material 3d print project I put together for a friend. These are used in the VERY fun (and freely available) &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.secrethitler.com&#x2F;&quot;&gt;Secret Hitler&lt;&#x2F;a&gt; Game. If you like the game I would encourage you to support the creators by purchasing a pre printed card set from them.&lt;&#x2F;p&gt;</description>
      </item>
      <item>
          <title>Tall Laptop Stand</title>
          <pubDate>Fri, 06 Sep 2019 00:00:00 +0000</pubDate>
          <author>Caitlin Sar Campbell</author>
          <link>https://dubiose.dev/mini-projects/tall-laptop-stand/</link>
          <guid>https://dubiose.dev/mini-projects/tall-laptop-stand/</guid>
          <description xml:base="https://dubiose.dev/mini-projects/tall-laptop-stand/">&lt;p&gt;This project was my first ever venture into 3D design. I had just acquired a 3D printer and wanted to print something out for myself. This was created in &quot;Parts&quot; mode in FreeCAD. In the end the design worked out well and I used it for many years.&lt;&#x2F;p&gt;</description>
      </item>
    </channel>
</rss>
