Skip to content

ObeidaZakzak/Houdini-VEX-Mandelbox

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Houdini-VEX-Mandelbox

Check it on ArtStation and Instagram.

This is a breakdown of the VEX code used to build the Mandelbox you see in the pictures above. Before starting, I recommend that you check the Mandelbulb Tutorial from Entagma to understand better the volume setup. The VEX code below is an adaptation of Entagma's tutorial with extra coding and different operations on the points in order to get a Mandelbox instead of a Mandelbulb.

The main idea is to apply an operation on each point of space several times until it reaches a given max number of iterations and by maintaining the distance between the point and the center of the box under a given limit. The operation to be applied at each point (x is considered as a point in the formula) :

(see Wikipedia)

Setting-up the nodes

We will work with volumes, so we need a volume node base_volume followed by a volume wrangler mandelbox where we will write some VEX code. Then we need a VDB convert node to visualize the details, and if you want extra details you can add another VDB convert to visualize the mandelbox as a polygones mesh (but it takes more time to compute). Note that in order to visulize the mandelbox correctly, the base_volume size must be set to 12x12, and the volume sampling to something higher than 150.

Writing the code

Everything is written inside of the mandelbox volume wrangler. We will seperate the operations by defining several function.

boxFold and ballFold functions

First of all, let's write the boxFold operation for a single axis :

function float boxFoldAxis(float x)
{
    if (x > 1) return(2-x);
    if (x < -1) return(-2 - x);
    return (x);
}

Now let's write boxFold for a given point by applying the boxfoldAxis at each axis :

function vector boxFold(vector pt)
{
    float x = boxFoldAxis(pt.x);
    float y = boxFoldAxis(pt.y);
    float z = boxFoldAxis(pt.z);
    
    return(set(x,y,z));
}

We need now the ballFold operation which modifies the magnitude of a given point :

function vector ballFold(float r; vector pt)
{
    float m = distance(set(0,0,0), pt);
    
    if (m < r) {
        m = m / pow(r,2);
    } else if (m < 1) {
        m = 1 / m;
    }
    return(m * normalize(pt));
}

Mandelbox function

The latest function is the one that iterates and modifies the points until it reaches the maximum number of iterations or the distance limit between the point and the center (0,0,0) :

function int Mandelbox(float s, r, f, L; int imax; vector pt0)
{
    int i;
    vector pt = pt0;
    
    for (i = 0; i < imax; i++)
    {
    
        pt = s*ballFold(r, f*boxFold(pt)) + pt;
        
        if (distance(set(0,0,0), pt) > L)
            return (i);
    }
    return (imax);
}

The main program

Once we have these functions written, we can now write the script modifying the volume in order to build the fractal form :

int maxiter = chi('MaxIter');

float s = ch('s');
float r = ch('r');
float f = ch('f');
float L = ch('L');

if (Mandelbox(s, r, f, L, maxiter, v@P) < maxiter) {
    @density = 0.0;
} else {
    @density = 1.0;
}

In the renders above, I used the following values :

maxiter = 15
s = 2.0
r = 0.5
f = 1.0
L = 4.3

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published