public static int ysize = 1025, xsize = ysize * 2 - 1; public static float[,] heighmap = new float[xsize, ysize]; public static float roughness = 2f; // , , public static void Square(int lx, int ly, int rx, int ry) { int l = (rx - lx) / 2; float a = heighmap[lx, ly]; // B--------C float b = heighmap[lx, ry]; // | | float c = heighmap[rx, ry]; // | ce | float d = heighmap[rx, ly]; // | | int cex = lx + l; // A--------D int cey = ly + l; heighmap[cex, cey] = (a + b + c + d) / 4 + Random.Range(-l * 2 * roughness / ysize, l * 2 * roughness / ysize); }
bool lrflag = false; public static void Diamond(int tgx, int tgy, int l) { float a, b, c, d; if (tgy - l >= 0) a = heighmap[tgx, tgy - l]; // C-------- else // | | a = heighmap[tgx, ysize - l]; // B---t g----D | // | | // A-------- if (tgx - l >= 0) b = heighmap[tgx - l, tgy]; else if (lrflag) b = heighmap[xsize - l, tgy]; else b = heighmap[ysize - l, tgy]; if (tgy + l < ysize) c = heighmap[tgx, tgy + l]; else c = heighmap[tgx, l]; if (lrflag) if (tgx + l < xsize) d = heighmap[tgx + l, tgy]; else<source lang="cs"> d = heighmap[l, tgy]; else if (tgx + l < ysize) d = heighmap[tgx + l, tgy]; else d = heighmap[l, tgy]; heighmap[tgx, tgy] = (a + b + c + d) / 4 + Random.Range(-l * 2 * roughness / ysize, l * 2 * roughness / ysize); }
public static void DiamondSquare(int lx, int ly, int rx, int ry) { int l = (rx - lx) / 2; Square(lx, ly, rx, ry); Diamond(lx, ly + l, l); Diamond(rx, ry - l, l); Diamond(rx - l, ry, l); Diamond(lx + l, ly, l); }
public static void Generate() { heighmap[0, 0] = Random.Range(0.3f, 0.6f); heighmap[0, ysize - 1] = Random.Range(0.3f, 0.6f); heighmap[xsize - 1, ysize - 1] = Random.Range(0.3f, 0.6f); heighmap[xsize - 1, 0] = Random.Range(0.3f, 0.6f); heighmap[ysize - 1, ysize - 1] = Random.Range(0.3f, 0.6f); heighmap[ysize - 1, 0] = Random.Range(0.3f, 0.6f); for (int l = (ysize - 1) / 2; l > 0; l /= 2) for (int x = 0; x < xsize - 1; x += l) { if (x >= ysize - l) lrflag = true; else lrflag = false; for (int y = 0; y < ysize - 1; y += l) DiamondSquare(x, y, x + l, y + l); } }
public static class TemperatureCurves_class { static int xsize = Heighmap_class.xsize; public static int snowEdge = Heighmap_class.ysize / 10; public static int greenEdge = Heighmap_class.ysize / 3; public static int[] northGreen = new int[xsize]; public static int[] southGreen = new int[xsize]; public static int[] northSnow = new int[xsize]; public static int[] southSnow = new int[xsize]; static float snowRoughness = 0.03f; static float greenRoughness = 0.15f; static void MidPointDisplacement1D(ref int[] curve, int l, int r, float roughness) { if (r - l > 1) { curve[(l + r) / 2] = (curve[l] + curve[r]) / 2 + (int)Random.Range(-(r - l) * roughness, (r - l) * roughness); MidPointDisplacement1D(ref curve, l, (l + r) / 2, roughness); MidPointDisplacement1D(ref curve, (l + r) / 2, r, roughness); } } public static void Generate() { northSnow[0] = northSnow[xsize - 1] = Heighmap_class.ysize - snowEdge; southSnow[0] = southSnow[xsize - 1] = snowEdge; northGreen[0] = northGreen[xsize - 1] = Heighmap_class.ysize - greenEdge; southGreen[0] = southGreen[xsize - 1] = greenEdge MidPointDisplacement1D(ref northGreen, 0, xsize - 1, greenRoughness); MidPointDisplacement1D(ref southGreen, 0, xsize - 1, greenRoughness); MidPointDisplacement1D(ref northSnow, 0, xsize - 1, snowRoughness); MidPointDisplacement1D(ref southSnow, 0, xsize - 1, snowRoughness); } }
public Texture2D tex; // , public static Color[] colors = new Color[Heighmap_class.xsize * Heighmap_class.ysize]; float waterLevel = 0.2f;
void SqrHeighmap() { for (int x = 0; x < Heighmap_class.xsize; x++) for (int y = 0; y < Heighmap_class.ysize; y++) Heighmap_class.heighmap[x, y] *= Heighmap_class.heighmap[x, y]; }
void SmoothImg() { for (int i = 0; i < Heighmap_class.xsize * Heighmap_class.ysize - 2; i++) { Color clr1 = colors[i]; Color clr2 = colors[i + 1]; colors[i] = (2 * clr1 + clr2) / 3; colors[i + 1] = (clr1 + 2 * clr2) / 3; } }
void SetSnow(int counter, float heigh) { if (heigh < waterLevel + Random.Range(-0.04f, 0.04f)) colors[counter] = new Color(Random.Range(0.8f, 0.85f), Random.Range(0.8f, 0.85f), Random.Range(0.85f, 0.9f)); else { colors[counter].r = 0.005f / heigh + Random.Range(0.8f, 0.85f); colors[counter].g = 0.005f / heigh + Random.Range(0.8f, 0.85f); colors[counter].b = 0.01f / heigh + Random.Range(0.8f, 0.85f); } }
void SetOcean(int counter, float heigh) { colors[counter].r = heigh / 5; colors[counter].g = heigh / 5; colors[counter].b = 0.2f + heigh / 2 + Random.Range(-0.02f, 0.02f); }
void SetGreen(int counter, float heigh) { colors[counter].g = 0.1f / heigh + 0.05f + Random.Range(-0.04f, 0.04f); if (heigh < waterLevel + 0.1f) colors[counter].g -= (waterLevel + 0.1f - heigh); if (colors[counter].g > 0.5f) colors[counter].g = 0.5f / heigh + 0.05f + Random.Range(-0.04f, 0.04f); colors[counter].r = 0; colors[counter].b = 0; }
void SetDesert(int counter, float heigh) { colors[counter].r = Random.Range(0.6f, 0.75f) + heigh / 2 - 0.35f; colors[counter].g = Random.Range(0.6f, 0.75f) + heigh / 2 - 0.35f; colors[counter].b = Random.Range(0.2f, 0.3f) + heigh / 2 - 0.35f; }
void SetMountains(int counter, float heigh) { float rnd = Random.Range(-0.03f, 0.03f); if (heigh > 1.1f) heigh = 1.1f + Random.Range(-0.05f, 0.05f); colors[counter].r = heigh * heigh / 2 + rnd - 0.1f; colors[counter].g = heigh * heigh / 2 + rnd - 0.1f; colors[counter].b = heigh * heigh / 2 + rnd - 0.05f; }
bool ChechInRange(int value, int min, int max, int rand) { return ((value > min + rand) && (value < max + rand)); }
void Awake() { Heighmap_class.Generate(); TemperatureCurves_class.Generate(); tex.Resize(Heighmap_class.xsize, Heighmap_class.ysize); tex.Apply(); SqrHeighmap(); int counter = 0; for (int y = 0; y < Heighmap_class.ysize; y++) for (int x = 0; x < Heighmap_class.xsize; x++) { float heigh = Heighmap_class.heighmap[x, y]; if (heigh < waterLevel) SetOcean(counter, heigh); else { if (ChechInRange(y, TemperatureCurves_class.southSnow[x], TemperatureCurves_class.northSnow[x], Random.Range(-10, 10))) if (ChechInRange(y, TemperatureCurves_class.southGreen[x], TemperatureCurves_class.northGreen[x], Random.Range(-10, 10))) { SetDesert(counter, heigh); if (heigh < waterLevel + 0.1f + Random.Range(-0.05f, 0.05f)) SetGreen(counter, heigh); } else SetGreen(counter, heigh); if (heigh > 0.82f + Random.Range(-0.05f, 0.05f)) SetMountains(counter, heigh); } if ((y < TemperatureCurves_class.southSnow[x] + Random.Range(-10, 10)) || (y > TemperatureCurves_class.northSnow[x] + Random.Range(-10, 10))) SetSnow(counter, heigh); counter++; } SmoothImg(); tex.SetPixels(colors); tex.Apply(); }
using UnityEngine; using System.Collections; public class Heighmap_class { public static int ysize = 1025, xsize = ysize * 2 - 1; public static float[,] heighmap = new float[xsize, ysize]; public static float roughness = 2f; // , , public static void Square(int lx, int ly, int rx, int ry) { int l = (rx - lx) / 2; float a = heighmap[lx, ly]; // B--------C float b = heighmap[lx, ry]; // | | float c = heighmap[rx, ry]; // | ce | float d = heighmap[rx, ly]; // | | int cex = lx + l; // A--------D int cey = ly + l; heighmap[cex, cey] = (a + b + c + d) / 4 + Random.Range(-l * 2 * roughness / ysize, l * 2 * roughness / ysize); } static bool lrflag = false; public static void Diamond(int tgx, int tgy, int l) { float a, b, c, d; if (tgy - l >= 0) a = heighmap[tgx, tgy - l]; // C-------- else // | | a = heighmap[tgx, ysize - l]; // B---t g----D | // | | // A-------- if (tgx - l >= 0) b = heighmap[tgx - l, tgy]; else if (lrflag) b = heighmap[xsize - l, tgy]; else b = heighmap[ysize - l, tgy]; if (tgy + l < ysize) c = heighmap[tgx, tgy + l]; else c = heighmap[tgx, l]; if (lrflag) if (tgx + l < xsize) d = heighmap[tgx + l, tgy]; else d = heighmap[l, tgy]; else if (tgx + l < ysize) d = heighmap[tgx + l, tgy]; else d = heighmap[l, tgy]; heighmap[tgx, tgy] = (a + b + c + d) / 4 + Random.Range(-l * 2 * roughness / ysize, l * 2 * roughness / ysize); } public static void DiamondSquare(int lx, int ly, int rx, int ry) { int l = (rx - lx) / 2; Square(lx, ly, rx, ry); Diamond(lx, ly + l, l); Diamond(rx, ry - l, l); Diamond(rx - l, ry, l); Diamond(lx + l, ly, l); } public static void MidPointDisplacement(int lx, int ly, int rx, int ry) { int l = (rx - lx) / 2; if (l > 0) { float a = heighmap[lx, ly]; // B--------C float b = heighmap[lx, ry]; // | | float c = heighmap[rx, ry]; // | ce | float d = heighmap[rx, ly]; // | | // A--------D int cex = lx + l; int cey = ly + l; heighmap[cex, cey] = (a + b + c + d) / 4 + Random.Range(-l * 2 * roughness / xsize, l * 2 * roughness / xsize); heighmap[lx, cey] = (a + b) / 2 + Random.Range(-l * 2 * roughness / xsize, l * 2 * roughness / xsize); heighmap[rx, cey] = (c + d) / 2 + Random.Range(-l * 2 * roughness / xsize, l * 2 * roughness / xsize); heighmap[cex, ly] = (a + d) / 2 + Random.Range(-l * 2 * roughness / xsize, l * 2 * roughness / xsize); heighmap[cex, ry] = (b + c) / 2 + Random.Range(-l * 2 * roughness / xsize, l * 2 * roughness / xsize); MidPointDisplacement(lx, ly, cex, cey); MidPointDisplacement(lx, ly + l, lx + l, ry); MidPointDisplacement(cex, cey, rx, ry); MidPointDisplacement(lx + l, ly, rx, cey); } } public static void Generate() { heighmap[0, 0] = Random.Range(0.3f, 0.6f); heighmap[0, ysize - 1] = Random.Range(0.3f, 0.6f); heighmap[xsize - 1, ysize - 1] = Random.Range(0.3f, 0.6f); heighmap[xsize - 1, 0] = Random.Range(0.3f, 0.6f); heighmap[ysize - 1, ysize - 1] = Random.Range(0.3f, 0.6f); heighmap[ysize - 1, 0] = Random.Range(0.3f, 0.6f); for (int l = (ysize - 1) / 2; l > 0; l /= 2) for (int x = 0; x < xsize - 1; x += l) { if (x >= ysize - l) lrflag = true; else lrflag = false; for (int y = 0; y < ysize - 1; y += l) DiamondSquare(x, y, x + l, y + l); } } }
using UnityEngine; using System.Collections; public static class TemperatureCurves_class { static int xsize = Heighmap_class.xsize; public static int snowEdge = Heighmap_class.ysize / 10; public static int greenEdge = Heighmap_class.ysize / 3; public static int[] northGreen = new int[xsize]; public static int[] southGreen = new int[xsize]; public static int[] northSnow = new int[xsize]; public static int[] southSnow = new int[xsize]; static float snowRoughness = 0.03f; static float greenRoughness = 0.15f; static void MidPointDisplacement1D(ref int[] curve, int l, int r, float roughness) { if (r - l > 1) { curve[(l + r) / 2] = (curve[l] + curve[r]) / 2 + (int)Random.Range(-(r - l) * roughness, (r - l) * roughness); MidPointDisplacement1D(ref curve, l, (l + r) / 2, roughness); MidPointDisplacement1D(ref curve, (l + r) / 2, r, roughness); } } public static void Generate() { northSnow[0] = northSnow[xsize - 1] = Heighmap_class.ysize - snowEdge; southSnow[0] = southSnow[xsize - 1] = snowEdge; northGreen[0] = northGreen[xsize - 1] = Heighmap_class.ysize - greenEdge; southGreen[0] = southGreen[xsize - 1] = greenEdge + Random.Range(-100, 100); MidPointDisplacement1D(ref northGreen, 0, xsize - 1, greenRoughness); MidPointDisplacement1D(ref southGreen, 0, xsize - 1, greenRoughness); MidPointDisplacement1D(ref northSnow, 0, xsize - 1, snowRoughness); MidPointDisplacement1D(ref southSnow, 0, xsize - 1, snowRoughness); } }
using UnityEngine; using System.Collections; public class Renderer_script : MonoBehaviour { public Texture2D tex; public static Color[] colors = new Color[Heighmap_class.xsize * Heighmap_class.ysize]; float waterLevel = 0.2f; void SqrHeighmap() { for (int x = 0; x < Heighmap_class.xsize; x++) for (int y = 0; y < Heighmap_class.ysize; y++) Heighmap_class.heighmap[x, y] *= Heighmap_class.heighmap[x, y]; } void SetSnow(int counter, float heigh) { if (heigh < waterLevel + Random.Range(-0.04f, 0.04f)) colors[counter] = new Color(Random.Range(0.8f, 0.85f), Random.Range(0.8f, 0.85f), Random.Range(0.85f, 0.9f)); else { colors[counter].r = 0.005f / heigh + Random.Range(0.8f, 0.85f); colors[counter].g = 0.005f / heigh + Random.Range(0.8f, 0.85f); colors[counter].b = 0.01f / heigh + Random.Range(0.8f, 0.85f); } } void SetOcean(int counter, float heigh) { colors[counter].r = heigh / 5; colors[counter].g = heigh / 5; colors[counter].b = 0.2f + heigh / 2 + Random.Range(-0.02f, 0.02f); } void SetGreen(int counter, float heigh) { colors[counter].g = 0.1f / heigh + 0.05f + Random.Range(-0.04f, 0.04f); if (heigh < waterLevel + 0.1f) colors[counter].g -= (waterLevel + 0.1f - heigh); if (colors[counter].g > 0.5f) colors[counter].g = 0.5f / heigh + 0.05f + Random.Range(-0.04f, 0.04f); colors[counter].r = 0; colors[counter].b = 0; } void SetDesert(int counter, float heigh) { colors[counter].r = Random.Range(0.6f, 0.75f) + heigh / 2 - 0.35f; colors[counter].g = Random.Range(0.6f, 0.75f) + heigh / 2 - 0.35f; colors[counter].b = Random.Range(0.2f, 0.3f) + heigh / 2 - 0.35f; } void SetMountains(int counter, float heigh) { float rnd = Random.Range(-0.03f, 0.03f); if (heigh > 1.1f) heigh = 1.1f + Random.Range(-0.05f, 0.05f); colors[counter].r = heigh * heigh / 2 + rnd - 0.1f; colors[counter].g = heigh * heigh / 2 + rnd - 0.1f; colors[counter].b = heigh * heigh / 2 + rnd - 0.05f; } void SmoothImg() { for (int i = 0; i < Heighmap_class.xsize * Heighmap_class.ysize - 2; i++) { Color clr1 = colors[i]; Color clr2 = colors[i + 1]; colors[i] = (2 * clr1 + clr2) / 3; colors[i + 1] = (clr1 + 2 * clr2) / 3; } } bool ChechInRange(int value, int min, int max, int rand) { return ((value > min + rand) && (value < max + rand)); } void Awake() { Heighmap_class.Generate(); TemperatureCurves_class.Generate(); tex.Resize(Heighmap_class.xsize, Heighmap_class.ysize); tex.Apply(); SqrHeighmap(); int counter = 0; for (int y = 0; y < Heighmap_class.ysize; y++) for (int x = 0; x < Heighmap_class.xsize; x++) { float heigh = Heighmap_class.heighmap[x, y]; if (heigh < waterLevel) SetOcean(counter, heigh); else { if (ChechInRange(y, TemperatureCurves_class.southSnow[x], TemperatureCurves_class.northSnow[x], Random.Range(-10, 10))) if (ChechInRange(y, TemperatureCurves_class.southGreen[x], TemperatureCurves_class.northGreen[x], Random.Range(-10, 10))) { SetDesert(counter, heigh); if (heigh < waterLevel + 0.1f + Random.Range(-0.05f, 0.05f)) SetGreen(counter, heigh); } else SetGreen(counter, heigh); if (heigh > 0.82f + Random.Range(-0.05f, 0.05f)) SetMountains(counter, heigh); } if ((y < TemperatureCurves_class.southSnow[x] + Random.Range(-10, 10)) || (y > TemperatureCurves_class.northSnow[x] + Random.Range(-10, 10))) SetSnow(counter, heigh); counter++; } SmoothImg(); tex.SetPixels(colors); tex.Apply(); } }
Source: https://habr.com/ru/post/249027/
All Articles