Показать сообщение отдельно
Старый 24.02.2013, 22:07   #1
dsd
Мастер
 
Аватар для dsd
 
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений
(для 1,836 пользователей)
Simplex noise 2d 3d 4d

по мотивам: http://webstaff.itn.liu.se/~stegu/si...mplexnoise.pdf




using System;
using UnityEngine;
using System.Collections.Generic;

public class 
SimplexNoise : MonoBehaviour {
    
    public 
float zScale = 70.0f;
    public 
float overallScale = 0.1f;
    public 
int seed = 158;
    
    private static 
Vector3[] grad3 = {
        new 
Vector3(1,1,0),new Vector3(-1,1,0),new Vector3(1,-1,0),new Vector3(-1,-1,0),
         new 
Vector3(1,0,1),new Vector3(-1,0,1),new Vector3(1,0,-1),new Vector3(-1,0,-1),
         new 
Vector3(0,1,1),new Vector3(0,-1,1),new Vector3(0,1,-1),new Vector3(0,-1,-1)};

    private static 
Vector4[] grad4= {
        new 
Vector4(0,1,1,1),    new Vector4(0,1,1,-1),     new Vector4(0,1,-1,1),     new Vector4(0,1,-1,-1),
         new 
Vector4(0,-1,1,1),    new Vector4(0,-1,1,-1), new Vector4(0,-1,-1,1), new Vector4(0,-1,-1,-1),
         new 
Vector4(1,0,1,1),     new Vector4(1,0,1,-1),     new Vector4(1,0,-1,1),     new Vector4(1,0,-1,-1),
        new 
Vector4(-1,0,1,1),     new Vector4(-1,0,1,-1), new Vector4(-1,0,-1,1), new Vector4(-1,0,-1,-1),
        new 
Vector4(1,1,0,1),     new Vector4(1,1,0,-1),     new Vector4(1,-1,0,1),     new Vector4(1,-1,0,-1),
        new 
Vector4(-1,1,0,1),     new Vector4(-1,1,0,-1), new Vector4(-1,-1,0,1), new Vector4(-1,-1,0,-1),
        new 
Vector4(1,1,1,0),     new Vector4(1,1,-1,0),     new Vector4(1,-1,1,0),     new Vector4(1,-1,-1,0),
        new 
Vector4(-1,1,1,0),     new Vector4(-1,1,-1,0), new Vector4(-1,-1,1,0), new Vector4(-1,-1,-1,0)};
    
    
// A lookup table to traverse the simplex around a given point in 4D.
     // Details can be found where this table is used, in the 4D noise method.
    
private static Vector4[] simplex = {
        new 
Vector4(0,1,2,3),new Vector4(0,1,3,2),new Vector4(0,0,0,0),new Vector4(0,2,3,1),new Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(1,2,3,0),
        new 
Vector4(0,2,1,3),new Vector4(0,0,0,0),new Vector4(0,3,1,2),new Vector4(0,3,2,1),new Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(1,3,2,0),
        new 
Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(0,0,0,0),
        new 
Vector4(1,2,0,3),new Vector4(0,0,0,0),new Vector4(1,3,0,2),new Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(2,3,0,1),new Vector4(2,3,1,0),
        new 
Vector4(1,0,2,3),new Vector4(1,0,3,2),new Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(2,0,3,1),new Vector4(0,0,0,0),new Vector4(2,1,3,0),
        new 
Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(0,0,0,0),
        new 
Vector4(2,0,1,3),new Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(3,0,1,2),new Vector4(3,0,2,1),new Vector4(0,0,0,0),new Vector4(3,1,2,0),
        new 
Vector4(2,1,0,3),new Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(0,0,0,0),new Vector4(3,1,0,2),new Vector4(0,0,0,0),new Vector4(3,2,0,1),new Vector4(3,2,1,0)};
    
    
    private static 
int[] p = new int[256];
    
// To remove the need for index wrapping, float the permutation table length
    
private static int[] perm = new int[512];

        
    
// Use this for initialization
    
void Start () {    
        
System.Random rand = new System.Random(seed);
        for(
int i=0; i<256; i++) p[i] = rand.Next(0,255); 
        for(
int i=0; i<512; i++) perm[i]=p[i & 255];
    }
    
// Update is called once per frame
    
void Update () {
    
    }
    
// This method is a *lot* faster than using (int)Math.floor(x)
     
private static int fastfloor(float x) {
         return 
x>0 ? (int)x : (int)x-1;
     }
    
    private static 
float dot(Vector3 gradient,Vector2 coords){
        return    
gradient.x*coords.x + gradient.y*coords.y;
    }
    
    private static 
float dot(Vector3 gradient,Vector3 coords){
        return    
gradient.x*coords.x + gradient.y*coords.y + gradient.z*coords.z;
    }
    
    private static 
float dot(Vector4 gradient,Vector4 coords){
        return    
gradient.x*coords.x + gradient.y*coords.y + gradient.z*coords.z + gradient.w*coords.w;
    }    
    
// 2D simplex noise
    
public float noise(float xin, float yin) {
        
xin = xin * overallScale;
        
yin = yin * overallScale;
        
float n0, n1, n2;
        
float F2 = 0.5f*((float)Math.Sqrt(3.0f)-1.0f);
        
float s = (xin+yin)*F2; 
        
int i = fastfloor(xin+s);
        
int j = fastfloor(yin+s);
        
float G2 = (3.0f-(float)Math.Sqrt(3.0f))/6.0f;
        
float t = (i+j)*G2;
        
float X0 = i-t; 
        
float Y0 = j-t;
        
float x0 = xin-X0; 
        
float y0 = yin-Y0;
        
int i1, j1; 
        if(
x0>y0) {i1=1; j1=0;} 
        else {
i1=0; j1=1;} 
        
float x1 = x0 - i1 + G2;
        
float y1 = y0 - j1 + G2;
        
float x2 = x0 - 1.0f + 2.0f * G2;
        
float y2 = y0 - 1.0f + 2.0f * G2;
        
int ii = i & 255;
        
int jj = j & 255;
        
int gi0 = perm[ii+perm[jj]] % 12;
        
int gi1 = perm[ii+i1+perm[jj+j1]] % 12;
        
int gi2 = perm[ii+1+perm[jj+1]] % 12;
        
float t0 = 0.5f - x0*x0-y0*y0;
        if(
t0<0) n0 = 0.0f;
        else {
            
t0 *= t0;
            
n0 = t0 * t0 * dot(grad3[gi0],new Vector2(x0, y0));
        }
        
float t1 = 0.5f - x1*x1-y1*y1;
        if(
t1<0) n1 = 0.0f;
        else {
            
t1 *= t1;
            
n1 = t1 * t1 * dot(grad3[gi1],new Vector2(x1, y1));
        } 
float t2 = 0.5f - x2*x2-y2*y2;
        if(
t2<0) n2 = 0.0f;
        else {
            
t2 *= t2;
            
n2 = t2 * t2 * dot(grad3[gi2],new Vector2(x2, y2));
        }
        return 
zScale * (n0 + n1 + n2);
    }    

// 3D simplex noise
    
public float noise(float xin, float yin, float zin) {
        
xin = xin * overallScale;
        
yin = yin * overallScale;
        
zin = zin * overallScale;
        
float n0, n1, n2, n3;
        
float F3 = 1.0f/3.0f;
        
float s = (xin+yin+zin)*F3;
        
int i = fastfloor(xin+s);
        
int j = fastfloor(yin+s);
        
int k = fastfloor(zin+s);
        
float G3 = 1.0f/6.0f;
        
float t = (i+j+k)*G3; 
        
float X0 = i-t;
        
float Y0 = j-t;
        
float Z0 = k-t;
        
float x0 = xin-X0;
        
float y0 = yin-Y0;
        
float z0 = zin-Z0;
        
int i1, j1, k1;
        
int i2, j2, k2;
        if(
x0>=y0) {
        if(
y0>=z0)
        { 
i1=1; j1=0; k1=0; i2=1; j2=1; k2=0; }
        else if(
x0>=z0) { i1=1; j1=0; k1=0; i2=1; j2=0; k2=1; } 
        else { 
i1=0; j1=0; k1=1; i2=1; j2=0; k2=1; }
        }
        else {
        if(
y0<z0) { i1=0; j1=0; k1=1; i2=0; j2=1; k2=1; }
        else if(
x0<z0) { i1=0; j1=1; k1=0; i2=0; j2=1; k2=1; }
        else { 
i1=0; j1=1; k1=0; i2=1; j2=1; k2=0; }
        }
        
float x1 = x0 - i1 + G3;
        
float y1 = y0 - j1 + G3;
        
float z1 = z0 - k1 + G3;
        
float x2 = x0 - i2 + 2.0f*G3;
        
float y2 = y0 - j2 + 2.0f*G3;
        
float z2 = z0 - k2 + 2.0f*G3;
        
float x3 = x0 - 1.0f + 3.0f*G3;
        
float y3 = y0 - 1.0f + 3.0f*G3;
        
float z3 = z0 - 1.0f + 3.0f*G3;
        
        
int ii = i & 255;
        
int jj = j & 255;
        
int kk = k & 255;
        
        
int gi0 = perm[ii+perm[jj+perm[kk]]] % 12;
        
int gi1 = perm[ii+i1+perm[jj+j1+perm[kk+k1]]] % 12;
        
int gi2 = perm[ii+i2+perm[jj+j2+perm[kk+k2]]] % 12;
        
int gi3 = perm[ii+1+perm[jj+1+perm[kk+1]]] % 12;

        
float t0 = 0.5f - x0*x0 - y0*y0 - z0*z0;
        if(
t0<0) n0 = 0.0f;
        else {
        
t0 *= t0;
        
n0 = t0 * t0 * dot(grad3[gi0], new Vector3(x0, y0, z0));
        }
        
float t1 = 0.5f - x1*x1 - y1*y1 - z1*z1;
        if(
t1<0) n1 = 0.0f;
        else {
        
t1 *= t1;
        
n1 = t1 * t1 * dot(grad3[gi1], new Vector3(x1, y1, z1));
        }
        
float t2 = 0.5f - x2*x2 - y2*y2 - z2*z2;
        if(
t2<0) n2 = 0.0f;
        else {
        
t2 *= t2;
        
n2 = t2 * t2 * dot(grad3[gi2], new Vector3(x2, y2, z2));
        }
        
float t3 = 0.5f - x3*x3 - y3*y3 - z3*z3;
        if(
t3<0) n3 = 0.0f;
        else {
        
t3 *= t3;
        
n3 = t3 * t3 * dot(grad3[gi3], new Vector3(x3, y3, z3));
        }
    return 
zScale * (n0 + n1 + n2 + n3);
    } 

// 4D simplex noise
    
public float noise(float x, float y, float z, float w) {
        
x = x * overallScale;
        
y = y * overallScale;
        
z = z * overallScale;
        
w = w * overallScale;
        
float F4 = ((float)Math.Sqrt(5.0f)-1.0f)/4.0f;
        
float G4 = (5.0f-(float)Math.Sqrt(5.0f))/20.0f;
        
float n0, n1, n2, n3, n4; 

        
float s = (x + y + z + w) * F4; 
        
int i = fastfloor(x + s);
        
int j = fastfloor(y + s);
        
int k = fastfloor(z + s);
        
int l = fastfloor(w + s);
        
float t = (i + j + k + l) * G4; 
        
float X0 = i - t; 
        
float Y0 = j - t;
        
float Z0 = k - t;
        
float W0 = l - t;
        
float x0 = x - X0; 
        
float y0 = y - Y0;
        
float z0 = z - Z0;
        
float w0 = w - W0;
        
        
int c1 = (x0 > y0) ? 32 : 0;
        
int c2 = (x0 > z0) ? 16 : 0;
        
int c3 = (y0 > z0) ? 8 : 0;
        
int c4 = (x0 > w0) ? 4 : 0;
        
int c5 = (y0 > w0) ? 2 : 0;
        
int c6 = (z0 > w0) ? 1 : 0;
        
int c = c1 + c2 + c3 + c4 + c5 + c6;
        
int i1, j1, k1, l1;
        
int i2, j2, k2, l2;
        
int i3, j3, k3, l3;
        
        
i1 = simplex[c].x>=3 ? 1 : 0;
        
j1 = simplex[c].y>=3 ? 1 : 0;
        
k1 = simplex[c].z>=3 ? 1 : 0;
        
l1 = simplex[c].w>=3 ? 1 : 0;
        
i2 = simplex[c].x>=2 ? 1 : 0;
        
j2 = simplex[c].y>=2 ? 1 : 0; 
        
k2 = simplex[c][2]>=2 ? 1 : 0;
        
l2 = simplex[c].w>=2 ? 1 : 0;
        
        
i3 = simplex[c].x>=1 ? 1 : 0;
        
j3 = simplex[c].y>=1 ? 1 : 0;
        
k3 = simplex[c].z>=1 ? 1 : 0;
        
l3 = simplex[c].w>=1 ? 1 : 0;
        
        
float x1 = x0 - i1 + G4;
        
float y1 = y0 - j1 + G4;
        
float z1 = z0 - k1 + G4;
        
float w1 = w0 - l1 + G4;
        
float x2 = x0 - i2 + 2.0f*G4;
        
float y2 = y0 - j2 + 2.0f*G4;
        
float z2 = z0 - k2 + 2.0f*G4;
        
float w2 = w0 - l2 + 2.0f*G4;
        
float x3 = x0 - i3 + 3.0f*G4;
        
float y3 = y0 - j3 + 3.0f*G4;
        
float z3 = z0 - k3 + 3.0f*G4;
        
float w3 = w0 - l3 + 3.0f*G4;
        
float x4 = x0 - 1.0f + 4.0f*G4;
        
float y4 = y0 - 1.0f + 4.0f*G4;
        
float z4 = z0 - 1.0f + 4.0f*G4;
        
float w4 = w0 - 1.0f + 4.0f*G4;
        
        
int ii = i & 255;
        
int jj = j & 255;
        
int kk = k & 255;
        
int ll = l & 255;
        
int gi0 = perm[ii+perm[jj+perm[kk+perm[ll]]]] % 32;
        
int gi1 = perm[ii+i1+perm[jj+j1+perm[kk+k1+perm[ll+l1]]]] % 32;
        
int gi2 = perm[ii+i2+perm[jj+j2+perm[kk+k2+perm[ll+l2]]]] % 32;
        
int gi3 = perm[ii+i3+perm[jj+j3+perm[kk+k3+perm[ll+l3]]]] % 32;
        
int gi4 = perm[ii+1+perm[jj+1+perm[kk+1+perm[ll+1]]]] % 32;
        
        
float t0 = 0.5f - x0*x0 - y0*y0 - z0*z0 - w0*w0;
        if(
t0<0) n0 = 0.0f;
        else {
        
t0 *= t0;
        
n0 = t0 * t0 * dot(grad4[gi0], new Vector4(x0, y0, z0, w0));
        }
        
float t1 = 0.5f - x1*x1 - y1*y1 - z1*z1 - w1*w1;
        if(
t1<0) n1 = 0.0f;
        else {
        
t1 *= t1;
        
n1 = t1 * t1 * dot(grad4[gi1], new Vector4(x1, y1, z1, w1));
        }
        
float t2 = 0.5f - x2*x2 - y2*y2 - z2*z2 - w2*w2;
        if(
t2<0) n2 = 0.0f;
        else {
        
t2 *= t2;
        
n2 = t2 * t2 * dot(grad4[gi2], new Vector4(x2, y2, z2, w2));
        }
        
float t3 = 0.5f - x3*x3 - y3*y3 - z3*z3 - w3*w3;
        if(
t3<0) n3 = 0.0f;
        else {
        
t3 *= t3;
        
n3 = t3 * t3 * dot(grad4[gi3], new Vector4(x3, y3, z3, w3));
        }
        
float t4 = 0.5f - x4*x4 - y4*y4 - z4*z4 - w4*w4;
        if(
t4<0) n4 = 0.0f;
        else {
        
t4 *= t4;
        
n4 = t4 * t4 * dot(grad4[gi4], new Vector4(x4, y4, z4, w4));
        }
        
        return 
zScale * (n0 + n1 + n2 + n3 + n4);
    }
    
} 

Последний раз редактировалось dsd, 26.02.2013 в 03:27.
(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо dsd за это полезное сообщение:
MadMedic (08.03.2013), pax (25.02.2013)