Noise.cs 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. using UnityEngine;
  2. using System.Collections;
  3. public static class Noise {
  4. public enum NormalizeMode {Local, Global};
  5. public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, int seed, float scale, int octaves, float persistance, float lacunarity, Vector2 offset, NormalizeMode normalizeMode) {
  6. float[,] noiseMap = new float[mapWidth,mapHeight];
  7. System.Random prng = new System.Random (seed);
  8. Vector2[] octaveOffsets = new Vector2[octaves];
  9. float maxPossibleHeight = 0;
  10. float amplitude = 1;
  11. float frequency = 1;
  12. for (int i = 0; i < octaves; i++) {
  13. float offsetX = prng.Next (-100000, 100000) + offset.x;
  14. float offsetY = prng.Next (-100000, 100000) - offset.y;
  15. octaveOffsets [i] = new Vector2 (offsetX, offsetY);
  16. maxPossibleHeight += amplitude;
  17. amplitude *= persistance;
  18. }
  19. if (scale <= 0) {
  20. scale = 0.0001f;
  21. }
  22. float maxLocalNoiseHeight = float.MinValue;
  23. float minLocalNoiseHeight = float.MaxValue;
  24. float halfWidth = mapWidth / 2f;
  25. float halfHeight = mapHeight / 2f;
  26. for (int y = 0; y < mapHeight; y++) {
  27. for (int x = 0; x < mapWidth; x++) {
  28. amplitude = 1;
  29. frequency = 1;
  30. float noiseHeight = 0;
  31. for (int i = 0; i < octaves; i++) {
  32. float sampleX = (x-halfWidth + octaveOffsets[i].x) / scale * frequency;
  33. float sampleY = (y-halfHeight + octaveOffsets[i].y) / scale * frequency;
  34. float perlinValue = Mathf.PerlinNoise (sampleX, sampleY) * 2 - 1;
  35. noiseHeight += perlinValue * amplitude;
  36. amplitude *= persistance;
  37. frequency *= lacunarity;
  38. }
  39. if (noiseHeight > maxLocalNoiseHeight) {
  40. maxLocalNoiseHeight = noiseHeight;
  41. } else if (noiseHeight < minLocalNoiseHeight) {
  42. minLocalNoiseHeight = noiseHeight;
  43. }
  44. noiseMap [x, y] = noiseHeight;
  45. }
  46. }
  47. for (int y = 0; y < mapHeight; y++) {
  48. for (int x = 0; x < mapWidth; x++) {
  49. if (normalizeMode == NormalizeMode.Local) {
  50. noiseMap [x, y] = Mathf.InverseLerp (minLocalNoiseHeight, maxLocalNoiseHeight, noiseMap [x, y]);
  51. } else {
  52. float normalizedHeight = (noiseMap [x, y] + 1) / (maxPossibleHeight/0.9f);
  53. noiseMap [x, y] = Mathf.Clamp(normalizedHeight,0, int.MaxValue);
  54. }
  55. }
  56. }
  57. return noiseMap;
  58. }
  59. }