public void LinearInterpTest(double alpha) { const double N0 = 0.0; const double N1 = 1.0; Assert.Equal(alpha, NoiseMath.Linear(N0, N1, alpha)); }
/// <summary> /// Returns the output value from the noise module given the /// (latitude, longitude) coordinates of the specified input value /// located on the surface of the sphere. /// </summary> /// <param name="lat">The latitude of the input value, in degrees.</param> /// <param name="lon">The longitude of the input value, in degrees.</param> /// <returns>The output value from the noise module.</returns> /// <remarks> /// Use a negative latitude if the input value is located on the /// southern hemisphere. /// /// Use a negative longitude if the input value is located on the /// western hemisphere. /// </remarks> public double GetValue(double lat, double lon) { double x, y, z; NoiseMath.LatLonToXYZ(lat, lon, out x, out y, out z); return(Source.GetValue(x, y, z)); }
public void LatLonTest(double lat, double lon, double expX, double expY, double expZ) { NoiseMath.LatLonToXYZ(lat, lon, out double x, out double y, out double z); Assert.Equal(expX, x, 6); Assert.Equal(expY, y, 6); Assert.Equal(expZ, z, 6); }
/// <summary> /// See the documentation on the base class. /// <seealso cref="Module"/> /// </summary> /// <param name="x">X coordinate</param> /// <param name="y">Y coordinate</param> /// <param name="z">Z coordinate</param> /// <returns>Returns the computed value</returns> public override double GetValue(double x, double y, double z) { double v0 = this.SourceModules[0].GetValue(x, y, z); double v1 = this.SourceModules[1].GetValue(x, y, z); double alpha = (this.SourceModules[2].GetValue(x, y, z) + 1) / 2; return(NoiseMath.Linear(v0, v1, alpha)); }
public void Math_Interp_SCurve5_Somewhere_Test_2() { double v = 0.9; double expected = 0.99144; Assert.AreEqual(expected, Math.Round(NoiseMath.SCurve5(v), 6)); }
public void Math_Interp_SCurve5_Upper_Test() { double v = 1; double expected = 1; Assert.AreEqual(expected, NoiseMath.SCurve5(v)); }
public void Math_Interp_SCurve5_Middle_Test() { double v = 0.5; double expected = 0.5; Assert.AreEqual(expected, NoiseMath.SCurve5(v)); }
/// <summary> /// See the documentation on the base class. /// <seealso cref="Module"/> /// </summary> /// <param name="x">X coordinate</param> /// <param name="y">Y coordinate</param> /// <param name="z">Z coordinate</param> /// <returns>Returns the computed value</returns> public override double GetValue(double x, double y, double z) { var v0 = SourceModules[0].GetValue(x, y, z); var v1 = SourceModules[1].GetValue(x, y, z); var alpha = (SourceModules[2].GetValue(x, y, z) + 1) / 2; return(NoiseMath.Linear(v0, v1, alpha)); }
/// <summary> /// See the documentation on the base class. /// <seealso cref="Module"/> /// </summary> /// <param name="x">X coordinate</param> /// <param name="y">Y coordinate</param> /// <param name="z">Z coordinate</param> /// <returns>Returns the computed value</returns> public override double GetValue(double x, double y, double z) { var ix = NoiseMath.FastFloor(x); var iy = NoiseMath.FastFloor(y); var iz = NoiseMath.FastFloor(z); return(((ix & 1) ^ (iy & 1) ^ (iz & 1)) != 0 ? -1.0 : 1.0); }
public void Math_Interp_SCurve3_Lower_Test() { double v = 0; double expected = 0; Assert.AreEqual(expected, NoiseMath.SCurve3(v)); }
public void Math_Interp_SCurve5_Somewhere_Test_1() { double v = 0.333; double expected = 0.209383; Assert.AreEqual(expected, Math.Round(NoiseMath.SCurve5(v), 6)); }
public void Math_Interp_SCurve3_Somewhere_Test_2() { double v = 0.9; double expected = 0.972; Assert.AreEqual(expected, NoiseMath.SCurve3(v)); }
public override double GetValue(double x, double y, double z) { if (SourceModule1 == null || SourceModule2 == null || WeightModule == null) { throw new NullReferenceException("No source module can be null"); } return(NoiseMath.LinearInterpolate(SourceModule1.GetValue(x, y, z), SourceModule2.GetValue(x, y, z), (WeightModule.GetValue(x, y, z) + 1.0) / 2.0)); }
public override double GetValue(double x, double y, double z) { if (SourceModule == null) { throw new InvalidOperationException("Source Module cannot be null"); } // Get the output value from the source module. double sourceModuleValue = SourceModule.GetValue(x, y, z); // Find the first element in the control point array that has a value // larger than the output value from the source module. int indexPos; for (indexPos = 0; indexPos < ControlPoints.Length; indexPos++) { if (sourceModuleValue < ControlPoints[indexPos]) { break; } } // Find the two nearest control points so that we can map their values // onto a quadratic curve. int index0 = NoiseMath.ClampValue(indexPos - 1, 0, ControlPoints.Length - 1); int index1 = NoiseMath.ClampValue(indexPos, 0, ControlPoints.Length - 1); // If some control points are missing (which occurs if the output value from // the source module is greater than the largest value or less than the // smallest value of the control point array), get the value of the nearest // control point and exit now. if (index0 == index1) { return(ControlPoints[index1]); } // Compute the alpha value used for linear interpolation. double value0 = ControlPoints[index0]; double value1 = ControlPoints[index1]; double alpha = (sourceModuleValue - value0) / (value1 - value0); if (InvertTerraces) { alpha = 1.0 - alpha; double temp = value0; value0 = value1; value1 = temp; } // Squaring the alpha produces the terrace effect. alpha *= alpha; // Now perform the linear interpolation given the alpha value. return(NoiseMath.LinearInterpolate(value0, value1, alpha)); }
public void Math_Interp_Linear_Right_Test() { var value1 = 0D; var value2 = 5D; var alpha = 1D; var expected = 5D; var actual = NoiseMath.Linear(value1, value2, alpha); Assert.AreEqual(expected, actual); }
public override double GetValue(double x, double y, double z) { x *= Frequency; z *= Frequency; double distFromCenter = System.Math.Sqrt(x * x + z * z); int distFromCenter0 = (distFromCenter > 0.0 ? (int)distFromCenter : (int)distFromCenter - 1); double distFromSmallerSphere = distFromCenter - distFromCenter0; double distFromLargerSphere = 1.0 - distFromSmallerSphere; double nearestDist = NoiseMath.GetSmaller(distFromSmallerSphere, distFromLargerSphere); return(1.0 - (nearestDist * 4.0)); }
internal static double GradientCoherentNoise(double x, double y, double z, int seed, NoiseQuality noiseQuality) { int x0 = (x > 0.0 ? (int)x : (int)x - 1); int x1 = x0 + 1; int y0 = (y > 0.0 ? (int)y : (int)y - 1); int y1 = y0 + 1; int z0 = (z > 0.0 ? (int)z : (int)z - 1); int z1 = z0 + 1; double xs = 0, ys = 0, zs = 0; switch (noiseQuality) { case NoiseQuality.Low: xs = (x - x0); ys = (y - y0); zs = (z - z0); break; case NoiseQuality.Standard: xs = NoiseMath.SCurve3(x - x0); ys = NoiseMath.SCurve3(y - y0); zs = NoiseMath.SCurve3(z - z0); break; case NoiseQuality.High: xs = NoiseMath.SCurve5(x - x0); ys = NoiseMath.SCurve5(y - y0); zs = NoiseMath.SCurve5(z - z0); break; } double n0 = GradientNoise(x, y, z, x0, y0, z0, seed); double n1 = GradientNoise(x, y, z, x1, y0, z0, seed); double ix0 = NoiseMath.LinearInterpolate(n0, n1, xs); n0 = GradientNoise(x, y, z, x0, y1, z0, seed); n1 = GradientNoise(x, y, z, x1, y1, z0, seed); double ix1 = NoiseMath.LinearInterpolate(n0, n1, xs); double iy0 = NoiseMath.LinearInterpolate(ix0, ix1, ys); n0 = GradientNoise(x, y, z, x0, y0, z1, seed); n1 = GradientNoise(x, y, z, x1, y0, z1, seed); ix0 = NoiseMath.LinearInterpolate(n0, n1, xs); n0 = GradientNoise(x, y, z, x0, y1, z1, seed); n1 = GradientNoise(x, y, z, x1, y1, z1, seed); ix1 = NoiseMath.LinearInterpolate(n0, n1, xs); double iy1 = NoiseMath.LinearInterpolate(ix0, ix1, ys); return(NoiseMath.LinearInterpolate(iy0, iy1, zs)); }
public override double GetValue(double x, double y, double z) { x *= Frequency; y *= Frequency; z *= Frequency; double distFromCenter = System.Math.Sqrt(x * x + y * y + z * z); int xInt = (x > 0.0 ? (int)x : (int)x - 1); double distFromSmallerSphere = distFromCenter - xInt; double distFromLargerSphere = 1.0 - distFromSmallerSphere; double nearestDist = NoiseMath.GetSmaller(distFromSmallerSphere, distFromLargerSphere); return(1.0 - (nearestDist * 4.0)); // Puts it in the -1.0 to +1.0 range. }
public void Math_LatLonToXYZ_Test_4() { double x, y, z; NoiseMath.LatLonToXYZ(45, 45, out x, out y, out z); double expectedX = 0.5, expectedY = 0.707107, expectedZ = 0.5; Assert.AreEqual(expectedX, Math.Round(x, 6)); Assert.AreEqual(expectedY, Math.Round(y, 6)); Assert.AreEqual(expectedZ, Math.Round(z, 6)); }
public void Math_LatLonToXYZ_Test_2() { double x, y, z; NoiseMath.LatLonToXYZ(-51, 63, out x, out y, out z); double expectedX = 0.285705, expectedY = -0.777146, expectedZ = 0.560729; Assert.AreEqual(expectedX, Math.Round(x, 6)); Assert.AreEqual(expectedY, Math.Round(y, 6)); Assert.AreEqual(expectedZ, Math.Round(z, 6)); }
public void Math_LatLonToXYZ_Test_1() { double x, y, z; NoiseMath.LatLonToXYZ(0, 0, out x, out y, out z); double expectedX = 1, expectedY = 0, expectedZ = 0; Assert.AreEqual(expectedX, x); Assert.AreEqual(expectedY, y); Assert.AreEqual(expectedZ, z); }
void DrawMath(NoiseMath module) { Rect r = Box(module.editorPos, 2 + module.usedModules + (module.canAcceptMore ? 1 : 0), module); EditorGUI.BeginDisabledGroup(add == module); GUILayout.BeginArea(new Rect(r.x + 16, r.y + 5, r.width - 32, r.height - 10)); EditorGUILayout.LabelField(module.operation.ToString(), EditorStyles.boldLabel); module.operation = (NoiseOperation)EditorGUILayout.EnumPopup("Type", module.operation); for (int i = 0; i < module.usedModules; i++) { EditorGUILayout.LabelField("Module " + i, EditorStyles.boldLabel); } if (module.canAcceptMore) { EditorGUILayout.LabelField("Add Module", EditorStyles.boldLabel); } GUILayout.EndArea(); EditorGUI.EndDisabledGroup(); // connection buttons ConnectionOutputButton(module, new Vector3(r.xMax, r.center.y)); float h = EditorGUIUtility.singleLineHeight + 2f; Vector2 pos = new Vector2(r.x, r.y + 5 + EditorGUIUtility.singleLineHeight * .5f + 2 * h); for (int i = 0; i < module.usedModules; i++) { if (i < module.modules.Count && module.modules[i] != -1) { DrawLine(planet.noiseModules[module.modules[i]].editorPos + cameraOffset + new Vector2(moduleWidth * .5f, 0f), pos); ConnectionInputButton( (int nm) => { module.modules[i] = nm; }, pos, () => { module.modules.RemoveAt(i); i--; }); } pos.y += h; } // new module button if (module.canAcceptMore) { ConnectionInputButton((int nm) => { module.modules.Add(nm); }, pos, null); } }
/// <summary> /// See the documentation on the base class. /// <seealso cref="Module"/> /// </summary> /// <param name="x">X coordinate</param> /// <param name="y">Y coordinate</param> /// <param name="z">Z coordinate</param> /// <returns>Returns the computed value</returns> public override double GetValue(double x, double y, double z) { // Get the output value from the source module. double sourceModuleValue = SourceModules[0].GetValue(x, y, z); // Find the first element in the control point array that has a value // larger than the output value from the source module. int indexPos; for (indexPos = 0; indexPos < ControlPoints.Count; indexPos++) { if (sourceModuleValue < ControlPoints[indexPos].x) { break; } } // Find the two nearest control points so that we can map their values // onto a quadratic curve. var index0 = NoiseMath.Clamp(indexPos - 1, 0, ControlPoints.Count - 1); var index1 = NoiseMath.Clamp(indexPos, 0, ControlPoints.Count - 1); // If some control points are missing (which occurs if the output value from // the source module is greater than the largest value or less than the // smallest value of the control point array), get the value of the nearest // control point and exit now. if (index0 == index1) { return(ControlPoints[index1].x); } // Compute the alpha value used for linear interpolation. var value0 = ControlPoints[index0].x; var value1 = ControlPoints[index1].x; var alpha = (sourceModuleValue - value0) / (value1 - value0); if (InvertTerraces) { alpha = 1.0 - alpha; NoiseMath.Swap(ref value0, ref value1); } // Squaring the alpha produces the terrace effect. alpha *= alpha; // Now perform the linear interpolation given the alpha value. return(NoiseMath.Linear(value0, value1, alpha)); }
/// <summary> /// See the documentation on the base class. /// <seealso cref="Module"/> /// </summary> /// <param name="x">X coordinate</param> /// <param name="y">Y coordinate</param> /// <param name="z">Z coordinate</param> /// <returns>Returns the computed value</returns> public override double GetValue(double x, double y, double z) { // Get the output value from the source module. double sourceValue = this.SourceModules[0].GetValue(x, y, z); // Find the first element in the control point array that has an input value // larger than the output value from the source module. int indexPos; for (indexPos = 0; indexPos < this.controlPoints.Count; indexPos++) { if (sourceValue < this.controlPoints[indexPos].InputValue) { break; } } // Find the four nearest control points so that we can perform cubic // interpolation. int index0 = NoiseMath.Clamp(indexPos - 2, 0, this.controlPoints.Count - 1); int index1 = NoiseMath.Clamp(indexPos - 1, 0, this.controlPoints.Count - 1); int index2 = NoiseMath.Clamp(indexPos, 0, this.controlPoints.Count - 1); int index3 = NoiseMath.Clamp(indexPos + 1, 0, this.controlPoints.Count - 1); // If some control points are missing (which occurs if the value from the // source module is greater than the largest input value or less than the // smallest input value of the control point array), get the corresponding // output value of the nearest control point and exit now. if (index1 == index2) { return(this.controlPoints[index1].OutputValue); } // Compute the alpha value used for cubic interpolation. double input0 = this.controlPoints[index1].InputValue; double input1 = this.controlPoints[index2].InputValue; double alpha = (sourceValue - input0) / (input1 - input0); // Now perform the cubic interpolation given the alpha value. return(NoiseMath.Cubic( this.controlPoints[index0].OutputValue, this.controlPoints[index1].OutputValue, this.controlPoints[index2].OutputValue, this.controlPoints[index3].OutputValue, alpha)); }
protected override void BuildImpl(CancellationToken cancellationToken) { Plane planeModel = new Plane(SourceModule); var xExtent = UpperXBound - LowerXBound; var zExtent = UpperZBound - LowerZBound; var xDelta = xExtent / destWidth; var zDelta = zExtent / destHeight; var po = new ParallelOptions() { CancellationToken = cancellationToken, }; Parallel.For(0, destHeight, po, z => { double zCur = LowerZBound + z * zDelta; int x; double xCur; for (x = 0, xCur = LowerXBound; x < destWidth; x++, xCur += xDelta) { float finalValue; if (!EnableSeamless) { finalValue = (float)planeModel.GetValue(xCur, zCur); } else { var swValue = planeModel.GetValue(xCur, zCur); var seValue = planeModel.GetValue(xCur + xExtent, zCur); var nwValue = planeModel.GetValue(xCur, zCur + zExtent); var neValue = planeModel.GetValue(xCur + xExtent, zCur + zExtent); var xBlend = 1.0 - ((xCur - LowerXBound) / xExtent); var zBlend = 1.0 - ((zCur - LowerZBound) / zExtent); var z0 = NoiseMath.Linear(swValue, seValue, xBlend); var z1 = NoiseMath.Linear(nwValue, neValue, xBlend); finalValue = (float)NoiseMath.Linear(z0, z1, zBlend); } DestNoiseMap[x, z] = finalValue; } }); }
/// <summary> /// Calculates the destination color. /// </summary> /// <param name="sourceColor">The source color generated from the color /// gradient.</param> /// <param name="backgroundColor">The color from the background image at the /// corresponding position.</param> /// <param name="lightValue">The intensity of the light at that position.</param> /// <returns>The destination color.</returns> Color CalcDestinationColor(Color sourceColor, Color backgroundColor, double lightValue) { var sourceRed = (double)sourceColor.Red / 255.0; var sourceGreen = (double)sourceColor.Green / 255.0; var sourceBlue = (double)sourceColor.Blue / 255.0; var sourceAlpha = (double)sourceColor.Alpha / 255.0; var backgroundRed = (double)backgroundColor.Red / 255.0; var backgroundGreen = (double)backgroundColor.Green / 255.0; var backgroundBlue = (double)backgroundColor.Blue / 255.0; // First, blend the source color to the background color using the alpha // of the source color. var red = NoiseMath.Linear(backgroundRed, sourceRed, sourceAlpha); var green = NoiseMath.Linear(backgroundGreen, sourceGreen, sourceAlpha); var blue = NoiseMath.Linear(backgroundBlue, sourceBlue, sourceAlpha); if (EnableLight) { // Now calculate the light color. var lightRed = lightValue * (double)LightColor.Red / 255.0; var lightGreen = lightValue * (double)LightColor.Green / 255.0; var lightBlue = lightValue * (double)LightColor.Blue / 255.0; // Apply the light color to the new color. red *= lightRed; green *= lightGreen; blue *= lightBlue; } // Clamp the color channels to the (0..1) range. red = NoiseMath.Clamp(red, 0, 1); green = NoiseMath.Clamp(green, 0, 1); blue = NoiseMath.Clamp(blue, 0, 1); // Rescale the color channels to the (0..255) range and return // the new color. Color newColor = new Color( (byte)((int)(red * 255) & 0xff), (byte)((int)(green * 255) & 0xff), (byte)((int)(blue * 255) & 0xff), Math.Max(sourceColor.Alpha, backgroundColor.Alpha)); return(newColor); }
public override double GetValue(double x, double y, double z) { if (SourceModule == null) throw new InvalidOperationException("Must have a source module"); if (controlPoints.Count >= 4) throw new Exception("must have 4 or less control points"); // Get the output value from the source module. double sourceModuleValue = SourceModule.GetValue(x, y, z); // Find the first element in the control point array that has an input value // larger than the output value from the source module. int indexPos; for (indexPos = 0; indexPos < controlPoints.Count; indexPos++) { if (sourceModuleValue < controlPoints[indexPos].InputValue) { break; } } // Find the four nearest control points so that we can perform cubic // interpolation. int index0 = NoiseMath.ClampValue(indexPos - 2, 0, controlPoints.Count - 1); int index1 = NoiseMath.ClampValue(indexPos - 1, 0, controlPoints.Count - 1); int index2 = NoiseMath.ClampValue(indexPos, 0, controlPoints.Count - 1); int index3 = NoiseMath.ClampValue(indexPos + 1, 0, controlPoints.Count - 1); // If some control points are missing (which occurs if the value from the // source module is greater than the largest input value or less than the // smallest input value of the control point array), get the corresponding // output value of the nearest control point and exit now. if (index1 == index2) { return controlPoints[indexPos].OutputValue; } // Compute the alpha value used for cubic interpolation. double input0 = controlPoints[indexPos].InputValue; double input1 = controlPoints[indexPos].InputValue; double alpha = (sourceModuleValue - input0) / (input1 - input0); // Now perform the cubic interpolation given the alpha value. return NoiseMath.CubicInterpolate(controlPoints[index0].OutputValue, controlPoints[index1].OutputValue, controlPoints[index2].OutputValue, controlPoints[index3].OutputValue, alpha); }
protected override void BuildImpl(CancellationToken cancellationToken) { Plane planeModel = new Plane(this.SourceModule); double xExtent = this.UpperXBound - this.LowerXBound; double zExtent = this.UpperZBound - this.LowerZBound; double xDelta = xExtent / this.destWidth; double zDelta = zExtent / this.destHeight; ParallelOptions po = new ParallelOptions() { CancellationToken = cancellationToken, }; Parallel.For(0, this.destHeight, po, z => { double zCur = this.LowerZBound + z * zDelta; int x; double xCur; for (x = 0, xCur = this.LowerXBound; x < this.destWidth; x++, xCur += xDelta) { float finalValue; if (!this.EnableSeamless) { finalValue = (float)planeModel.GetValue(xCur, zCur); } else { double swValue = planeModel.GetValue(xCur, zCur); double seValue = planeModel.GetValue(xCur + xExtent, zCur); double nwValue = planeModel.GetValue(xCur, zCur + zExtent); double neValue = planeModel.GetValue(xCur + xExtent, zCur + zExtent); double xBlend = 1.0 - ((xCur - this.LowerXBound) / xExtent); double zBlend = 1.0 - ((zCur - this.LowerZBound) / zExtent); double z0 = NoiseMath.Linear(swValue, seValue, xBlend); double z1 = NoiseMath.Linear(nwValue, neValue, xBlend); finalValue = (float)NoiseMath.Linear(z0, z1, zBlend); } this.DestNoiseMap[x, z] = finalValue; } }); }
/// <summary> /// Returns the color at the specified position in the color gradient. /// </summary> /// <param name="gradientPosition">The specified position.</param> /// <returns>The color at that position.</returns> public Color GetColor(double gradientPosition) { // Find the first element in the gradient point array that has a gradient // position larger than the gradient position passed to this method. int indexPos; for (indexPos = 0; indexPos < gradientPoints.Count; indexPos++) { if (gradientPosition < gradientPoints[indexPos].Position) { break; } } // Find the two nearest gradient points so that we can perform linear // interpolation on the color. var index0 = NoiseMath.Clamp(indexPos - 1, 0, gradientPoints.Count - 1); var index1 = NoiseMath.Clamp(indexPos, 0, gradientPoints.Count - 1); // If some gradient points are missing (which occurs if the gradient // position passed to this method is greater than the largest gradient // position or less than the smallest gradient position in the array), get // the corresponding gradient color of the nearest gradient point and exit // now. if (index0 == index1) { return(gradientPoints[index1].Color); } // Compute the alpha value used for linear interpolation. var input0 = gradientPoints[index0].Position; var input1 = gradientPoints[index1].Position; var alpha = (gradientPosition - input0) / (input1 - input0); // Now perform the linear interpolation given the alpha value. var color0 = gradientPoints[index0].Color; var color1 = gradientPoints[index1].Color; return(Color.LinearInterpColor(color0, color1, (float)alpha)); }
/// <summary> /// See the documentation on the base class. /// <seealso cref="Module"/> /// </summary> /// <param name="x">X coordinate</param> /// <param name="y">Y coordinate</param> /// <param name="z">Z coordinate</param> /// <returns>Returns the computed value</returns> public override double GetValue(double x, double y, double z) { var controlValue = SourceModules[2].GetValue(x, y, z); double alpha; if (EdgeFalloff > 0.0) { if (controlValue < (LowerBound - EdgeFalloff)) { // The output value from the control module is below the selector // threshold; return the output value from the first source module. return(SourceModules[0].GetValue(x, y, z)); } else if (controlValue < (LowerBound + EdgeFalloff)) { // The output value from the control module is near the lower end of the // selector threshold and within the smooth curve. Interpolate between // the output values from the first and second source modules. double lowerCurve = (LowerBound - EdgeFalloff); double upperCurve = (LowerBound + EdgeFalloff); alpha = NoiseMath.SCurve3((controlValue - lowerCurve) / (upperCurve - lowerCurve)); return(NoiseMath.Linear(SourceModules[0].GetValue(x, y, z), SourceModules[1].GetValue(x, y, z), alpha)); } else if (controlValue < (UpperBound - EdgeFalloff)) { // The output value from the control module is within the selector // threshold; return the output value from the second source module. return(SourceModules[1].GetValue(x, y, z)); } else if (controlValue < (UpperBound + EdgeFalloff)) { // The output value from the control module is near the upper end of the // selector threshold and within the smooth curve. Interpolate between // the output values from the first and second source modules. double lowerCurve = (UpperBound - EdgeFalloff); double upperCurve = (UpperBound + EdgeFalloff); alpha = NoiseMath.SCurve3((controlValue - lowerCurve) / (upperCurve - lowerCurve)); return(NoiseMath.Linear(SourceModules[1].GetValue(x, y, z), SourceModules[0].GetValue(x, y, z), alpha)); } else { // Output value from the control module is above the selector threshold; // return the output value from the first source module. return(SourceModules[0].GetValue(x, y, z)); } } else { if (controlValue < LowerBound || controlValue > UpperBound) { return(SourceModules[0].GetValue(x, y, z)); } else { return(SourceModules[1].GetValue(x, y, z)); } } }