Thursday, April 16, 2026

What’s the error in my model of 3D OpenSimplex2S?


I used to make use of a Perlin operate to create 3D noise. I am making an attempt to modify to OpenSimplex2S to be a bit extra environment friendly (higher efficiency and noise high quality in 3D house), however I did not simply copy and paste. I attempted to review how the algorithm labored and create my very own model.

It has been 5 days and I have never gotten anyplace, and I’ve a ton of code variations that I am probably not certain what to do with…

That is the OpenSimplex code I wrote:

    float OpenSimplex(vec3 p){
        // Transformation to Tetrahedral Area
        float s = (p.x + p.y + p.z)/3.0;
        vec3 t = p + vec3(s);
        vec3 i = ground(t);
        float fx = t.x - i.x;
        float fy = t.y - i.y;
        float fz = t.z - i.z;
        
        ivec3 cell = ivec3(i);
        
        ivec3 p1 = cell+ivec3(0);
        ivec3 i2;
        ivec3 i3;
        if(fx >= fy){
            if(fy >= fz){
                i2 = ivec3(1,0,0);
                i3 = ivec3(1,1,0);
            }else if(fx >= fz){
                i2 = ivec3(1,0,0);
                i3 = ivec3(1,0,1);
            }else{
                i2 = ivec3(0,0,1);
                i3 = ivec3(1,0,1);
            }
        }else{
            if(fy < fz){
                i2 = ivec3(0,0,1);
                i3 = ivec3(0,1,1);
            }else if(fx < fz){
                i2 = ivec3(0,1,0);
                i3 = ivec3(0,1,1);
            }else{
                i2 = ivec3(0,1,0);
                i3 = ivec3(1,1,0);
            }
        }
        ivec3 p2 = cell + i2;
        ivec3 p3 = cell + i3;
        ivec3 p4 = cell+ivec3(1);
        
        // Vectors of every Level (LUT already normalized).
        vec3 d1 = pontos[idx(p1)];
        vec3 d2 = pontos[idx(p2)];
        vec3 d3 = pontos[idx(p3)];
        vec3 d4 = pontos[idx(p4)];
        
        // Vectors of the Level in Tetrahedral Area to the factors.
        vec3 v1 = t - p1;
        vec3 v2 = t - p2;
        vec3 v3 = t - p3;
        vec3 v4 = t - p4;
        
        // Attenuation calculation for every level.
        float limite = 0.6;
        float f1 = dot(v1,v1);
        f1 = f1 >= limite ? 0.0 : pow(limite - f1,4);
        float f2 = dot(v2,v2);
        f2 = f2 >= limite ? 0.0 : pow(limite - f2,4);
        float f3 = dot(v3,v3);
        f3 = f3 >= limite ? 0.0 : pow(limite - f3,4);
        float f4 = dot(v4,v4);
        f4 = f4 >= limite ? 0.0 : pow(limite - f4,4);
        
        // Ultimate Calculation
        float remaining = 0.0;
        remaining += f1*dot(v1,d1);
        remaining += f2*dot(v2,d2);
        remaining += f3*dot(v3,d3);
        remaining += f4*dot(v4,d4);
        
        return remaining;
    }

These are the capabilities I used to arrange the LUT:

    int wrap(int x, int max){
        return ((xpercentmax)+max)%max;
    }

    int idx(ivec3 c){
        const int gs = 27;
        ivec3 cq = ivec3(wrap(c.x,gs),wrap(c.y,gs),wrap(c.z,gs));
        return cq.x+gs*cq.y+gs*gs*cq.z;
    }

The issue is that once I run it utilizing a easy Ray Marcher to check the noise, I leap on to a sure distance and that is the end result (there are a number of photos nevertheless it’s the identical end result):

What’s the error in my model of 3D OpenSimplex2S?

enter image description here

enter image description here

