Slightly altered MandelBox

  • 0 Replies
  • 293 Views

0 Members and 1 Guest are viewing this topic.

Offline kosalos

  • *
  • Fractal Friar
  • *
  • Posts: 102
« on: October 03, 2018, 07:15:22 AM »
Bet you guys tried this idea years ago, but it is new to me, and it has some beautiful effects:
While doing the ray marching Distance Estimation for a Mandelbox,
alter the Box and Sphere fold values every time through the loop,
and for more control, also alter the delta fold values themselves every time through the loop.

Here's the relevant portions of my iPad app:

typedef struct {
    vector_float3 position;     // 0.01 ... 1
    float diffuse;              // 0.01 ... 1
    float specular;             // 0.01 ... 1
} Lighting;

typedef struct {
    vector_float3 camera;       // -10 ... 10
    vector_float3 focus;        // -10 ... 10
    vector_float3 viewVector,topVector,sideVector; // calculated by CPU before shader call
    float deFactor1,deFactor2;

    float zoom;                 // 0.2 ... 2
    float scaleFactor;          // -5 ... 5
    float epsilon;              // 0.00001 ... 0.005
   
    bool isJulia;               // Julia mode enbled?
    vector_float3 julia;        // -10 ... 10
   
    vector_float3 sphere;       // 0 ... 2
    float sphereMult;           // 0.1 ... 6
    vector_float3 box;          // 0.5 ... 2.5
   
    vector_float3 color;        // 0 ... 0.5
    Lighting lighting;
   
    bool isBurningShip;         // alternate MandelBox equation?
    float fog;                  // 0.7 ... 2
   
    vector_float3 dBox;         // 0.1 ... 2   alter box,sphere during DE iterations
    vector_float3 dSphere;
    vector_float3 ddBox;        // 0.1 ... 2   alter dBox,dSsphere
    vector_float3 ddSphere;
}  Control;

// ---------------------------------------------------------------------
// calculate before Shader call:

func toRectangular(_ sph:float3) -> float3 { let ss = sph.x * sin(sph.z); return float3( ss * cos(sph.y), ss * sin(sph.y), sph.x * cos(sph.z)) }
func toSpherical(_ rec:float3) -> float3 { return float3(length(rec), atan2(rec.y,rec.x), atan2(sqrt(rec.x*rec.x+rec.y*rec.y), rec.z)) }

c.viewVector = c.focus - c.camera
c.topVector = toSpherical(c.viewVector)
c.topVector.z += 1.5708
c.topVector = toRectangular(c.topVector)
c.sideVector = cross(c.viewVector,c.topVector)
c.sideVector = normalize(c.sideVector) * length(c.topVector)

c.deFactor1 = abs(c.scaleFactor - 1.0);
c.deFactor2 = pow( Float(abs(c.scaleFactor)), Float(1 - 10));

// ---------------------------------------------------------------------

constant int MAX_ITERS = 10;
constant int MAX_STEPS = 150;

float DE    // distance estimate
(
 float3 position,
 constant Control &control)
{
    float3 c = control.isJulia ? control.julia : position;
    float3 v = position;
    float dr = 1.5;
   
    Control cc = control;
   
    for (int i = 0; i < MAX_ITERS; i++) {
        v = clamp(v, -cc.box.x, cc.box.x) * cc.box.y - v;
        if(control.isBurningShip) v = -abs(v);
       
        float mag = dot(v, v);
        if(mag < cc.sphere.x) {
            v = v * control.sphereMult;
            dr = dr * control.sphereMult;
        }
        else if (mag < cc.sphere.y) {
            v = v / mag;
            dr = dr / mag;
        }
       
        v = v * control.scaleFactor + c;
        dr = dr * abs(control.scaleFactor) + 1.0;
       
        cc.box *= cc.dBox;
        cc.sphere *= cc.dSphere;
       
        cc.dBox *= cc.ddBox;
        cc.dSphere *= cc.ddSphere;
    }
   
    return (length(v) - control.deFactor1) / dr - control.deFactor2;
}

//MARK: -

float3 getNormal
(
 float3 position,
 constant Control &control)
{
    float4 eps = float4(0, control.epsilon, 2.0 * control.epsilon, 3.0 * control.epsilon);
    return normalize(float3(-DE(position - eps.yxx,control) + DE(position + eps.yxx,control),
                            -DE(position - eps.xyx,control) + DE(position + eps.xyx,control),
                            -DE(position - eps.xxy,control) + DE(position + eps.xxy,control)));
}

//MARK: -

float3 lighting
(
 float3 position,
 float distance,
 constant Control &control)
{
    float3 normal = getNormal(position,control);
    float3 color = normal * control.color;
   
    float3 L = normalize(control.lighting.position - position);
    float dotLN = dot(L, normal);
    if(dotLN >= 0) {
        color += control.lighting.diffuse * dotLN;
       
        float3 V = normalize(float3(distance));
        float3 R = normalize(reflect(-L, normal));
        float dotRV = dot(R, V);
        if(dotRV >= 0) color += control.lighting.specular * pow(dotRV, 2);
    }
   
    return color;
}

//MARK: -

float3 rayMarch
(
 float3 rayDir,
 constant Control &control)
{
    float de,distance = 0.0;
    float3 position;
    float ff = pow(control.fog,4);
   
    for(int i = 0; i < MAX_STEPS; ++i) {
        position = control.camera + rayDir * distance;
       
        de = DE(position, control);
        if(de < control.epsilon) break;
       
        distance += de;
        if(distance > ff) return float3();
    }
   
    float3 color = lighting(position,distance,control);
   
    color *= (1 - distance / ff);
    return color;
}

//MARK: -

kernel void mandelBoxShader
(
 texture2d<float, access::write> outTexture [[texture(0)]],
 constant Control &control [[buffer(0)]],
 uint2 p [[thread_position_in_grid]])
{
    if(p.x > uint(control.xSize) || p.y > uint(control.ySize)) return;
    uint2 srcP = p;
   
    float den = float(control.xSize);
    float dx =  control.zoom * (float(srcP.x)/den - 0.5);
    float dy = -control.zoom * (float(srcP.y)/den - 0.5);
   
    float3 direction = normalize((control.sideVector * dx) + (control.topVector * dy) + control.viewVector);
   
    outTexture.write(float4(rayMarch(direction,control),1),p);
}

------------------------
Here's the project on Github:  https://github.com/Kosalos/MandelBox2



Linkback: https://fractalforums.org/programming/11/slightly-altered-mandelbox/1946/


clip
(Perturbation) Images are always slightly incorrect

Started by Iluso on Programming

7 Replies
146 Views
Last post September 28, 2019, 08:37:39 PM
by 3DickUlus
xx
Slightly extended Newton method fractals

Started by gannjondal on Fractal Mathematics And New Theories

6 Replies
246 Views
Last post September 29, 2019, 10:18:01 PM
by gerrit
xx
mandelbox

Started by mclarekin on Fractal Image Gallery

0 Replies
100 Views
Last post October 10, 2018, 08:42:33 AM
by mclarekin
clip
once I was a mandelbox

Started by udo2013 on Fractal movie gallery

1 Replies
92 Views
Last post May 25, 2019, 05:57:44 AM
by Tas_mania
clip
MandelBox 3D display

Started by kosalos on Fractal Image Gallery

0 Replies
97 Views
Last post November 30, 2018, 02:02:02 AM
by kosalos