public void CalcDistance(int seed, real3 p, int3 pr, int3 primedBase, float cellularJitter, ref real distance0, ref real distance1, ref int closestHash) { for (int xi = pr.x - 1; xi <= pr.x + 1; xi++) { int yPrimed = primedBase.y; for (int yi = pr.y - 1; yi <= pr.y + 1; yi++) { int zPrimed = primedBase.z; for (int zi = pr.z - 1; zi <= pr.z + 1; zi++) { int hash = Hash(seed, primedBase.x, yPrimed, zPrimed); int idx = hash & (255 << 2); real vecX = (float)(xi - p.x) + RandVecs3D[idx] * cellularJitter; real vecY = (float)(yi - p.y) + RandVecs3D[idx | 1] * cellularJitter; real vecZ = (float)(zi - p.z) + RandVecs3D[idx | 2] * cellularJitter; real newDistance = abs(vecX) + abs(vecY) + abs(vecZ); distance1 = max(min(distance1, newDistance), distance0); if (newDistance < distance0) { distance0 = newDistance; closestHash = hash; } zPrimed += PrimeZ; } yPrimed += PrimeY; } primedBase.x += PrimeX; } }
internal static void GradCoordDual(int seed, int xPrimed, int yPrimed, int zPrimed, real3 pd, out real3 po) { int hash = Hash(seed, xPrimed, yPrimed, zPrimed); int index1 = hash & (63 << 2); int index2 = (hash >> 6) & (255 << 2); real3 pg = new real3(Gradients3D[index1], Gradients3D[index1 | 1], Gradients3D[index1 | 2]); real3 value = pd * pg; po = (value.x + value.y + value.z) * new real3(RandVecs3D[index2], RandVecs3D[index2 | 1], RandVecs3D[index2 | 2]); }
public void Warp(int seed, float frequency, float amp, real3 ps, ref real3 p) { real3 pf = ps * frequency; int3 p0 = FastFloor(pf); real3 s = InterpHermite(pf - p0); p0 *= Prime; int3 p1 = p0 + Prime; int hash0 = Hash(seed, p0.x, p0.y, p0.z) & (255 << 2); int hash1 = Hash(seed, p1.x, p0.y, p0.z) & (255 << 2); real lx0x = lerp(RandVecs3D[hash0], RandVecs3D[hash1], s.x); real ly0x = lerp(RandVecs3D[hash0 | 1], RandVecs3D[hash1 | 1], s.x); real lz0x = lerp(RandVecs3D[hash0 | 2], RandVecs3D[hash1 | 2], s.x); hash0 = Hash(seed, p0.x, p1.y, p0.z) & (255 << 2); hash1 = Hash(seed, p1.x, p1.y, p0.z) & (255 << 2); real lx1x = lerp(RandVecs3D[hash0], RandVecs3D[hash1], s.x); real ly1x = lerp(RandVecs3D[hash0 | 1], RandVecs3D[hash1 | 1], s.x); real lz1x = lerp(RandVecs3D[hash0 | 2], RandVecs3D[hash1 | 2], s.x); real lx0y = lerp(lx0x, lx1x, s.y); real ly0y = lerp(ly0x, ly1x, s.y); real lz0y = lerp(lz0x, lz1x, s.y); hash0 = Hash(seed, p0.x, p0.y, p1.z) & (255 << 2); hash1 = Hash(seed, p1.x, p0.y, p1.z) & (255 << 2); lx0x = lerp(RandVecs3D[hash0], RandVecs3D[hash1], s.x); ly0x = lerp(RandVecs3D[hash0 | 1], RandVecs3D[hash1 | 1], s.x); lz0x = lerp(RandVecs3D[hash0 | 2], RandVecs3D[hash1 | 2], s.x); hash0 = Hash(seed, p0.x, p1.y, p1.z) & (255 << 2); hash1 = Hash(seed, p1.x, p1.y, p1.z) & (255 << 2); lx1x = lerp(RandVecs3D[hash0], RandVecs3D[hash1], s.x); ly1x = lerp(RandVecs3D[hash0 | 1], RandVecs3D[hash1 | 1], s.x); lz1x = lerp(RandVecs3D[hash0 | 2], RandVecs3D[hash1 | 2], s.x); p.x += lerp(lx0y, lerp(lx0x, lx1x, s.y), s.z) * amp; p.y += lerp(ly0y, lerp(ly0x, ly1x, s.y), s.z) * amp; p.z += lerp(lz0y, lerp(lz0x, lz1x, s.y), s.z) * amp; }
public real GetValue(int seed, real3 p) { mCellularJitterModifier = 1; // temp int3 pr = FastRound(p); real distance0 = real.MaxValue; real distance1 = real.MaxValue; int closestHash = 0; float cellularJitter = 0.39614353f * mCellularJitterModifier; int3 primedBase = (pr - 1) * Prime; distanceFunc.CalcDistance(seed, p, pr, primedBase, cellularJitter, ref distance0, ref distance1, ref closestHash); return(distance0 - 1); // TODO more return types }
public real GetValue(int seed, real3 p) { int3 p0 = FastFloor(p); real3 s = InterpHermite(p - p0); p0 *= Prime; int3 p1 = p0 + Prime; real xf00 = lerp(ValCoord(seed, p0.x, p0.y, p0.z), ValCoord(seed, p1.x, p0.y, p0.z), s.x); real xf10 = lerp(ValCoord(seed, p0.x, p1.y, p0.z), ValCoord(seed, p1.x, p1.y, p0.z), s.x); real xf01 = lerp(ValCoord(seed, p0.x, p0.y, p1.z), ValCoord(seed, p1.x, p0.y, p1.z), s.x); real xf11 = lerp(ValCoord(seed, p0.x, p1.y, p1.z), ValCoord(seed, p1.x, p1.y, p1.z), s.x); real yf0 = lerp(xf00, xf10, s.y); real yf1 = lerp(xf01, xf11, s.y); return(lerp(yf0, yf1, s.z)); }
public real GetValue(int seed, real3 p) { int3 p0 = FastFloor(p); real3 d0 = p - p0; real3 d1 = d0 - 1; real3 s = InterpQuintic(d0); p0 *= Prime; int3 p1 = p0 + Prime; real xf00 = lerp(GradCoord(seed, p0.x, p0.y, p0.z, d0.x, d0.y, d0.z), GradCoord(seed, p1.x, p0.y, p0.z, d1.x, d0.y, d0.z), s.x); real xf10 = lerp(GradCoord(seed, p0.x, p1.y, p0.z, d0.x, d1.y, d0.z), GradCoord(seed, p1.x, p1.y, p0.z, d1.x, d1.y, d0.z), s.x); real xf01 = lerp(GradCoord(seed, p0.x, p0.y, p1.z, d0.x, d0.y, d1.z), GradCoord(seed, p1.x, p0.y, p1.z, d1.x, d0.y, d1.z), s.x); real xf11 = lerp(GradCoord(seed, p0.x, p1.y, p1.z, d0.x, d1.y, d1.z), GradCoord(seed, p1.x, p1.y, p1.z, d1.x, d1.y, d1.z), s.x); real yf0 = lerp(xf00, xf10, s.y); real yf1 = lerp(xf01, xf11, s.y); return(lerp(yf0, yf1, s.z) * 0.964921414852142333984375f); }
public real GetValue(int seed, real3 p) { int3 ijk = FastFloor(p); real3 pi = p - ijk; ijk *= Prime; int seed2 = seed + 1293373; int3 nMask = (int3)(-0.5f - pi); real3 p0 = pi + nMask; real a0 = 0.75f - p0.x * p0.x - p0.y * p0.y - p0.z * p0.z; real value = (a0 * a0) * (a0 * a0) * GradCoord(seed, ijk.x + (nMask.x & PrimeX), ijk.y + (nMask.y & PrimeY), ijk.z + (nMask.z & PrimeZ), p0.x, p0.y, p0.z); real3 p1 = pi - 0.5f; real a1 = 0.75f - p1.x * p1.x - p1.y * p1.y - p1.z * p1.z; value += (a1 * a1) * (a1 * a1) * GradCoord(seed2, ijk.x + PrimeX, ijk.y + PrimeY, ijk.z + PrimeZ, p1.x, p1.y, p1.z); real3 aFlipMask0 = ((nMask | 1) << 1) * p1; real3 aFlipMask1 = (-2 - (nMask << 2)) * p1 - 1.0f; bool skip5 = false; real a2 = aFlipMask0.x + a0; if (a2 > 0) { real x2 = p0.x - (nMask.x | 1); real y2 = p0.y; real z2 = p0.z; value += (a2 * a2) * (a2 * a2) * GradCoord(seed, ijk.x + (~nMask.x & PrimeX), ijk.y + (nMask.y & PrimeY), ijk.z + (nMask.z & PrimeZ), x2, y2, z2); } else { real a3 = aFlipMask0.y + aFlipMask0.z + a0; if (a3 > 0) { real x3 = p0.x; real y3 = p0.y - (nMask.y | 1); real z3 = p0.z - (nMask.z | 1); value += (a3 * a3) * (a3 * a3) * GradCoord(seed, ijk.x + (nMask.x & PrimeX), ijk.y + (~nMask.y & PrimeY), ijk.z + (~nMask.z & PrimeZ), x3, y3, z3); } real a4 = aFlipMask1.x + a1; if (a4 > 0) { real x4 = (nMask.x | 1) + p1.x; real y4 = p1.y; real z4 = p1.z; value += (a4 * a4) * (a4 * a4) * GradCoord(seed2, ijk.x + (nMask.x & (PrimeX * 2)), ijk.y + PrimeY, ijk.z + PrimeZ, x4, y4, z4); skip5 = true; } } bool skip9 = false; real a6 = aFlipMask0.y + a0; if (a6 > 0) { real x6 = p0.x; real y6 = p0.y - (nMask.y | 1); real z6 = p0.z; value += (a6 * a6) * (a6 * a6) * GradCoord(seed, ijk.x + (nMask.x & PrimeX), ijk.y + (~nMask.y & PrimeY), ijk.z + (nMask.z & PrimeZ), x6, y6, z6); } else { real a7 = aFlipMask0.x + aFlipMask0.z + a0; if (a7 > 0) { real x7 = p0.x - (nMask.x | 1); real y7 = p0.y; real z7 = p0.z - (nMask.z | 1); value += (a7 * a7) * (a7 * a7) * GradCoord(seed, ijk.x + (~nMask.x & PrimeX), ijk.y + (nMask.y & PrimeY), ijk.z + (~nMask.z & PrimeZ), x7, y7, z7); } real a8 = aFlipMask1.y + a1; if (a8 > 0) { real x8 = p1.x; real y8 = (nMask.y | 1) + p1.y; real z8 = p1.z; value += (a8 * a8) * (a8 * a8) * GradCoord(seed2, ijk.x + PrimeX, ijk.y + (nMask.y & (PrimeY << 1)), ijk.z + PrimeZ, x8, y8, z8); skip9 = true; } } bool skipD = false; real aA = aFlipMask0.z + a0; if (aA > 0) { real xA = p0.x; real yA = p0.y; real zA = p0.z - (nMask.z | 1); value += (aA * aA) * (aA * aA) * GradCoord(seed, ijk.x + (nMask.x & PrimeX), ijk.y + (nMask.y & PrimeY), ijk.z + (~nMask.z & PrimeZ), xA, yA, zA); } else { real aB = aFlipMask0.x + aFlipMask0.y + a0; if (aB > 0) { real xB = p0.x - (nMask.x | 1); real yB = p0.y - (nMask.y | 1); real zB = p0.z; value += (aB * aB) * (aB * aB) * GradCoord(seed, ijk.x + (~nMask.x & PrimeX), ijk.y + (~nMask.y & PrimeY), ijk.z + (nMask.z & PrimeZ), xB, yB, zB); } real aC = aFlipMask1.z + a1; if (aC > 0) { real xC = p1.x; real yC = p1.y; real zC = (nMask.z | 1) + p1.z; value += (aC * aC) * (aC * aC) * GradCoord(seed2, ijk.x + PrimeX, ijk.y + PrimeY, ijk.z + (nMask.z & (PrimeZ << 1)), xC, yC, zC); skipD = true; } } if (!skip5) { real a5 = aFlipMask1.y + aFlipMask1.z + a1; if (a5 > 0) { real x5 = p1.x; real y5 = (nMask.y | 1) + p1.y; real z5 = (nMask.z | 1) + p1.z; value += (a5 * a5) * (a5 * a5) * GradCoord(seed2, ijk.x + PrimeX, ijk.y + (nMask.y & (PrimeY << 1)), ijk.z + (nMask.z & (PrimeZ << 1)), x5, y5, z5); } } if (!skip9) { real a9 = aFlipMask1.x + aFlipMask1.z + a1; if (a9 > 0) { real x9 = (nMask.x | 1) + p1.x; real y9 = p1.y; real z9 = (nMask.z | 1) + p1.z; value += (a9 * a9) * (a9 * a9) * GradCoord(seed2, ijk.x + (nMask.x & (PrimeX * 2)), ijk.y + PrimeY, ijk.z + (nMask.z & (PrimeZ << 1)), x9, y9, z9); } } if (!skipD) { real aD = aFlipMask1.x + aFlipMask1.y + a1; if (aD > 0) { real xD = (nMask.x | 1) + p1.x; real yD = (nMask.y | 1) + p1.y; real zD = p1.z; value += (aD * aD) * (aD * aD) * GradCoord(seed2, ijk.x + (nMask.x & (PrimeX << 1)), ijk.y + (nMask.y & (PrimeY << 1)), ijk.z + PrimeZ, xD, yD, zD); } } return(value * 9.046026385208288f); }
public real GetValue(int seed, real3 p) { int3 ijk = FastRound(p); real3 p0 = p - ijk; int3 nSign = (int3)(-1.0f - p0) | 1; real3 a0 = nSign * -p0; ijk *= Prime; real value = 0; real a = (0.6f - p0.x * p0.x) - (p0.y * p0.y + p0.z * p0.z); for (int l = 0; ; l++) { if (a > 0) { value += (a * a) * (a * a) * GradCoord(seed, ijk.x, ijk.y, ijk.z, p0.x, p0.y, p0.z); } if (a0.x >= a0.y && a0.x >= a0.z) { real b = a + a0.x + a0.x; if (b > 1) { b -= 1; value += (b * b) * (b * b) * GradCoord(seed, ijk.x - nSign.x * PrimeX, ijk.y, ijk.z, p0.x + nSign.x, p0.y, p0.z); } } else if (a0.y > a0.x && a0.y >= a0.z) { real b = a + a0.y + a0.y; if (b > 1) { b -= 1; value += (b * b) * (b * b) * GradCoord(seed, ijk.x, ijk.y - nSign.y * PrimeY, ijk.z, p0.x, p0.y + nSign.y, p0.z); } } else { real b = a + a0.z + a0.z; if (b > 1) { b -= 1; value += (b * b) * (b * b) * GradCoord(seed, ijk.x, ijk.y, ijk.z - nSign.z * PrimeZ, p0.x, p0.y, p0.z + nSign.z); } } if (l == 1) { break; } a0 = 0.5f - a0; p0 = nSign * a0; a += (0.75f - a0.x) - (a0.y + a0.z); ijk += (nSign >> 1) & Prime; nSign = -nSign; seed = ~seed; } return(value * 32.69428253173828125f); }
internal static int3 FastRound(real3 f) { return(math.select((int3)(f - 0.5f), (int3)(f + 0.5f), f >= 0)); }
internal static real3 InterpQuinticDeriv(real3 t) { return(30 * t * t * (t * t - 2 * t + 1)); }
internal static real3 InterpHermiteDeriv(real3 t) { return(6 * t * (1 - t)); }
internal static real3 InterpHermite(real3 t) { return(t * t * (3 - 2 * t)); }
internal static real3 InterpQuintic(real3 t) { return(t * t * t * (t * (t * 6 - 15) + 10)); }
internal static int3 FastFloor(real3 f) { return(math.select((int3)f - 1, (int3)f, f >= 0)); }
public void Warp(int seed, float frequency, float amp, real3 ps, ref real3 p) { ps *= frequency; amp *= 7.71604938271605f; int3 ijk = FastRound(ps); real3 p0 = ps - ijk; int3 nSign = (int3)(-p0 - 1) | 1; real3 a0 = nSign * -p0; ijk *= Prime; real3 pv = 0; real a = (0.6f - p0.x * p0.x) - (p0.y * p0.y + p0.z * p0.z); for (int l = 0; ; l++) { if (a > 0) { real aaaa = (a * a) * (a * a); GradCoordOut(seed, ijk.x, ijk.y, ijk.z, out var po); pv += aaaa * po; } real b = a; int3 ijk1 = ijk; real3 p1 = p0; if (a0.x >= a0.y && a0.x >= a0.z) { p1.x += nSign.x; b = b + a0.x + a0.x; ijk1.x -= nSign.x * PrimeX; } else if (a0.y > a0.x && a0.y >= a0.z) { p1.y += nSign.y; b = b + a0.y + a0.y; ijk1.y -= nSign.y * PrimeY; } else { p1.z += nSign.z; b = b + a0.z + a0.z; ijk1.z -= nSign.z * PrimeZ; } if (b > 1) { b -= 1; real bbbb = (b * b) * (b * b); GradCoordOut(seed, ijk1.x, ijk1.y, ijk1.z, out var po); pv += bbbb * po; } if (l == 1) { break; } a0 = 0.5f - a0; p0 = nSign * a0; a += (0.75f - a0.x) - (a0.y + a0.z); ijk += (nSign >> 1) & Prime; nSign = -nSign; seed += 1293373; } p += pv * amp; }
public real GetValue(int seed, real3 p) { int3 p1 = FastFloor(p); real3 s = p - p1; p1 *= Prime; int3 p0 = p1 - Prime; int3 p2 = p1 + Prime; int3 p3 = p1 + unchecked (Prime * 2); var s1 = new real4 { x = ValCoord(seed, p0), y = ValCoord(seed, p0.x, p1.y, p0.z), z = ValCoord(seed, p0.x, p2.y, p0.z), w = ValCoord(seed, p0.x, p3.y, p0.z) }; var s2 = new real4 { x = ValCoord(seed, p1.x, p0.y, p0.z), y = ValCoord(seed, p1.x, p1.y, p0.z), z = ValCoord(seed, p1.x, p2.y, p0.z), w = ValCoord(seed, p1.x, p3.y, p0.z) }; var s3 = new real4 { x = ValCoord(seed, p2.x, p0.y, p0.z), y = ValCoord(seed, p2.x, p1.y, p0.z), z = ValCoord(seed, p2.x, p2.y, p0.z), w = ValCoord(seed, p2.x, p3.y, p0.z) }; var s4 = new real4 { x = ValCoord(seed, p3.x, p0.y, p0.z), y = ValCoord(seed, p3.x, p1.y, p0.z), z = ValCoord(seed, p3.x, p2.y, p0.z), w = ValCoord(seed, p3.x, p3.y, p0.z) }; var t1 = new real4 { x = ValCoord(seed, p0.x, p0.y, p1.z), y = ValCoord(seed, p0.x, p1.y, p1.z), z = ValCoord(seed, p0.x, p2.y, p1.z), w = ValCoord(seed, p0.x, p3.y, p1.z) }; var t2 = new real4 { x = ValCoord(seed, p1.x, p0.y, p1.z), y = ValCoord(seed, p1.x, p1.y, p1.z), z = ValCoord(seed, p1.x, p2.y, p1.z), w = ValCoord(seed, p1.x, p3.y, p1.z) }; var t3 = new real4 { x = ValCoord(seed, p2.x, p0.y, p1.z), y = ValCoord(seed, p2.x, p1.y, p1.z), z = ValCoord(seed, p2.x, p2.y, p1.z), w = ValCoord(seed, p2.x, p3.y, p1.z) }; var t4 = new real4 { x = ValCoord(seed, p3.x, p0.y, p1.z), y = ValCoord(seed, p3.x, p1.y, p1.z), z = ValCoord(seed, p3.x, p2.y, p1.z), w = ValCoord(seed, p3.x, p3.y, p1.z) }; var u1 = new real4 { x = ValCoord(seed, p0.x, p0.y, p2.z), y = ValCoord(seed, p0.x, p1.y, p2.z), z = ValCoord(seed, p0.x, p2.y, p2.z), w = ValCoord(seed, p0.x, p3.y, p2.z) }; var u2 = new real4 { x = ValCoord(seed, p1.x, p0.y, p2.z), y = ValCoord(seed, p1.x, p1.y, p2.z), z = ValCoord(seed, p1.x, p2.y, p2.z), w = ValCoord(seed, p1.x, p3.y, p2.z), }; var u3 = new real4 { x = ValCoord(seed, p2.x, p0.y, p2.z), y = ValCoord(seed, p2.x, p1.y, p2.z), z = ValCoord(seed, p2.x, p2.y, p2.z), w = ValCoord(seed, p2.x, p3.y, p2.z) }; var u4 = new real4 { x = ValCoord(seed, p3.x, p0.y, p2.z), y = ValCoord(seed, p3.x, p1.y, p2.z), z = ValCoord(seed, p3.x, p2.y, p2.z), w = ValCoord(seed, p3.x, p3.y, p2.z) }; var v1 = new real4 { x = ValCoord(seed, p0.x, p0.y, p3.z), y = ValCoord(seed, p0.x, p1.y, p3.z), z = ValCoord(seed, p0.x, p2.y, p3.z), w = ValCoord(seed, p0.x, p3.y, p3.z) }; var v2 = new real4 { x = ValCoord(seed, p1.x, p0.y, p3.z), y = ValCoord(seed, p1.x, p1.y, p3.z), z = ValCoord(seed, p1.x, p2.y, p3.z), w = ValCoord(seed, p1.x, p3.y, p3.z) }; var v3 = new real4 { x = ValCoord(seed, p2.x, p0.y, p3.z), y = ValCoord(seed, p2.x, p1.y, p3.z), z = ValCoord(seed, p2.x, p2.y, p3.z), w = ValCoord(seed, p2.x, p3.y, p3.z) }; var v4 = new real4 { x = ValCoord(seed, p3.x, p0.y, p3.z), y = ValCoord(seed, p3.x, p1.y, p3.z), z = ValCoord(seed, p3.x, p2.y, p3.z), w = ValCoord(seed, p3.x, p3.y, p3.z) }; var sl = CubicLerp(s1, s2, s3, s4, s.x); var tl = CubicLerp(t1, t2, t3, t4, s.x); var ul = CubicLerp(u1, u2, u3, u4, s.x); var vl = CubicLerp(v1, v2, v3, v4, s.x); var sf = new real4(sl.x, tl.x, ul.x, vl.x); var tf = new real4(sl.y, tl.y, ul.y, vl.y); var uf = new real4(sl.z, tl.z, ul.z, vl.z); var vf = new real4(sl.z, tl.z, ul.z, vl.z); return(CubicLerp(CubicLerp(sf, tf, uf, vf, s.y), s.z) * (1 / (1.5f * 1.5f * 1.5f))); }
internal static void GradCoordOut(int seed, int xPrimed, int yPrimed, int zPrimed, out real3 po) { int hash = Hash(seed, xPrimed, yPrimed, zPrimed) & (255 << 2); po = new real3(RandVecs3D[hash], RandVecs3D[hash | 1], RandVecs3D[hash | 2]); }