-
Notifications
You must be signed in to change notification settings - Fork 19
Blender Addon
Tetra3D is a relatively simple 3D renderer first and foremost. However, I've created a Blender add-on to help smooth out the workflow a bit and gain some additional features. You don't have to install the add-on to use Tetra3D, but it definitely helps if you want to "dig in" a bit more and use Blender to create content for usage with Tetra.
To install the Tetra3D add-on, you simply download the .py file from the most-recent releases entry, or from the repo's "home" file list. After that, open Blender, go to the Edit > Preferences menu, and then the Add-ons section.
Choose "Install" from the top-right, and select the tetra3d.py
file you downloaded. Enable it by checking its checkbox at the right-hand side of the Tetra3D entry. That will complete the process.
Adding the Tetra3D add-on to Blender will give you a few new Tetra3D panels - one in the Render Properties section (where the Camera icon is), one in the Object Properties section (where the Object icon [which looks like a "selected" square] is), one in the World Settings section (where the globe icon appears), and one in the Material Properties section.
Export options, available in the Render Properties section
To export data from Blender for use with Tetra3D, you can either enable export on save (as described below) and save, or press the Export button above. Note that the second export format option, .gltf + .bin + textures
, isn't supported properly by Tetra3d as of yet.
By enabling the Export on Save checkbox, your blend file will export to the filepath and format specified automatically whenever you save.
You can change the filepath and file format to export the data in, as well (note that Tetra3D doesn't properly support the GLTF + bin option). If you leave the filepath blank, it will use the same filepath and filename as the current .blend file. Otherwise, it will expect a full filepath. You can change whether cameras and lights export along-side the data, as well.
You can also choose to pack the textures into the GLTF file, which means that they will be automatically loaded from the file when loading the models. If you choose not to pack the textures into the GLTF file, textures will not be loaded automatically when the mesh is loaded. Instead, the Material.TexturePath
property will populate with the relative path to the texture from the exported mesh file location.
Clear color and fog settings can be altered in the World Properties section. When fog is enabled, you can change the fog's color, and the range that the fog becomes active (ranging from 0, the near plane for the camera, to 1, or the far plane for the camera). Transparent fog has no color, and instead simply fades the objects out the further out from the camera they appear. Transparent fog also has optional bayer matrix dithering, which can be altered using the Dithered Transparency Size spinner; a transparency size of 0 disables the dithering.
Collections, or groups, are also handled correctly, thanks to the add-on; this means that Blender Collections can be used similarly to prefabs or scene instances in other engines. Essentially, you create a collection of various objects that you want to instantiate multiple times, and then create and place a Collection Instance for each of those objects. Editing the original edits all of the clones, of course. The collection instance objects in Blender are substituted for their contents when the collection is placed in Tetra3D.
So, for example, if you have a collection named FoliageCollection
that is comprised of three objects - Tree
and Bush
parented to a Foliage
object, and place two instances of it in your scene in Blender, you would end up with a hierarchy like this when loaded into Tetra3D:
Root
|
|_ Foliage (object named "FoliageCollection" in Blender)
| |__ Tree
| |__ Bush
|
|_ Foliage (object named "FoliageCollection.001" in Blender)
|__ Tree
|__ Bush
Something to note is that in Blender, a Collection is a resource that can "contain" or "use" other resources, like objects. Deleting an object in Blender using the default shortcut, the x
key, will delete the object from the current scene, but not other scenes or collections that use that object. When you export a scene with Tetra3D, objects deleted from scenes but not collections will also be deleted - otherwise, they will still show up in your export, despite them not appearing in the scene.
You can also do this manually with shift+x
to delete the object from the scene and all collections that are using it, or remove the deleted object from its collections in the Blender Outliner, with the view set to display the resources in the Blender File.
Linking objects from separate blend files works just fine, and doing so forms a hierarchy. When you link objects from a blend file into another and export the target blend file, The Tetra3D addon will export the necessary information to be able to properly instantiate the object later if given the necessary source library. What this means is that when loading a GLTF file with objects from a linked blend file into Tetra3D, it will require that a library be provided that has the linked objects.
As an example, let's say you have a level1.blend
file, which contains your first game level. You also have a player.blend
file, that contains your player character. You link (not append) your player from the player.blend
file into your game levels - this way, changes you make to the player are automatically mirrored in any levels you import the Player character into. You then export the level1.blend
file to a level1.gltf
file, and player.blend
into a player.gltf
file, in the same folder.
Now, since the player was linked into level1.gltf
from the player.blend file, loading the level1.gltf
file in Tetra3D requires a dependent library for the Player character. It would be found at the path to the player.blend
file, relative to the location of level1.blend
. Just for the sake of this example, you could load the player.gltf
file first, then pass a reference to it into the GLTFLoadOptions
struct when loading the level1.gltf
file, thusly:
// Load the Player first - this becomes a Library, as usual.
player, err := tetra3d.LoadGLTFFile("assets/gfx/player.gltf", nil)
if err != nil {
panic(err)
}
// Create a GLTFLoadOptions struct...
loadOptions := tetra3d.GLTFLoadOptions{}
// Then pass the library as a reference.
loadOptions.DependentLibraryResolver = func(blendPath string) *Library {
/*
The DependentLibraryResolver is a function that takes a path string, pointing to
a .blend file, and returns a *Library reference. In this example, blendPath would be
"player.blend".
For this simple example, we return the player library directly for simplicity and clarity, and
because we know that the player library is the only dependent library in this example.
However, this is rather inflexible.
One better way to do this would be to wrap this entire process in a resource loading and
retrieval system (effectively a map).If a library requires a dependant library, it could then
alter the blendPath to refer to the exported GLTF file and then call the resource retrieval
function to either load or retrieve the library (if it has already been loaded).
*/
return player
}
// Now when we load the level, the player will be cloned from the loaded player dependent library
// and placed where he appears in Blender. Amazing!
level1, err := tetra3d.LoadGLTFFile("assets/gfx/level1.gltf", loadOptions)
if err != nil {
panic(err)
}
... Or as mentioned in the comment, modify the blendPath to refer to the exported GLTF file (assuming you place the blend file next to the GLTF export and name them the same, which you generally should, as that's the only way a "master" library could reliably know where its dependent libraries might be).
A circular dependency loop (A depends on elements of B, which depends on elements from A) is not supported.