Smoke fractals using OpenVDB

In this tutorial we’re going to make cloudy fractals like this Mandelbulb. Requirements:

  • Mandelbulb3D v1.9.9
  • Cinema 4D
  • Octane

The first part of this tutorial is the same as for making particle fractals (https://codefolio.nl/2019/03/03/making-a-particle-fractal/).

We’ll start by making a fractal in Mandelbulb3D.

I assumed you are familiar with Mandelbulb3D and are able to create your own fractal. If you’re not, you can import these parameters by using the button ‘From clipboard’.

Mandelbulb3Dv18{
g…..S….O/…w….2……………1…….s1E…………………………..
………………………………….kz1……..A./………………y.2…wD
…Uz6….k/…./M.0/……l….9/….E3…..omEQgisq6rD/……….m/dkpXm1….U
z…..kD12../2k/..u/.sDpz8..UW3Xi7yj2..kcNYgbzf/..s1Z0knz.U0…..y1…sD…../..
.z1…sDYsAIxzzzjz1……….WAbUdisqcljRRxgCKosEwnYRydIKa5uzwPN9SaPRGyDFHQlSHA1
Iw1iNMIOip7tzqF/G0ZZtVyDU…..21…………..sD.6….sD..G…………………
………….oAnAt1…sD….zw1…………………………………..R….k1.
…..83iyz1…….kz.wzzz1.U..6.P….U5…EB….m….c3….F….6/…I1…..SF52
…U.qFG9yzb2zzzRYoWzz7lz16.pc..zXCc..kvrEtMc7xD6ocyFE0ujz1……….2.28.kFrA0.
.Ub96aAIVz9.1se7Umvxz0………./EU0.wzzz1………..s/……………….E.2c..
zzzz………….0……………….2./8.kzzzD…………8………………..
/EU0.wzzz1……………………………..MpQT0UvNPcvee0RUx3.yRiibHJJnRIV..XR
SvBmx3dLA0UvNPcvQsLIHm5.ibhVi1bTIZ4K.sSq4uClyp5W8/UvNPcvMwbjZl3.ibhVinqTg7fJ.sSq
4uCkzxYf60UvNPcv..EsUa3feeWCNqGQIJ36wk8EwyLsUa3f…………………………..
E….Ek.l2E…..I….k….UEI31IdtKNbxaP…IjR5…………………………6U.
06U………………/………EvQc7EdgRgznKL3TraOtUz………………………
..kH.d82975vJSxD……..kz1……….F6hMjeapx2EbdZ3DQU5A.2…………………
…………………2…..3….5….EZQdNqPsBoPh/5PZVLEiR4PZB5……………..
0IV.06E./………………….E……..cz1….wxcMUzUV8b8CMyA.E……….UaNaNa
NaNizcPixrPlC6zD……………………………………………………….
……………………………….wzzzzD……IaPZBLOm.pPrN1……………..
………………………………….U.2……………………………….
……………………………………………………………………..
……………………………………k…..I….2….EHnl4RjJqItpaA……..
……………………………………Uu6wi9yEVxz………………………
……………………………………………………………………..
………………………………………………..}
{Titel: m164}

We can export the Mandelbulb3D model to a point cloud. Make sure you have version 1.9.9. Open the BTracer (Bulb tracer) and import the parameters from main. You probably will need to scale the object (I scaled to 0.5). After it fits in the preview window, you can write it to a ply file.

Next I downloaded the OpenVDB library from Dreamworks (https://www.openvdb.org/) and wrote a very basic C++ program for converting the ply file to a VDB file. The programming isn’t hard, but it takes some effort to configure the C++ environment, especially if you are using Windows. This is the whole program. If you have problems setting up the C++environment or cannot program at all I can give you the binaries.

 include "pch.h"
include <stdio.h>
include <iostream>
include <vector>
include <openvdb/openvdb.h>
include <fstream>
include <gflags/gflags.h>
include <boost/algorithm/string.hpp>
include <exception>

DEFINE_string(filename, "", "The name of the ply file");
DEFINE_int32(skip, 11, "The number of lines to skip (default 11)");
DEFINE_bool(rgb, true, "Use rgb channels");
DEFINE_int32(magnification, 10000, "The factor for magnification");

using namespace openvdb;

void readPly() {
try {
std::cout << "Starting ply to openvdb converter. Command line options:" << std::endl;
std::cout << "-filename" << std::endl;
std::cout << "-skip" << std::endl;
std::cout << "-rgb" << std::endl;
std::cout << "-magnification" << std::endl;
if (FLAGS_filename.empty()) {
std::cout << "Please specify a filename in ply format (-filename)" << std::endl;
return;
}
else {
std::cout << "Reading file " << FLAGS_filename << "..." << std::endl;
}
openvdb::initialize();
openvdb::GridPtrVec grids;
openvdb::FloatGrid::Ptr grid = openvdb::FloatGrid::create(0.0);
typename FloatGrid::Accessor accessor = grid->getAccessor();
openvdb::FloatGrid::Ptr gridr = openvdb::FloatGrid::create(0.0);
typename FloatGrid::Accessor accessorr = gridr->getAccessor();
openvdb::FloatGrid::Ptr gridg = openvdb::FloatGrid::create(0.0);
typename FloatGrid::Accessor accessorg = gridg->getAccessor();
openvdb::FloatGrid::Ptr gridb = openvdb::FloatGrid::create(0.0);
typename FloatGrid::Accessor accessorb = gridb->getAccessor();
std::ifstream infile(FLAGS_filename);
float x, y, z, r, g, b, a;
int i = 0;
for (i = 0; i <= FLAGS_skip - 1; i++) {
std::string dummyLine;
std::getline(infile, dummyLine);
}
while (infile >> x >> y >> z >> r >> g >> b >> a) {
accessor.setValue(Coord(x * FLAGS_magnification, y * FLAGS_magnification, z * FLAGS_magnification), 1);
if (FLAGS_rgb) {
accessorr.setValue(Coord(x * FLAGS_magnification, y * FLAGS_magnification, z * FLAGS_magnification), r / 100);
accessorg.setValue(Coord(x * FLAGS_magnification, y * FLAGS_magnification, z * FLAGS_magnification), g / 100);
accessorb.setValue(Coord(x * FLAGS_magnification, y * FLAGS_magnification, z * FLAGS_magnification), b / 100);
}
i++;
}
infile.close();
grid->setName("density");
gridr->setName("r");
gridg->setName("g");
gridb->setName("b");
std::vector<std::string> splitFilename{};
boost::algorithm::split(splitFilename, FLAGS_filename, boost::is_any_of("."));
std::string resultFilename = splitFilename[0] + ".vdb";
std::cout << "Writing file " << resultFilename << std::endl;
openvdb::io::File file(resultFilename);
grids.push_back(grid);
if (FLAGS_rgb) {
grids.push_back(gridr);
grids.push_back(gridg);
grids.push_back(gridb);
}
file.setCompression(0);
file.write(grids);
file.close();
std::cout << "Finished!" << std::endl;
}
catch (std::exception& e) {
std::cout << "Exception: " << e.what() << std::endl;
}
}
int main(int argc, char* argv[])
{
gflags::ParseCommandLineFlags(&argc, &argv, true);
openvdb::initialize();
readPly();
}

If we now run PlyToOpenVDBConverter.exe -filename <filename.ply> we get a vdb file as result.

Now it’s time to start Cinema 4D, enable Octane and add a Octane VDB volume. Specify the file we just created as input.

Make the volume step length lower and the fractal cloud appears (you can also make the density higher). You can change the appearance of the fractal by changing the absorption, scattering, and emission values.

Here are some examples created using this technique.


2 Comments

  • Reply jeoffrey rodriguez July 3, 2019 at 4:46 pm

    Hello Linda,
    You have some awesome works on your blog, spent a lot of my day on.
    I’m very interested in playing with fractals but i’m a complete noob at C++.
    Can you send me your PlyToOpenVDBConverter.exe please ?

    Also, do you post your work on instagram so i can follow your next adventures ?

    Thanks a lot for your researchs

Leave a Reply

Your email address will not be published.*