cotton candyKnotted Fishing LineElectric Doily
Knotted Fishing Line
Previous Image | Next Image
Description: based on Knighty's Kleinian (plus spherical inversion)
https://www.shadertoy.com/view/lstyR4
Stats:
Views: 53
Total Favorities: 0 View Who Favorited
Filesize: 4.51MB
Height: 1065 Width: 2400
Keywords: Knighty's Kleinian 
Posted by: kosalos February 19, 2020, 02:15:28 AM

Rating: ***** by 1 members.
Total Likes: 1

Image Linking Codes
BB Thumbnail Image Code
BB Medium Image Code
Direct Link
0 Members and 1 Guest are viewing this picture.

Comments (1) rss

kosalos
Fractal Friar
*
Offline Offline

Posts: 118



View Profile
February 19, 2020, 08:40:56 PM
source code (OSX metal)

camera = SIMD3<Float>(5.091495, 4.9838924, 28.142923)
viewVector =  SIMD3<Float>(-0.31140244, 0.43357626, 0.84560037)
topVector =  SIMD3<Float>(-0.49328095, 0.686812, -0.53381944)
sideVector =  SIMD3<Float>(-0.8122199, -0.58335125, -1.4901161e-08)

control.maxSteps = 12.0
control.mins = simd_float4(control.cx,control.cy,control.cz,control.cw);
control.maxs = simd_float4(control.dx,control.dy,control.dz,control.dw);
control.power = 1.025
control.InvCx =  -0.08920003
control.InvCy =  0.01999999
control.InvCz =  -0.47600016
control.InvRadius =  4.2999983
control.InvAngle =  0.12400001
control.orbitStyle = 0
control.secondSurface = 0

float DE_KLEINIAN2(float3 pos,device Control &control,thread float4 &orbitTrap) {
    float k, scale = 1;

    float3 ot,trap = control.otFixed;
    if(int(control.orbitStyle + 0.5) == 2) trap -= pos;
   
    for(int i=0; i < control.maxSteps; ++i) {
        pos = 2 * clamp(pos, control.mins.xyz, control.maxs.xyz) - pos;
        k = max(control.mins.w / dot(pos,pos), control.power);
        pos *= k;
        scale *= k;

        ot = pos;
        if(control.orbitStyle > 0) ot -= trap;
        orbitTrap = min(orbitTrap, float4(abs(ot), dot(ot,ot)));
    }

    float rxy = length(pos.xy);
    return .7 * max(rxy - control.maxs.w, rxy * pos.z / length(pos)) / scale;
}

float DE(float3 pos,device Control &control,thread float4 &orbitTrap) {
    if(control.doInversion) {
        pos = pos - control.InvCenter;
        float r = length(pos);
        float r2 = r*r;
        pos = (control.InvRadius * control.InvRadius / r2 ) * pos + control.InvCenter;
       
        float an = atan2(pos.y,pos.x) + control.InvAngle;
        float ra = sqrt(pos.y * pos.y + pos.x * pos.x);
        pos.x = cos(an)*ra;
        pos.y = sin(an)*ra;
        float de = DE_KLEINIAN2(pos,control,orbitTrap);
        de = r2 * de / (control.InvRadius * control.InvRadius + r * de);
        return de;
    }
   
    return DE_KLEINIAN2(pos,control,orbitTrap);
}

constant int MAX_MARCHING_STEPS = 255;
constant float MIN_DIST = 0.00002;
constant float MAX_DIST = 60;

float3 shortest_dist(float3 eye, float3 marchingDirection,device Control &control,thread float4 &orbitTrap) {
    float dist,hop = 0;
    float3 ans = float3(MIN_DIST,0,0);
    float secondSurface = control.secondSurface;
    int i = 0;
   
    for(; i < MAX_MARCHING_STEPS; ++i) {
        dist = DE(eye + ans.x * marchingDirection,control,orbitTrap);
        if(dist < MIN_DIST) {
            if(secondSurface == 0.0) break;     // secondSurface is disabled (equals 0), or has 2already been used
            ans.x += secondSurface;             // move along ray, and start looking for 2nd surface
            secondSurface = 0;                  // set to zero as 'already been used' marker
        }

        ans.x += dist;
        if(ans.x >= MAX_DIST) break;
       
        // don't let average distance be driven into the dirt
        if(dist >= 0.0001) hop = mix(hop,dist,0.95);
    }
   
    ans.y = float(i);
    ans.z = hop;
    return ans;
}

Return to Gallery


Powered by SMF Gallery Pro