Мастер
Регистрация: 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.
|