The fundamental material nodes in Bella are the Conductor, and the Dielectric, which represent opaque and transparent materials, respectively. These share a few attributes in common, such as opacity, normal (i.e. bump), roughness, and anisotropy.

Besides these two (which we call substrates) there is a the third main material component, the Layer, which essentially simulates a thin (on the scale of micrometers) dielectric layer over the underlying conductor or dielectric substrate.

The layer itself is comprised of Surface and Medium sub-components, which control how light behaves at, and below, the surface, respectively. Like the conductor and dielectric substrates, the surface accepts a Coating node (described later on), and the medium accepts an optional Scattering node, which controls the scattering of light within the layer medium.

For a very simple introductory example, let's begin with a simple conductor, with roughness 60%, then add a layer with roughness 10%, then raise the conductor roughness to 80%, and finally raise the layer roughness to 25%:

We can begin to see here, how the layer is simulating the thin dielectric coating it represents -- however, what would happen if we began to change the layer's transmittance color, which is white (meaning that it does not interact with light passing through it) by default?

Let's reduce the layer roughness to 10% again, and tint its transmittance using a hue similar to that of the conductor; finally, let's then add some subtle scattering in the layer medium:

However, what if we wish to have only a layer, with no substrate? No worries, as the Bella Sheet material is exactly that: a material consisting of just a layer, which is useful for zero-thickness (i.e. not describing a closed volume) glass panes, leaves, paper, and the like -- especially when we introduce scattering in the layer medium:

As mentioned above, the conductor and the dielectric, as well as the layer surface, support application of a Coating, which simulates thin film interference.

In addition to the core material types, there are also the Blend and Stack materials, which may be used to combine other materials together, either by blending them, or by stacking them one above another -- in either case, we may combine materials using a scalar value, or by texture mapping:

Lastly, we naturally have the Emitter material, which simply allows for light to be emitted (of course using real-world output energy values) from arbitrary geometry.


All textures in Bella are implemented as nodes (whether file-based or procedural), the outputs of which may be used to drive the inputs of other textures, or of intermediate nodes, materials, and so forth.

By way of example, here is shown a Bella material being edited in Maya Hypershade:


Cameras in Bella are represented using the Camera, Lens, and Sensor nodes, which are modeled to represent features commonly found in DSLR cameras, in order to allow you to leverage your existing knowledge of photography, in Bella.

The camera supports either fully manual exposure control, or automated exposure compensation, with either aperture or shutter priority. This can be very convenient for adjusting DOF (Depth of Field) while maintaining the current exposure.

The Sensor node represents the physical camera sensor, and provides control over film size, ISO, and sharpness, as well as simulation of sensor diffraction and bloom.

TODO: create image

The Lens node supports optional vignetting, lens shift, and choice of diaphragm shape (circular, or with straight or curved blades) and rotation, as well as a lens filter stack, for adding lens filters such as the diffraction or ND (Neutral Density) filters.

TODO: create image

There are currently two types of lenses: Thin and Thick . Where the thin lens models an ideal lens, the thick lens simulates effects seen in real-world (read: lower-quality) lenses, yielding some complex visual effects like chromatic aberration or field curvature effects.


Bella provides procedural Sphere, Plane, Cylinder, and Disk nodes, which render with perfect precision, and require virtually no memory.

These may optionally be substituted for mesh geometry in Maya by setting the Render Perfect option in the Bella parameters for a mesh's polySphere, polyPlane, polyCylinder, or polyDisc node.


In addition to supporting mesh lights through the emitter material, Bella also provides procedural Point, Area, Directional, and Spot lights.

For the most part these exist for the purpose of accurately representing host-application lights in Bella scenes, and as such, they do not by default use real-world units.

Instead, these lights use a generic and unitless Intensity value, which is multiplied by a Multiplier value; the reason for this design is to allow Bella plugins to drive light intensity according to host-application light intensity, with the multiplier being used to scale Bella output to match that of the host (or other plugin) light.

As such, once the multiplier has been suitably set, output energy in both host application and Bella may then be controlled using the host application intensity value.

That said, some of the Bella light types also accept direct assignment of a Bella emitter material (specifically, those which have a physical area), in case you prefer to work in real energy units.

nodes and the scene hierarchy

Everything contained in a Bella scene is a node, and everything seen in a Bella render is an instance of a node, or an instance of a hierarchy of nodes, and so forth.

The scene consists of a collection of nodes, each with input and output attributes that may be connected to the inputs and outputs of other nodes. One of the primary node types is the transform (or xform in Bella), which is a node that associates a 3D transformation with a collection of child nodes, each of which may in turn be a geometry node, or another xform.

At the root of the visual scene hierarchy we find the world xform -- everything visible in the render is ultimately parented to the world xform, either directly or indirectly. And everything seen may be said to be an instance of some geometry node, or an instance of an xform, along with its child geometries and xforms, and so on.

For detailed help on all Bella node definitions, see here.


The Bella render architecture is based on having one or more Solvers render the scene. Our current beauty-pass solvers (which to make it clear, are all currently CPU-based) are:


An unbiased bi-directional path tracer, Atlas is the default solver for production beauty pass, as it is highly optimized for solving complex lighting scenarios.


Very similar to Atlas, Ares is a sophisticated unbiased (non bi-directional) path tracer, which may be used for production beauty pass, potentially rendering faster than Atlas in scenes which have less complex lighting.


Apollo is a quasi-unbiased solver using a proprietary new method. It is a production beauty pass solver capable of solving lighting scenarios which have traditionally been infeasible for a bi-directional path tracer like Atlas. It is our hope that eventually, Apollo will replace Atlas as the default solver, but as it is a completely new technology, we must carefully validate that there do not exist cases in which it yields incorrect or undesirable results.


An unbiased path tracer, the IPR (Interactive Preview Render) solver has been created & tuned for giving quick initial feedback on changes in the scene. This solver is used to implement any realtime interactive rendering windows in the Bella's GUI and plugins.


A special type of Solver, a Pass (sometimes referred to as a layer, channel, or AOV in other rendering software) is used to render a specific non-beauty output, such as an object or material ID pass, and so forth. Bella's currently-supported passes are these:

  • Albedo Pass
  • Material Pass
  • Normal Pass
  • Object Pass
  • Tangent Pass
  • Z Pass

We expect to add more pass types as we receive requests for them, and perhaps if it is desired, provide an API for people to write their own proprietary pass solvers.


Bella implements Intel's OpenImageDenoise library for both IPR and production rendering.

In IPR we use a quick denoising pass that requires little CPU or memory, but which tends to produce mediocre results. In the beauty pass we generate full albedo & normal information, for results we have found to be beyond our expectations.

color management

With native support for the linear, sRGB, and Rec709 color spaces, Bella also optionally (i.e. depending on whether the OCIO environment variable is set) uses OpenColorIO for color management.

This applies to file input & output, to the Bella GUI for accurate input & display, and to the Maya plugin.

The Bella file formats

Bella provides both binary (.bsx) and plain-text (.bsa) file formats. Additionally, it provides native support for a zipped scene archive format (.bsz), which contains all referenced assets, to ease rendering a given scene on different machines (or sending to a render farm).

While the binary format is generally used for production, due to its reduced size and superior read/write performance, a plain-text format can be invaluable for debugging purposes, for sending fragments of Bella scenes over the network (the Bella Scene API is capable of accepting such fragments directly), or for hand-authoring scenes and/or for creating tools capable of working with Bella, without introducing a binary dependency on any Bella libraries.

As such, we have placed an emphasis on creating a plain-text format that is easy to read and write -- in fact, you may find it to look more like code, than a file format:

# Bella Scene - 2019-02-24T20:32:39-0600

# Arrays may be auto-indexed, and nodes may be referenced before creation:
xform world:
  .children[*]          = __persp__;
  .children[*]          = __sphere__;
  .children[*]          = __plane__;
  .children[*]          = __keyRight__;
  .children[*]          = __keyLeft__;
  .steps[0].xform       = mat4(-0.01 0 0 0 0 0.01 0 0 0 0 0.01 0 0 0 0 1);

# We can create a node and set its inputs by their full paths:
settings settings;
settings.beautyPass     = beautyPass;
settings.camera         = __perspShape__;
settings.iprScale       = 57f;

# Or, an existing node may be made current using the 'with' keyword:
camera __perspShape__;
with __perspShape__:
  .lens                 = lens;
  .sensor               = sensor;

# Or, we can combine both into the node creation step:
xform __persp__:
  .children[0]          = __perspShape__;


We will provide a full spec for the format (and perhaps in time, parsers for various languages), but as you can tell even without having seen a spec, it is very easy to create Bella scenes. Please note that for purposes of clarity, the above snippet is not really something you could render, mainly because it refers to many non-existent nodes.

And in fact, we have already used this internally to good effect, for instance, to create a quick & dirty SketchUp exporter (for development purposes -- nothing you would want to use for work), simply by opening an output file in Ruby, and writing out a .bsa file -- no complicated linking of Bella code libraries necessary.


The initial Bella plugin is Bella for Maya. As might be expected, it implements Bella nodes as Maya nodes, and provides seamless and interactive Maya-native material and scene editing and preview rendering.

To read more about the Maya plugin, please refer to the plugin documentation, here. (TODO: write maya docs)

Next on our plugin roadmap are plugins for Rhinoceros, followed by SketchUp, Cinema 4D, 3ds Max, and others (not necessarily in that order), so please let us know if you have a preference, as we will naturally take demand into account, as we move forward.

Bella GUI

The Bella GUI is used for rendering, and light interactive editing of scenes, outside the host 3D application where they were authored.

While plugins, to whatever degree applicable, allow rendering directly inside the host application, it can also be desirable to have rendering occur outside, and independent of the host application, in order that you may continue working, while rendering is done in a separate process.

As such, Bella plugins include a Send to Bella command, for exporting the scene to a Bella file, and starting Bella GUI rendering it, while you keep working.

Though serving this purpose is the main scope of the Bella GUI, it does nevertheless provide a good deal of scene editing capability, and as it is generally not possible to provide so tight an integration in a host 3D application, can be a comfortable option for certain portions of the workflow.

As development progresses, we will be continuing to refine and augment this GUI, as seems sensible to us, and according to customer request.

Bella CLI

The Bella CLI is simply a command-line application that can be used to render a Bella file.

It is useful for creating a personal render farm, or integrating Bella into existing rendering pipelines.