You possibly can see the tetrahedrons; this was the perfect model I may obtain to verify if the algorithm was working, however the result’s so unusual that I am simply questioning what’s occurring… Can anybody with expertise in creating 3D noise inform me what’s incorrect with my code? I believed the error may be within the calculation that selects the vectors connecting the purpose in 3D house with the tetrahedrons, however I’ve messed with that a lot that now I don’t know what I am doing.

replace 1

I rewrote all of the OpenSimplex2S code, making an attempt to correctly separate regular house from tetrahedral house… However it nonetheless would not work. I’ve revised the code a number of instances and the end result continues to be unchanged, however I’ve tried to make the code cleaner:

float OpenSimplex2S(vec3 p){
        vec3 pf = ground(p);
        ivec3 cell = ivec3(pf);
        
        float pfv = (p.x+p.y+p.z)/3;
        vec3 pt = p + pfv;
        float fx = pt.x - ground(pt.x);
        float fy = pt.y - ground(pt.y);
        float fz = pt.z - ground(pt.z);
        
        ivec3 p1 = ivec3(0);
        ivec3 p2 = ivec3(0);
        ivec3 p3 = ivec3(0);
        ivec3 p4 = ivec3(1);
        
        if(fx >= fy){
            if(fy >= fz){
                p2 = ivec3(1,0,0);
                p3 = ivec3(1,1,0);
            }else if(fx >= fz){
                p2 = ivec3(1,0,0);
                p3 = ivec3(1,0,1);
            }else{
                p2 = ivec3(0,0,1);
                p3 = ivec3(1,0,1);
            }
        }else{
            if(fy < fz){
                p2 = ivec3(0,0,1);
                p3 = ivec3(0,1,1);
            }else if(fx < fz){
                p2 = ivec3(0,1,0);
                p3 = ivec3(0,1,1);
            }else{
                p2 = ivec3(0,1,0);
                p3 = ivec3(1,1,0);
            }
        }
        
        vec3 d1 = pontos[idx(cell+p1)];
        vec3 d2 = pontos[idx(cell+p2)];
        vec3 d3 = pontos[idx(cell+p3)];
        vec3 d4 = pontos[idx(cell+p4)];
        
        // Factors within the Area of the Tetrahedron
        // pt is already a degree within the house of the tetrahedron... However the others...
        float pfv1 = (cell.x+p1.x+cell.y+p1.y+cell.z+p1.z)/3;
        vec3 pt1 = cell + p1 + vec3(pfv1);
        float pfv2 = (cell.x+p2.x+cell.y+p2.y+cell.z+p2.z)/3;
        vec3 pt2 = cell + p2 + vec3(pfv2);
        float pfv3 = (cell.x+p3.x+cell.y+p3.y+cell.z+p3.z)/3;
        vec3 pt3 = cell + p3 + vec3(pfv3);
        float pfv4 = (cell.x+p4.x+cell.y+p4.y+cell.z+p4.z)/3;
        vec3 pt4 = cell + p4 + vec3(pfv4);
        
        // Vectors for the factors within the Tetrahedron
        vec3 v1 = pt - pt1;
        vec3 v2 = pt - pt2;
        vec3 v3 = pt - pt3;
        vec3 v4 = pt - pt4;
        
        // Mitigation
        float limite = 0.6;
        float f1 = dot(v1,v1);
        f1 = f1 >= limite ? 0.0 : pow(limite - f1, 4);
        float f2 = dot(v2,v2);
        f2 = f2 >= limite ? 0.0 : pow(limite - f2, 4);
        float f3 = dot(v3,v3);
        f3 = f3 >= limite ? 0.0 : pow(limite - f3, 4);
        float f4 = dot(v4,v4);
        f4 = f4 >= limite ? 0.0 : pow(limite - f4, 4);
        
        float remaining = 0.0;
        remaining += f1*dot(v1,d1);
        remaining += f2*dot(v2,d2);
        remaining += f3*dot(v3,d3);
        remaining += f4*dot(v4,d4);
        
        return remaining;
}

enter image description here

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisement -spot_img

Latest Articles