protected virtual void UpdateNoisePropertyBlock(NoiseStruct noiseStruct) { NoisePropertyBlock.SetTexture("_Splerp", noiseStruct.splerpTexture); NoisePropertyBlock.SetTexture("_PerlinHash", NoiseUtils.PerlinHashTexture); switch (noiseStruct.renderType) { case RenderType.Render1D: NoisePropertyBlock.SetTexture("_Gradients", NoiseUtils.Gradients1DTexture); break; case RenderType.Render2D: NoisePropertyBlock.SetTexture("_Gradients", NoiseUtils.Gradients2DTexture); break; case RenderType.Render3D: NoisePropertyBlock.SetTexture("_Gradients", NoiseUtils.Gradients3DTexture); break; default: throw new ArgumentOutOfRangeException("noiseStruct", noiseStruct.renderType, "Given RenderType not supported."); } // TODO: worldTransform does not contain proper object position... why? NoisePropertyBlock.SetMatrix("_WorldTransform", noiseStruct.worldTransform ? noiseStruct.worldTransform.localToWorldMatrix : Matrix4x4.identity); NoisePropertyBlock.SetFloat("_Resolution", noiseStruct.resolution); NoisePropertyBlock.SetFloat("_Frequency", noiseStruct.frequency); NoisePropertyBlock.SetFloat("_Amplitude", noiseStruct.amplitude); }
protected override float Value2D(Vector3 point, NoiseStruct noiseStruct) { point *= noiseStruct.frequency; //Calculate Integer Lattice Points and interpolants t int i0X = Mathf.FloorToInt(point.x); int i0Y = Mathf.FloorToInt(point.y); var t0 = new Vector2(point.x - i0X, point.y - i0Y); i0X &= HashMask; i0Y &= HashMask; int i1X = i0X + 1; int i1Y = i0Y + 1; int h0 = NoiseUtils.PerlinHash[i0X]; int h1 = NoiseUtils.PerlinHash[i1X]; int h00 = NoiseUtils.PerlinHash[h0 + i0Y]; int h01 = NoiseUtils.PerlinHash[h0 + i1Y]; int h10 = NoiseUtils.PerlinHash[h1 + i0Y]; int h11 = NoiseUtils.PerlinHash[h1 + i1Y]; t0.x = NoiseUtils.Splerp(ref noiseStruct.splerp, 0f, 1f, t0.x); t0.y = NoiseUtils.Splerp(ref noiseStruct.splerp, 0f, 1f, t0.y); return (Mathf.Lerp(Mathf.Lerp(h00, h10, t0.x), Mathf.Lerp(h01, h11, t0.x), t0.y) * (1f / HashMask)); }
protected override float Value1D(Vector3 point, NoiseStruct noiseStruct) { point *= noiseStruct.frequency; //Calculate Integer Lattice Points int ix = Mathf.FloorToInt(point.x); ix &= HashMask; return(NoiseUtils.PerlinHash[ix] * (1f / HashMask)); }
protected override float Value1D(Vector3 point, NoiseStruct noiseStruct) { point *= noiseStruct.frequency; //Calculate Integer Lattice Points and interpolants t int i0X = Mathf.FloorToInt(point.x); float t = point.x - i0X; i0X &= HashMask; int i1X = i0X + 1; int h0 = NoiseUtils.PerlinHash[i0X]; int h1 = NoiseUtils.PerlinHash[i1X]; t = NoiseUtils.Splerp(ref noiseStruct.splerp, 0f, 1f, t); return(Mathf.Lerp(h0, h1, t) * (1f / HashMask)); }
public virtual void UpdateNoise(Renderer renderer, NoiseStruct noiseStruct) { //TODO: Seperate this and only call when needed switch (noiseStruct.renderType) { case RenderType.Render1D: renderer.sharedMaterial.EnableKeyword("RENDERTYPE_1D"); renderer.sharedMaterial.DisableKeyword("RENDERTYPE_2D"); renderer.sharedMaterial.DisableKeyword("RENDERTYPE_3D"); break; case RenderType.Render2D: renderer.sharedMaterial.DisableKeyword("RENDERTYPE_1D"); renderer.sharedMaterial.EnableKeyword("RENDERTYPE_2D"); renderer.sharedMaterial.DisableKeyword("RENDERTYPE_3D"); break; case RenderType.Render3D: renderer.sharedMaterial.DisableKeyword("RENDERTYPE_1D"); renderer.sharedMaterial.DisableKeyword("RENDERTYPE_2D"); renderer.sharedMaterial.EnableKeyword("RENDERTYPE_3D"); break; default: throw new ArgumentOutOfRangeException("noiseStruct", noiseStruct.renderType, "Given RenderType not supported."); } if (noiseStruct.range == Range) { renderer.sharedMaterial.DisableKeyword("RANGE_ADJUST"); renderer.sharedMaterial.EnableKeyword("RANGE_NOADJUST"); } else { renderer.sharedMaterial.EnableKeyword("RANGE_ADJUST"); renderer.sharedMaterial.DisableKeyword("RANGE_NOADJUST"); } renderer.GetPropertyBlock(NoisePropertyBlock); UpdateNoisePropertyBlock(noiseStruct); renderer.SetPropertyBlock(NoisePropertyBlock); }
public float Value(Vector3 point, NoiseStruct noiseStruct) { float value; switch (noiseStruct.renderType) { case RenderType.Render1D: value = Value1D(point, noiseStruct); break; case RenderType.Render2D: value = Value2D(point, noiseStruct); break; case RenderType.Render3D: value = Value3D(point, noiseStruct); break; default: throw new ArgumentOutOfRangeException("noiseStruct", noiseStruct.renderType, "Given RenderType not supported."); } if (noiseStruct.range != Range) { switch (noiseStruct.range) { case Range.OneGreaterZero: //Convert to OneGreaterZero value = (value / 2f) + 0.5f; break; case Range.OneAroundZero: //Convert to OneAroundZero value = (value - 0.5f) * 2f; break; default: throw new ArgumentOutOfRangeException(); } } return(value * noiseStruct.amplitude); }
protected override float Value2D(Vector3 point, NoiseStruct noiseStruct) { point *= noiseStruct.frequency; //Calculate Integer Lattice Points and interpolants t int i0X = Mathf.FloorToInt(point.x); int i0Y = Mathf.FloorToInt(point.y); var t0 = new Vector2(point.x - i0X, point.y - i0Y); var t1 = new Vector2(t0.x - 1f, t0.y - 1f); i0X &= NoiseUtils.HashMask; i0Y &= NoiseUtils.HashMask; int i1X = i0X + 1; int i1Y = i0Y + 1; int h0 = NoiseUtils.PerlinHash[i0X]; int h1 = NoiseUtils.PerlinHash[i1X]; int h00 = NoiseUtils.PerlinHash[h0 + i0Y]; int h01 = NoiseUtils.PerlinHash[h0 + i1Y]; int h10 = NoiseUtils.PerlinHash[h1 + i0Y]; int h11 = NoiseUtils.PerlinHash[h1 + i1Y]; var g00 = NoiseUtils.Gradients2D[h00 & NoiseUtils.GradientsMask2D]; var g01 = NoiseUtils.Gradients2D[h01 & NoiseUtils.GradientsMask2D]; var g10 = NoiseUtils.Gradients2D[h10 & NoiseUtils.GradientsMask2D]; var g11 = NoiseUtils.Gradients2D[h11 & NoiseUtils.GradientsMask2D]; float v00 = Vector2.Dot(g00, new Vector2(t0.x, t0.y)); float v01 = Vector2.Dot(g01, new Vector2(t0.x, t1.y)); float v10 = Vector2.Dot(g10, new Vector2(t1.x, t0.y)); float v11 = Vector2.Dot(g11, new Vector2(t1.x, t1.y)); //t0.x = NoiseUtils.Splerp(ref noiseStruct.splerp, 0f, 1f, t0.x); //t0.y = NoiseUtils.Splerp(ref noiseStruct.splerp, 0f, 1f, t0.y); t0.x = NoiseUtils.SmootherStep(t0.x); t0.y = NoiseUtils.SmootherStep(t0.y); return (Mathf.Lerp(Mathf.Lerp(v00, v10, t0.x), Mathf.Lerp(v01, v11, t0.x), t0.y) * NoiseUtils.Sqr2); }
protected override float Value3D(Vector3 point, NoiseStruct noiseStruct) { point *= noiseStruct.frequency; //Skew Point double skew = (point.x + point.y + point.z) * Skew3; //Determine surrounding unit cube with integer coorindates in skewed space i = (int)Math.Floor(point.x + skew); j = (int)Math.Floor(point.y + skew); k = (int)Math.Floor(point.z + skew); double unskew = (i + j + k) * Unskew3; u = point.x - i + unskew; v = point.y - j + unskew; w = point.z - k + unskew; A = new[] { 0, 0, 0 }; int hi = u >= w ? u >= v ? 0 : 1 : v >= w ? 1 : 2; int lo = u < w ? u < v ? 0 : 1 : v < w ? 1 : 2; return((float)(8.0 * (K(hi) + K(3 - hi - lo) + K(lo) + K(0)))); }
protected override float Value1D(Vector3 point, NoiseStruct noiseStruct) { point *= noiseStruct.frequency; //Calculate Integer Lattice Points and interpolants t int i0X = Mathf.FloorToInt(point.x); float t0 = point.x - i0X; float t1 = t0 - 1f; i0X &= NoiseUtils.HashMask; int i1X = i0X + 1; int h0 = NoiseUtils.PerlinHash[i0X]; int h1 = NoiseUtils.PerlinHash[i1X]; float g0 = NoiseUtils.Gradients1D[h0 & NoiseUtils.GradientsMask1D]; float g1 = NoiseUtils.Gradients1D[h1 & NoiseUtils.GradientsMask1D]; float v0 = g0 * t0; float v1 = g1 * t1; //t0 = NoiseUtils.Splerp(ref noiseStruct.splerp, 0f, 1f, t0); t0 = NoiseUtils.SmootherStep(t0); return(Mathf.Lerp(v0, v1, t0) * 2f); }
protected override float Value3D(Vector3 point, NoiseStruct noiseStruct) { point *= noiseStruct.frequency; float n0, n1, n2, n3; // Noise contributions form the four corners // Factor to skew simplex tetrahedron grid to unit cube grid float skew = (point.x + point.y + point.z) * Skew3; // Find integer lattice points in skewed space int i0 = Mathf.FloorToInt(point.x + skew); int j0 = Mathf.FloorToInt(point.y + skew); int k0 = Mathf.FloorToInt(point.z + skew); // Factor to unskew back to simplex tetrahedron grid float unskew = (i0 + j0 + k0) * Unskew3; // Unskew integer lattice points in skewed space back into simplex grid // This is now the origin point of our simplex cell, called first corner //var corner0 = new Vector3(i0 - unskew, j0 - unskew, k0 - unskew); // Relative coordinates from first corner to input point within simplex cell var t0 = new Vector3(point.x - i0 + unskew, point.y - j0 + unskew, point.z - k0 + unskew); // For the 3D case, the simplex shape is a slightly irregular tetrahedron. // Determine which simplex we are in. int i1, j1, k1; // Offsets for second corner of simplex cell in skewed space int i2, j2, k2; // Offsets for third corner of simplex cell in skewed space int i3 = 1, j3 = 1, k3 = 1; // Offsets for fourth corner of simplex cell in skewed space if (t0.x >= t0.y) { if (t0.y >= t0.z) // x > y > z { i1 = 1; j1 = 0; k1 = 0; i2 = 1; j2 = 1; k2 = 0; } else if (t0.x >= t0.z) // x > z > y { i1 = 1; j1 = 0; k1 = 0; i2 = 1; j2 = 0; k2 = 1; } else // z > x > y { i1 = 0; j1 = 0; k1 = 1; i2 = 1; j2 = 0; k2 = 1; } } else // t0.x < t0.y { if (t0.y < t0.z) // z > y > x { i1 = 0; j1 = 0; k1 = 1; i2 = 0; j2 = 1; k2 = 1; } else if (t0.x < t0.z) // y > z > x { i1 = 0; j1 = 1; k1 = 0; i2 = 0; j2 = 1; k2 = 1; } else // y > x > z { i1 = 0; j1 = 1; k1 = 0; i2 = 1; j2 = 1; k2 = 0; } } var t1 = new Vector3(t0.x - i1 + Unskew3, t0.y - j1 + Unskew3, t0.z - k1 + Unskew3); var t2 = new Vector3(t0.x - i2 + 2*Unskew3, t0.y - j2 + 2*Unskew3, t0.z - k2 + 2*Unskew3); var t3 = new Vector3(t0.x - i3 + 3*Unskew3, t0.y - j3 + 3*Unskew3, t0.z - k3 + 3*Unskew3); // Work out the hashed gradient indices gi of the four simplex corners int ii = i0 & NoiseUtils.HashMask; int jj = j0 & NoiseUtils.HashMask; int kk = k0 & NoiseUtils.HashMask; int gi0 = NoiseUtils.PerlinHash[NoiseUtils.PerlinHash[NoiseUtils.PerlinHash[kk ] + jj ] + ii] & NoiseUtils.GradientsMask3D; // Gradient index for first corner int gi1 = NoiseUtils.PerlinHash[NoiseUtils.PerlinHash[NoiseUtils.PerlinHash[kk + k1] + jj + j1] + ii + i1] & NoiseUtils.GradientsMask3D; // Gradient index for second corner int gi2 = NoiseUtils.PerlinHash[NoiseUtils.PerlinHash[NoiseUtils.PerlinHash[kk + k2] + jj + j2] + ii + i2] & NoiseUtils.GradientsMask3D; // Gradient index for third corner int gi3 = NoiseUtils.PerlinHash[NoiseUtils.PerlinHash[NoiseUtils.PerlinHash[kk + k3] + jj + j3] + ii + i3] & NoiseUtils.GradientsMask3D; // Gradient index for forth corner // Calculate the contribution c from the four corners float c0 = 0.6f - t0.x * t0.x - t0.y * t0.y - t0.z * t0.z; if (c0 < 0) n0 = 0.0f; else n0 = Mathf.Pow(c0, 4) * Vector3.Dot(NoiseUtils.Gradients3D[gi0], t0); float c1 = 0.6f - t1.x * t1.x - t1.y * t1.y - t1.z * t1.z; if (c1 < 0) n1 = 0.0f; else n1 = Mathf.Pow(c1, 4) * Vector3.Dot(NoiseUtils.Gradients3D[gi1], t1); float c2 = 0.6f - t2.x * t2.x - t2.y * t2.y - t2.z * t2.z; if (c2 < 0) n2 = 0.0f; else n2 = Mathf.Pow(c2, 4) * Vector3.Dot(NoiseUtils.Gradients3D[gi2], t2); float c3 = 0.6f - t3.x * t3.x - t3.y * t3.y - t3.z * t3.z; if (c3 < 0) n3 = 0.0f; else n3 = Mathf.Pow(c3, 4) * Vector3.Dot(NoiseUtils.Gradients3D[gi3], t3); // Add contributions from each corner to get the final noise value. // The result is scaled to return values in the interval [-1,1]. return 8.0f * (n0 + n1 + n2 + n3); }
protected override float Value3D(Vector3 point, NoiseStruct noiseStruct) { point *= noiseStruct.frequency; return(Mathf.Sin(point.x) * Mathf.Sin(point.y) * Mathf.Sin(point.z)); }
protected override float Value2D(Vector3 point, NoiseStruct noiseStruct) { point *= noiseStruct.frequency; return(0); }
protected override float Value1D(Vector3 point, NoiseStruct noiseStruct) { point *= 2 * Mathf.PI * noiseStruct.frequency; return(Mathf.Sin(point.x)); }
protected override float Value3D(Vector3 point, NoiseStruct noiseStruct) { return((float)m_random.NextDouble()); }
protected abstract float Value3D(Vector3 point, NoiseStruct noiseStruct);
protected override float Value3D(Vector3 point, NoiseStruct noiseStruct) { point *= noiseStruct.frequency; //Calculate Integer Lattice Points and interpolants t int i0X = Mathf.FloorToInt(point.x); int i0Y = Mathf.FloorToInt(point.y); int i0Z = Mathf.FloorToInt(point.z); //Get point relative to wavelet center var t0 = new Vector3(point.x - i0X, point.y - i0Y, point.z - i0Z); var t1 = new Vector3(t0.x - 1f, t0.y - 1f, t0.z - 1f); i0X &= NoiseUtils.HashMask; i0Y &= NoiseUtils.HashMask; i0Z &= NoiseUtils.HashMask; int i1X = i0X + 1; int i1Y = i0Y + 1; int i1Z = i0Z + 1; // Fold x,y,z using permuation table int h0 = NoiseUtils.PerlinHash[i0X]; int h1 = NoiseUtils.PerlinHash[i1X]; int h00 = NoiseUtils.PerlinHash[h0 + i0Y]; int h01 = NoiseUtils.PerlinHash[h0 + i1Y]; int h10 = NoiseUtils.PerlinHash[h1 + i0Y]; int h11 = NoiseUtils.PerlinHash[h1 + i1Y]; int h000 = NoiseUtils.PerlinHash[h00 + i0Z]; int h001 = NoiseUtils.PerlinHash[h00 + i1Z]; int h010 = NoiseUtils.PerlinHash[h01 + i0Z]; int h011 = NoiseUtils.PerlinHash[h01 + i1Z]; int h100 = NoiseUtils.PerlinHash[h10 + i0Z]; int h101 = NoiseUtils.PerlinHash[h10 + i1Z]; int h110 = NoiseUtils.PerlinHash[h11 + i0Z]; int h111 = NoiseUtils.PerlinHash[h11 + i1Z]; var g000 = NoiseUtils.Gradients3D[h000 & NoiseUtils.GradientsMask3D]; var g001 = NoiseUtils.Gradients3D[h001 & NoiseUtils.GradientsMask3D]; var g010 = NoiseUtils.Gradients3D[h010 & NoiseUtils.GradientsMask3D]; var g011 = NoiseUtils.Gradients3D[h011 & NoiseUtils.GradientsMask3D]; var g100 = NoiseUtils.Gradients3D[h100 & NoiseUtils.GradientsMask3D]; var g101 = NoiseUtils.Gradients3D[h101 & NoiseUtils.GradientsMask3D]; var g110 = NoiseUtils.Gradients3D[h110 & NoiseUtils.GradientsMask3D]; var g111 = NoiseUtils.Gradients3D[h111 & NoiseUtils.GradientsMask3D]; float v000 = Vector3.Dot(g000, new Vector3(t0.x, t0.y, t0.z)); float v001 = Vector3.Dot(g001, new Vector3(t0.x, t0.y, t1.z)); float v010 = Vector3.Dot(g010, new Vector3(t0.x, t1.y, t0.z)); float v011 = Vector3.Dot(g011, new Vector3(t0.x, t1.y, t1.z)); float v100 = Vector3.Dot(g100, new Vector3(t1.x, t0.y, t0.z)); float v101 = Vector3.Dot(g101, new Vector3(t1.x, t0.y, t1.z)); float v110 = Vector3.Dot(g110, new Vector3(t1.x, t1.y, t0.z)); float v111 = Vector3.Dot(g111, new Vector3(t1.x, t1.y, t1.z)); //t0.x = NoiseUtils.Splerp(ref noiseStruct.splerp, 0f, 1f, t0.x); //t0.y = NoiseUtils.Splerp(ref noiseStruct.splerp, 0f, 1f, t0.y); //t0.z = NoiseUtils.Splerp(ref noiseStruct.splerp, 0f, 1f, t0.z); //Compute the dropoff t0.x = NoiseUtils.SmootherStep(t0.x); t0.y = NoiseUtils.SmootherStep(t0.y); t0.z = NoiseUtils.SmootherStep(t0.z); return(Mathf.Lerp( Mathf.Lerp(Mathf.Lerp(v000, v100, t0.x), Mathf.Lerp(v010, v110, t0.x), t0.y), Mathf.Lerp(Mathf.Lerp(v001, v101, t0.x), Mathf.Lerp(v011, v111, t0.x), t0.y), t0.z)); }
protected override float Value2D(Vector3 point, NoiseStruct noiseStruct) { point *= noiseStruct.frequency; float n0, n1, n2; // Noise contributions form the three corners // Skew simplex triangle grid to rightangle isosceles triangles, two of which form a square float skew = (point.x + point.y) * Skew2; // Find integer lattice points in skewed space int i0 = Mathf.FloorToInt(point.x + skew); int j0 = Mathf.FloorToInt(point.y + skew); float unskew = (i0 + j0) * Unskew2; // Unskew integer lattice points in skewed space back into simplex grid // This is now the origin point of our simplex cell, called first corner //var corner0 = new Vector2(i0 - unskew, j0 - unskew); // Relative coordinates from first corner to input point within simplex cell var t0 = new Vector2(point.x - i0 + unskew, point.y - j0 + unskew); // For the 2D case, the simplex shape is a triangle. // Determine which simplex we are in. int i1, j1; // Offsets for second corner of simplex cell in skewed space int i2 = 1, j2 = 1; // Offsets for third corner of simplex cell in skewed space if (t0.x > t0.y) //lower triangle { i1 = 1; j1 = 0; } else // upper triangle { i1 = 0; j1 = 1; } var t1 = new Vector2(t0.x - i1 + Unskew2, t0.y - j1 + Unskew2); var t2 = new Vector2(t0.x - i2 + 2 * Unskew2, t0.y - j2 + 2 * Unskew2); // Work out the hashed gradient indices gi of the four simplex corners int ii = i0 & NoiseUtils.HashMask; int jj = j0 & NoiseUtils.HashMask; int gi0 = NoiseUtils.PerlinHash[NoiseUtils.PerlinHash[jj ] + ii] & NoiseUtils.GradientsMask3D; // Gradient index for first corner int gi1 = NoiseUtils.PerlinHash[NoiseUtils.PerlinHash[jj + j1] + ii + i1] & NoiseUtils.GradientsMask3D; // Gradient index for second corner int gi2 = NoiseUtils.PerlinHash[NoiseUtils.PerlinHash[jj + j2] + ii + i2] & NoiseUtils.GradientsMask3D; // Gradient index for third corner // Calculate the contribution c from the four corners float c0 = 0.5f - (t0.x * t0.x + t0.y * t0.y); if (c0 < 0) n0 = 0.0f; else n0 = Mathf.Pow(c0, 4) * dot(NoiseUtils.Gradients3D[gi0], t0); float c1 = 0.5f - t1.x * t1.x - t1.y * t1.y; if (c1 < 0) n1 = 0.0f; else n1 = Mathf.Pow(c1, 4) * dot(NoiseUtils.Gradients3D[gi1], t1); float c2 = 0.5f - t2.x * t2.x - t2.y * t2.y; if (c2 < 0) n2 = 0.0f; else n2 = Mathf.Pow(c2, 4) * dot(NoiseUtils.Gradients3D[gi2], t2); // Add contributions from each corner to get the final noise value. // The result is scaled to return values in the interval [-1,1]. return 70f * (n0 + n1 + n2); }