So I'm playing with OSL right now, and have had a lot of luck in the past with texture and most of its key-value optional parameters. I've moved on to texture3d, which uses voxel formats—a great idea—but I can't find any documentation as to what voxel formats Blender supports.

I tried VDB, which is what volumes export to by default (also a voxel texture format); but can't tell if it's actually reading the file or not. I'm definitely not getting the shape I expected.

My code is as follows:

volume voltex(string filename = "", point uv = 0, output color cOut = 0, output float aOut = 0.0) {
    color cTex = texture3d(filename, uv);
    cOut = cTex;
    aOut = cTex[0];

Filename is set to "///data.vdb", and this file does exist in the project's directory.

But, when I tie the node to Principled Volume, I get an error-pink with no variations on transparency or color. No issue loading the file is reported in the terminal.

My Node Layout

My Result

The little round grey cloud in the above image is the imported volume of data.vdb; these two objects should be at least shaped the same way. I might be missing something obvious.

Is OSL's texture3d function fully supported? For which formats does it work?

UPDATE: It seems that volume shaders don't really handle UV coordinates in the same way; I'm using object-space coordinates now and having some results. However, the question of which file formats qualify as voxel textures remains.


1 Answer 1


OK, I've done it. In a sense.

The first and foremost thing to mention is that, as of the moment, Blender does not seem to support any voxel formats on an OSL level. I'm sure it will eventually, and the framework for texture3d seems to work fine; but there aren't any valid inputs. Someone please correct me if I'm wrong.

However, intrinsically, a voxel texture can be thought of as an array, along an additional axis, of pixel textures. I've successfully described a 3D shape by determining the z-height of the voxel I'm looking at, using format to create a file name of %03d.png, and looking the texture for that plane up in a directory. It runs very efficiently.

enter image description here

My specific code, so far, is as follows.

volume tex3d(float t = 0.0, point p = 0, int frame_count = 0, vector dimensions = 0, string path = "", output float aOut = 0) {
    //align point to [0, 1] square
    point st = (p + vector(1.0))/2.0;
    //find frame by comparing against z-dimension of volume
    int frame = st[2] / (dimensions[2]/frame_count);
    //Get our file name, so we can pull a texture from the directory
    string sz = format("%03x.png", frame);
    aOut = 1.0 - texture(concat(path, sz), st[0], st[1]);

Ideally Blender will eventually support both VDB, as it already exports to it; and Field3D, which is an open sourced format by the same people who put OSL together. For now, this will do nicely.

Notably, the voxel cloud still does not match the blurb in the corner; this is because I drew it by hand. There's likely a way to convert VDBs to a sequence of PNGs, but I haven't done it as of yet.

  • $\begingroup$ Well, thanks for putting the work in! This is good to know. $\endgroup$
    – Robin Betts
    Mar 22, 2021 at 16:49
  • $\begingroup$ @RobinBetts I'm honestly not going to be the least bit surprised when Blender implements OpenVDB in its texture3d function. Probably Field3D too, as it's introduced by the same people who introduced OSL and is completely open. But, unfortunately, it hasn't happened quite yet. $\endgroup$ Mar 23, 2021 at 4:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .