//not cave noise just normal noise now as it needed a noise with another seed public float SampleCaves(float x, float z, PerlinNoise perlin) { float w = perlin.FractalNoise2D(x, z, 1, CaveFrequency, caveAmplitude); //larger caves (A higher frequency will also create larger caves). It is unitless, 1 != 1m return(Mathf.Abs(perlin.FractalNoise2D(x + w, z + w, caveOct, CaveFrequency, caveAmplitude))); }
public void GeneratePerlinElevations() { PerlinNoise perlin = new PerlinNoise(Mathf.FloorToInt(Random.value * 10000000)); perlin.LoadPermTableIntoTexture(); Utils.instance.allCorners.ForEach(corner => { corner.elevation = baseElevation + perlin.FractalNoise2D( corner.wPos.x / Config.reg.tileSize, corner.wPos.z / Config.reg.tileSize, perlinOctaves, perlinFrq, perlinAmp); corner.touches[0].elevation = baseElevation + perlin.FractalNoise2D( corner.touches[0].wPos.x / Config.reg.tileSize, corner.touches[0].wPos.z / Config.reg.tileSize, perlinOctaves, perlinFrq, perlinAmp); if (!perlinSmooth) { corner.elevation = Mathf.Floor(corner.elevation); } corner.elevation = Mathf.Clamp(corner.elevation, Config.reg.SeaLevel, 1000); corner.touches[0].elevation = Mathf.Clamp(corner.touches[0].elevation, Config.reg.SeaLevel, 1000); corner.touches[0].Update(); corner.GetWater(); if (corner.GetWater()) { corner.elevation = Config.reg.SeaLevel; } // corner.touches[0].elevation = corner.touches[0].GetElevationFromCorners(); }); }
public float SampleGround(float x, float z, PerlinNoise perlin) { //This creates the noise used for the ground. //The last value (8.0f) is the amp that defines (roughly) the maximum float w = perlin.FractalNoise2D(x, z, 1, GroundFrequency, GroundAmplitude); return(perlin.FractalNoise2D(x - w, z - w, GroundOct, GroundFrequency, GroundAmplitude)); }
//All of these sample functions create the noise needed for a certain effect, for example caves, moutains etc. //The last three values in the noise functions are octaves, frequency and amplitude. //More ocatves will create more detail but is slower. //Higher/lower frquency will 'strech/shrink' out the noise. //Amplitude defines roughly the range of the noise, ie amp = 1.0 means roughly -1.0 to +1.0 * range of noise //The range of noise is 0.5 for 1D, 0.75 for 2D and 1.5 for 3D float SampleMountains(float x, float z, PerlinNoise perlin) { //This creates the noise used for the mountains. It used something called //domain warping. Domain warping is basically offseting the position used for the noise by //another noise value. It tends to create a warped effect that looks nice. float w = perlin.FractalNoise2D(x, z, 3, 120.0f, 32.0f); //Clamp noise to 0 so mountains only occur where there is a positive value //The last value (32.0f) is the amp that defines (roughly) the maximum mountaion height //Change this to create high/lower mountains return(Mathf.Min(0.0f, perlin.FractalNoise2D(x + w, z + w, 6, 120.0f, 32.0f))); }
/// <summary> /// Generate height information for the terrain at the given tile /// </summary> float[,] GenerateHeightMap(int tileX, int tileZ) { //create the heightmap to store the data var heightmapSize = _terrainSettings.HeightmapSize; var htmap = new float[heightmapSize, heightmapSize]; var ratio = (float)_terrainSize / (float)heightmapSize; for (var x = 0; x < heightmapSize; ++x) { for (var z = 0; z < heightmapSize; ++z) { var worldX = (x + tileX * (heightmapSize - 1)) * ratio; var worldZ = (z + tileZ * (heightmapSize - 1)) * ratio; var height = 0f; //generate height using noise //var mountains = Mathf.Max(0.0f, _mountainNoise.FractalNoise2D(worldX, worldZ, 6, _terrainSettings.MountainFrequency, 0.8f)); var ground = _groundNoise.FractalNoise2D(worldX, worldZ, 4, _terrainSettings.GroundFrequency, 0.1f) + _terrainSettings.LakeDepth / 100f; height = ground; htmap[z, x] = height; } } return(htmap); }
public void GenerateChunk(Chunk chunk) { int chunkx = chunk.chunkx; int chunky = chunk.chunky; int id = 0; Random.seed = chunk.chunkSeed; for (int x = -chunkSize / 128; x < chunkSize / 128; x++) { for (int y = -chunkSize / 128; y < chunkSize / 128; y++) { float _x = x * 64 + chunkSize * chunkx; float _y = y * 64 + chunkSize * chunky; float ran = lnoise.FractalNoise2D(_x / 256, _y / 256, 3, 0.1f, 0.7f); if (ran > 0f) { transform.position = new Vector3(_x, _y, 1) + (Vector3)Random.insideUnitCircle * 31; Asteroid a = GenerateRandomAsteroid(ran, chunk.chunkSeed + id); a.chunk = chunk; a.id = id; chunk.asteroids.Add(id++, a); } } } }
float SampleGround(float x, float z, PerlinNoise perlin) { //This creates the noise used for the ground. //The last value (8.0f) is the amp that defines (roughly) the maximum //and minimum vaule the ground varies from the surface level return(perlin.FractalNoise2D(x, z, 4, 80.0f, 8.0f)); }
// Update is called once per frame void Update() { if (GameManager.state == GameState.Running) { time += Time.deltaTime; transform.position = new Vector2(thisPosition.x + perlin.FractalNoise2D(new Vector2(thisPosition.x + time, thisPosition.y + time), 8, 0.03f, 2f, 0.5f, amount), thisPosition.y + perlin.FractalNoise2D(new Vector2(thisPosition.y + time, thisPosition.y + time), 8, 0.03f, 2f, 0.5f, amount)); } }
private float[] GetWeightsForPoint(int x, int y, float terrainMaxHeight) { // Normalise x/y coordinates to range 0-1 float y_01 = (float)y / (float)terrainData.alphamapHeight; float x_01 = (float)x / (float)terrainData.alphamapWidth; // Setup an array to record the mix of texture weights at this point float[] splatWeights = new float[terrainData.alphamapLayers]; // get height and slope at corresponding point float height = terrainData.GetInterpolatedHeight(x_01, y_01); float slope = terrainData.GetSteepness(x_01, y_01) / 90.0f; float noise = alphaNoise.FractalNoise2D(x_01 * terrainData.size.x, y_01 * terrainData.size.z, 4, alphaFrq, alphaNoiseScale); //if (x == 250 && y == 250) Debug.Log(slope + " " + height + " " + noise); splatWeights[0] = Mathf.Max(0f, plainTextureWeight - (slope * steepTextureWeight)); // decreases with slope (ground texture) splatWeights[1] = slope * steepTextureWeight; // increases with slope (rocky texture) // uplands terrain splatWeights[2] = ( height > (highlandThreshold * terrainMaxHeight) && // higher than threshold slope < steepTerrainThreshold) // plain terrain ? (highlandTextureWeight + noise) : 0f; // mid strata terrain splatWeights[3] = ( height <(midStrataUpperThreshold *terrainMaxHeight) && // lower than upper threshold height> (midStrataMiddleThreshold * terrainMaxHeight) && // higher than middle threshold slope > steepTerrainThreshold) // steep terrain ? (midStrataTextureWeight + noise) : 0f; splatWeights[4] = ( height <(midStrataMiddleThreshold *terrainMaxHeight) && // lower than middle threshold height> (midStrataLowerThreshold * terrainMaxHeight) && // higher than lower threshold slope > steepTerrainThreshold) // steep terrain ? (midStrataTextureWeight + noise) : 0f; // lowlands terrain splatWeights[5] = ( height < (lowlandThreshold * terrainMaxHeight) && // lower than threshold slope < steepTerrainThreshold) // plain terrain ? (lowlandTextureWeight + noise) : 0f; // Sum of all textures weights must add to 1, so calculate normalization factor from sum of weights float z = splatWeights.Sum(); // Loop through each terrain texture for (int i = 0; i < terrainData.alphamapLayers; i++) { // Normalize so that sum of all texture weights = 1 splatWeights[i] /= z; } return(splatWeights); }
public void AddNoise() { // set noise seed groundNoise = new PerlinNoise(groundNoiseSeed); // get the heights of the terrain float[,] heights = terrainData.GetHeights(0, 0, heightMapSize, heightMapSize); // we set each sample of the terrain in the size to the desired height for (int x = 0; x < heightMapSize; x++) { for (int z = 0; z < heightMapSize; z++) { heights[z, x] += groundNoise.FractalNoise2D(x, z, 4, groundFrq, groundNoiseScale) + // + 0.1f; (float)SimpleRNG.GetNormal () * groundNoiseScale;/ groundNoise.FractalNoise2D(x, z, 4, Mathf.RoundToInt(0.8f * groundFrq), 0.8f * groundNoiseScale) + groundNoise.FractalNoise2D(x, z, 4, Mathf.RoundToInt(0.5f * groundFrq), 0.5f * groundNoiseScale) + groundNoise.FractalNoise2D(x, z, 4, Mathf.RoundToInt(0.2f * groundFrq), 0.2f * groundNoiseScale); } // set the new height terrainData.SetHeights(0, 0, heights); } }
float getHeight(int tileX, int tileZ, int x, int z) { float worldPosX = ((tileX * m_heightMapSize) + x) * 0.02f; float worldPosZ = ((tileZ * m_heightMapSize) + z) * 0.02f; float mountains = Mathf.Max(0.0f, m_mountainNoise.FractalNoise2D(worldPosX, worldPosZ, 6, m_mountainFrq, 0.8f)); float plain = m_groundNoise.FractalNoise2D(worldPosX, worldPosZ, 4, m_groundFrq, 0.1f) + 0.1f; float height = plain + mountains; height = height * amplitude; return(height); }
public void CalcTerrain() { NoiseModule noise = new PerlinNoise(seed); for (int i = 0; i < MAP_SIZE * dim; i++) { float z = (initPos.z - (BaseDimension * 1.5f / dim)) + i * BaseDimension / (MAP_SIZE * dim); for (int j = 0; j < MAP_SIZE * dim; j++) { float x = (initPos.x - (BaseDimension * 1.5f / dim)) + j * BaseDimension / (MAP_SIZE * dim); float p2 = noise.FractalNoise2D(x, z, octaves_ground, frequency_ground * (dimension / BaseDimension), amplitude_ground, lacunarity_ground, persistence_ground); heightMapTable[i, j] = 0.5f + p2; } } }
void FillHeights(float[,] htmap, int tileX, int tileZ) { float ratio = (float)m_terrainSize / (float)m_heightMapSize; for (int x = 0; x < m_heightMapSize; x++) { for (int z = 0; z < m_heightMapSize; z++) { float worldPosX = (x + tileX * (m_heightMapSize - 1)) * ratio; float worldPosZ = (z + tileZ * (m_heightMapSize - 1)) * ratio; float mountains = Mathf.Max(0.0f, m_mountainNoise.FractalNoise2D(worldPosX, worldPosZ, 12, m_mountainFrq, 0.8f)); float plain = m_groundNoise.FractalNoise2D(worldPosX, worldPosZ, 12, m_groundFrq, 0.1f) + 0.1f; htmap[z, x] = plain + mountains; } } }
void GeneratePerlin(bool t) { float r = 1.0f - EmotionModel.CurrentState.x / -1.0f; float g = 1.0f - EmotionModel.CurrentState.magnitude; float b = 1.0f - EmotionModel.CurrentState.x / 1.0f; for (float x = 0.0F; x < 512; x++) { for (float y = 0.0F; y < 512; y++) { float noise = perlin.FractalNoise2D(x, y, oct, frq, amp); noise = (noise + 1.0f) * 0.25f; // noiseTex.SetPixel((int)x,(int)y,new Color(noise*r,noise*g,noise*b)); noiseTex.SetPixel((int)x, (int)y, new Color(noise * r, noise * g, noise * b, 1.0f)); } } noiseTex.Apply(); }
public void UpdateVegetationAtPatch(IntVector2 patchCoord, Transform patchHolder) { // reset SimpleRNG using tree seed SimpleRNG.SetSeed((uint)(treeNoiseSeed + patchCoord.x + patchCoord.y * terrainManager.worldPatchesX)); // set RNG seed depending on tree seed, world seed, and patch coordinates treeRNG = new System.Random(treeNoiseSeed + patchCoord.x + patchCoord.y * terrainManager.worldPatchesX); if (treePrefabs.Length > 0) { // get the number of trees in the patch (vegetation density) int numberOftrees = 0; if (true) { numberOftrees = Mathf.RoundToInt(Mathf.Max(0f, (float)SimpleRNG.GetNormal(treeDensity, treeDensityStdev))); } else { numberOftrees = Mathf.RoundToInt(vegetationNoiseOutsideModel.FractalNoise2D(patchCoord.x, patchCoord.y, 4, treeNoiseFrequency, treeNoiseScale) * treeDensity); } // place trees for (int i = 0; i < numberOftrees; i++) { // scale x and z coordinates for placing prefab prototypes in terrain. Note that this is not needed when placing GameObjects //Vector3 point = terrainManager.GetRandomPointInPatchSurface(patchCoord, treeRNG, scaleToTerrain: true); Vector3 point = loadSceneryAndLore.GetValidRandomPositionInPatch(patchCoord, 1f, treeRNG); float slope = terrainManager.GetSlopeAtPoint(point.x, point.z); if (slope < 0.7f) { //make sure tree are not on cliffs GameObject temp = Instantiate(treePrefabs[Random.Range(0, treePrefabs.Length)], point, Quaternion.identity); //temp.transform.Translate(Vector3.down * 1f); temp.transform.localScale = Vector3.one * (treeScale.min + (float)treeRNG.NextDouble() * (treeScale.max - treeScale.min)); temp.transform.Rotate(Vector3.up * Random.Range(0f, 360f)); temp.transform.parent = patchHolder.transform; // TreeInstance temp = new TreeInstance (); // temp.position = point; // temp.rotation = Random.Range (0f, 360f) * Mathf.Deg2Rad; // temp.prototypeIndex = Random.Range (0, treePrefabs.Length); // temp.color = Color.white; // temp.lightmapColor = Color.white; // // actTerrain.AddTreeInstance (temp); } } } //Debug.Log (terrainData.treeInstanceCount); // reset SimpleRNG using cactus seed SimpleRNG.SetSeed((uint)(cactusNoiseSeed + patchCoord.x + patchCoord.y * terrainManager.worldPatchesX)); // set RNG seed depending on cactus seed, world seed, and patch coordinates cactusRNG = new System.Random(cactusNoiseSeed + patchCoord.x + patchCoord.y * terrainManager.worldPatchesX); if (cactusPrefabs.Length > 0) { // get the number of cactus in the patch (vegetation density) int numberOfCactus = 0; if (true) { numberOfCactus = Mathf.RoundToInt(Mathf.Max((float)SimpleRNG.GetNormal(cactusDensity, cactusDensityStdev))); } else { numberOfCactus = Mathf.RoundToInt(vegetationNoiseOutsideModel.FractalNoise2D(patchCoord.x, patchCoord.y, 4, cactusNoiseFrequency, cactusNoiseScale) * cactusDensity); } // place trees for (int i = 0; i < numberOfCactus; i++) { //Debug.Log(patchCoord.ToString()); // scale x and z coordinates for placing prefab prototypes in terrain. Note that this is not needed when placing GameObjects //Vector3 point = terrainManager.GetRandomPointInPatchSurface(patchCoord, cactusRNG, scaleToTerrain: true); Vector3 point = loadSceneryAndLore.GetValidRandomPositionInPatch(patchCoord, 1f, cactusRNG); // normal diffusion //point = new Vector3(point.x + (float)SimpleRNG.GetNormal(0, .01f), 0f, point.z + (float)SimpleRNG.GetNormal(0, 0.01f)); float slope = terrainManager.GetSlopeAtPoint(point.x, point.z); if (slope < 0.7f) { //make sure cactus are not on cliffs GameObject temp = Instantiate(cactusPrefabs[cactusRNG.Next(0, cactusPrefabs.Length)], point, Quaternion.identity); //temp.transform.Translate(Vector3.down * 0.2f); temp.transform.localScale = Vector3.one * (cactusScale.min + (float)cactusRNG.NextDouble() * (cactusScale.max - cactusScale.min)); temp.transform.Rotate(Vector3.up * Random.Range(0f, 360f)); temp.transform.parent = patchHolder.transform; //TreeInstance temp = new TreeInstance(); //temp.position = point; //temp.rotation = Random.Range(0f, 360f) * Mathf.Deg2Rad; //temp.prototypeIndex = Random.Range(treePrefabs.Length, treePrefabs.Length + cactusPrefabs.Length); //float randomScale = Random.Range(1f, cactusMaxScale); //temp.widthScale = randomScale; //temp.heightScale = randomScale; //temp.color = Color.white; //temp.lightmapColor = Color.white; //actTerrain.AddTreeInstance(temp); } } } }
float SampleGround(float x, float z, PerlinNoise perlin, VoronoiNoise voronoi) { //This creates the noise used for the ground. //The last value (8.0f) is the amp that defines (roughly) the maximum //and minimum vaule the ground varies from the surface level //return perlin.FractalNoise2D(x, z, 12, 80.0f, 8.0f); test = voronoi.FractalNoise2D(x, z, 8, 32.0f, 8.0f) + perlin.FractalNoise2D(x, z, 12, 80.0f, 8.0f)/2; if(test > 1.85f) { return Mathf.Min (1.85f, test) + test/3f; } else { return test; } //return Mathf.Min (2.75f,test); }
void FillTreeInstances() { terrain.treeDistance = m_treeDistance; terrain.treeBillboardDistance = m_treeBillboardDistance; terrain.treeCrossFadeLength = m_treeCrossFadeLength; terrain.treeMaximumFullLODCount = m_treeMaximumFullLODCount; m_treeProtoTypes = new TreePrototype[2]; m_treeProtoTypes[0] = new TreePrototype(); m_treeProtoTypes [0].prefab = m_tree0; m_treeProtoTypes [1] = new TreePrototype (); m_treeProtoTypes[1].prefab = m_tree1; terrain.terrainData.treePrototypes = m_treeProtoTypes; PerlinNoise m_treeNoise = new PerlinNoise(Random.Range(0,100)); //ArrayList instances = new ArrayList(); for(int x = 0; x < m_terrainSize; x += m_treeSpacing) { for (int z = 0; z < m_terrainSize; z += m_treeSpacing) { float unit = 1.0f / (m_terrainSize - 1); float offsetX = Random.value * unit * m_treeSpacing; float offsetZ = Random.value * unit * m_treeSpacing; float normX = x * unit + offsetX; float normZ = z * unit + offsetZ; // Get the steepness value at the normalized coordinate. float angle = terrain.terrainData.GetSteepness(normX, normZ); // Steepness is given as an angle, 0..90 degrees. Divide // by 90 to get an alpha blending value in the range 0..1. float frac = angle / 90.0f; if(frac < 0.45f) //make sure tree are not on steep slopes { float worldPosX = x; float worldPosZ = z; float noise = m_treeNoise.FractalNoise2D(worldPosX, worldPosZ, 3, m_treeFrq, 1.0f); float ht = terrain.terrainData.GetInterpolatedHeight(normX, normZ); if(noise > 0.0f && ht < m_terrainHeight*0.4f) { TreeInstance temp = new TreeInstance(); temp.position = new Vector3(normX,ht,normZ); temp.prototypeIndex = Random.Range (0, 2); temp.widthScale = 1f; temp.heightScale = 1f; temp.color = Color.white; temp.lightmapColor = Color.white; terrain.AddTreeInstance(temp); } } } } //terrain.terrainData.treeInstances = (TreeInstance[])instances.ToArray(typeof(TreeInstance)); terrain.terrainData.SetHeights(0, 0, new float[,] { { } }); terrain.Flush (); }
void FillDetailMap() { m_detailProtoTypes = new DetailPrototype[0]; terrain.terrainData.detailPrototypes = m_detailProtoTypes; m_detailProtoTypes = new DetailPrototype[3]; float minHeight = 0.2f; float maxHeight = 0.8f; float minWidth = 0.2f; float maxWidth = 0.8f; m_detailProtoTypes[0] = new DetailPrototype(); m_detailProtoTypes[0].prototypeTexture = m_detail0; m_detailProtoTypes[0].renderMode = detailMode; m_detailProtoTypes[0].healthyColor = m_grassHealthyColor; m_detailProtoTypes[0].dryColor = m_grassDryColor; m_detailProtoTypes [0].minHeight = minHeight; m_detailProtoTypes [0].maxHeight = maxHeight; m_detailProtoTypes [0].minWidth = minWidth; m_detailProtoTypes [0].maxWidth = maxWidth; m_detailProtoTypes[1] = new DetailPrototype(); m_detailProtoTypes[1].prototypeTexture = m_detail1; m_detailProtoTypes[1].renderMode = detailMode; m_detailProtoTypes[1].healthyColor = m_grassHealthyColor; m_detailProtoTypes[1].dryColor = m_grassDryColor; m_detailProtoTypes [1].minHeight = minHeight; m_detailProtoTypes [1].maxHeight = maxHeight; m_detailProtoTypes [1].minWidth = minWidth; m_detailProtoTypes [1].maxWidth = maxWidth; m_detailProtoTypes[2] = new DetailPrototype(); m_detailProtoTypes[2].prototypeTexture = m_detail2; m_detailProtoTypes[2].renderMode = detailMode; m_detailProtoTypes[2].healthyColor = m_grassHealthyColor; m_detailProtoTypes[2].dryColor = m_grassDryColor; m_detailProtoTypes [2].minHeight = minHeight; m_detailProtoTypes [2].maxHeight = maxHeight; m_detailProtoTypes [2].minWidth = minWidth; m_detailProtoTypes [2].maxWidth = maxWidth; terrain.terrainData.detailPrototypes = m_detailProtoTypes; PerlinNoise m_detailNoise = new PerlinNoise(Random.Range(0,100)); //each layer is drawn separately so if you have a lot of layers your draw calls will increase int[,] detailMap0 = new int[512,512]; int[,] detailMap1 = new int[512,512]; int[,] detailMap2 = new int[512,512]; float ratio = (float)m_terrainSize/(float)512; for(int x = 0; x < 512; x++) { for (int z = 0; z < 512; z++) { detailMap0[z,x] = 0; detailMap1[z,x] = 0; detailMap2[z,x] = 0; float unit = 1.0f / (512 - 1); float normX = x * unit; float normZ = z * unit; // Get the steepness value at the normalized coordinate. float angle = terrain.terrainData.GetSteepness(normX, normZ); // Steepness is given as an angle, 0..90 degrees. Divide // by 90 to get an alpha blending value in the range 0..1. float frac = angle / 90.0f; if(frac < 0.3f) { float worldPosX = (x+(512-1))*ratio; float worldPosZ = (z+(512-1))*ratio; float noise = m_detailNoise.FractalNoise2D(worldPosX, worldPosZ, 3, m_detailFrq, 1.0f); if(noise > 0.0f) { float rnd = Random.value; if(rnd < 0.33) detailMap0[z,x] = 1; else if(rnd < 0.66f) detailMap1[z,x] = 1; else detailMap2[z,x] = 1; } } } } terrain.terrainData.wavingGrassStrength = m_wavingGrassStrength; terrain.terrainData.wavingGrassAmount = m_wavingGrassAmount; terrain.terrainData.wavingGrassSpeed = m_wavingGrassSpeed; terrain.terrainData.wavingGrassTint = m_wavingGrassTint; terrain.detailObjectDensity = m_detailObjectDensity; terrain.detailObjectDistance = m_detailObjectDistance; terrain.terrainData.SetDetailResolution(512, m_detailResolutionPerPatch); terrain.terrainData.SetDetailLayer(0,0,0,detailMap0); terrain.terrainData.SetDetailLayer(0,0,1,detailMap1); terrain.terrainData.SetDetailLayer(0,0,2,detailMap2); }
//not cave noise just normal noise now as it needed a noise with another seed public float SampleCaves(float x, float z, PerlinNoise perlin) { float w = perlin.FractalNoise2D(x , z ,1,CaveFrequency,caveAmplitude); //larger caves (A higher frequency will also create larger caves). It is unitless, 1 != 1m return Mathf.Abs(perlin.FractalNoise2D(x+w, z+w,caveOct,CaveFrequency,caveAmplitude)); }
//Not usable void FollowMothership() { transform.position = new Vector2(motherShip_t.position.x + perlin1.FractalNoise2D(new Vector2(sprite.position.x + time, sprite.position.y + time), 8, 0.03f, 2f, 0.5f, 1f), motherShip_t.position.y + perlin2.FractalNoise2D(new Vector2(sprite.position.x + time, sprite.position.y + time), 8, 0.03f, 1f, 0.5f, 1f)); shot.transform.position = transform.position; }
/// <summary> /// Generate detail like grass and props on the terrain /// </summary> List <int[, ]> GenerateDetailLayers(TerrainData data, int tileX, int tileZ) { //make sure there are details set if (_detailPrototypes.Length < 1) { return(null); } //create all layers //note: each layer is a seperate draw call so try to keep it low var detailLayers = new List <int[, ]>(); var detailSize = _terrainSettings.DetailMapSize; var ratio = (float)_terrainSize / (float)detailSize; //create maps for each layer for (int i = 0; i < _detailPrototypes.Length; ++i) { detailLayers.Add(new int[detailSize, detailSize]); } var centerTile = tileX == (_tilesX / 2) && tileZ == (_tilesZ / 2); //fill the layers for (int x = 0; x < detailSize; x++) { for (int z = 0; z < detailSize; z++) { //Set all detail to 0 foreach (var layer in detailLayers) { layer[z, x] = 0; } var unit = 1.0f / (detailSize - 1); var normX = x * unit; var normZ = z * unit; // Get the steepness value at the normalized coordinate. var angle = data.GetSteepness(normX, normZ); // Steepness is given as an angle, 0..90 degrees. Divide // by 90 to get an alpha blending value in the range 0..1. var frac = angle / 90.0f; //select a random type of layer to use(texture or mesh var rng = Random.value; //Select a random grass layer var grassLayer = Random.Range(0, _grassLayers); //select a random prop layer var propLayer = Random.Range(_grassLayers, _meshLayers + 1); //in the center tile fill it completely with grass, and remove it on locations of props and buildings later if (centerTile) { //prefer to spawn grass if (rng < 0.99f) { detailLayers[grassLayer][z, x] = 1; } else { if (detailLayers.Count > 1) { detailLayers[propLayer][z, x] = 1; } } } else if (frac < 0.5f) { var worldPosX = (x + tileX * (detailSize - 1)) * ratio; var worldPosZ = (z + tileZ * (detailSize - 1)) * ratio; var noise = _detailNoise.FractalNoise2D(worldPosX, worldPosZ, 3, _terrainSettings.DetailFrequency, 1.0f); if (noise > 0.0f) { //prefer to spawn grass if (rng < 0.99f) { detailLayers[grassLayer][z, x] = 1; } else { if (detailLayers.Count > 1) { detailLayers[propLayer][z, x] = 1; } } } } } } return(detailLayers); }
void fillTreeInstances(Terrain terrain) { terrain.treeDistance = 2000f; //The distance at which trees will no longer be drawn terrain.treeBillboardDistance = 1000f; //The distance at which trees meshes will turn into tree billboards terrain.treeCrossFadeLength = 25f; //As trees turn to billboards there transform is rotated to match the meshes, a higher number will make this transition smoother terrain.treeMaximumFullLODCount = ((int)Random.Range(2f, 4f)); //The maximum number of trees that will be drawn in a certain area. TreePrototype[] m_treeProtoTypes = new TreePrototype[2]; m_treeProtoTypes[0] = new TreePrototype(); m_treeProtoTypes[0].prefab = m_tree0; m_treeProtoTypes[1] = new TreePrototype(); m_treeProtoTypes[1].prefab = m_tree1; terrain.terrainData.treePrototypes = m_treeProtoTypes; PerlinNoise m_treeNoise = new PerlinNoise(Random.Range(0, 100)); int m_treeSpacing = ((int)Random.Range(2048f, 4096f)); // 96 to 256 float m_treeFrq = 0.001f; for (int x = 0; x < m_terrainSize; x += m_treeSpacing) { for (int z = 0; z < m_terrainSize; z += m_treeSpacing) { float unit = 1.0f / (m_terrainSize - 1); float offsetX = Random.value * unit * m_treeSpacing; float offsetZ = Random.value * unit * m_treeSpacing; float normX = x * unit + offsetX; float normZ = z * unit + offsetZ; // Get the steepness value at the normalized coordinate. float angle = terrain.terrainData.GetSteepness(normX, normZ); // Steepness is given as an angle, 0..90 degrees. Divide // by 90 to get an alpha blending value in the range 0..1. float frac = angle / 90.0f; if (frac < 0.1f) //make sure tree are not on steep slopes { float worldPosX = x; float worldPosZ = z; float noise = m_treeNoise.FractalNoise2D(worldPosX, worldPosZ, 3, m_treeFrq, 1.0f); float ht = terrain.terrainData.GetInterpolatedHeight(normX, normZ); if (noise > 0.0f) { TreeInstance temp = new TreeInstance(); temp.position = new Vector3(normX, ht, normZ); temp.prototypeIndex = Random.Range(0, 2); temp.widthScale = 1f; temp.heightScale = 1f; temp.color = Color.white; temp.lightmapColor = Color.white; terrain.AddTreeInstance(temp); } } } } terrain.terrainData.SetHeights(0, 0, new float[, ] { { } }); terrain.Flush(); (terrain.GetComponent(typeof(TerrainCollider)) as TerrainCollider).enabled = false; (terrain.GetComponent(typeof(TerrainCollider)) as TerrainCollider).enabled = true; }
float SampleGround(float x, float z, PerlinNoise perlin) { //This creates the noise used for the ground. //The last value (8.0f) is the amp that defines (roughly) the maximum //and minimum vaule the ground varies from the surface level return perlin.FractalNoise2D(x, z, 4, 80.0f, 8.0f); }
public void CreateVoxels(PerlinNoise surfacePerlin, PerlinNoise cavePerlin) { //float startTime = Time.realtimeSinceStartup; //Creates the data the mesh is created form. Fills m_voxels with values between -1 and 1 where //-1 is a soild voxel and 1 is a empty voxel. int w = m_voxels.GetLength(0); int h = m_voxels.GetLength(1); int l = m_voxels.GetLength(2); for (int x = 0; x < w; x++) { for (int z = 0; z < l; z++) { //world pos is the voxels position plus the voxel chunks position float worldX = x + m_pos.x; float worldZ = z + m_pos.z; float ht = SampleGround(worldX, worldZ, surfacePerlin); // float localBiom = 0f; // localBiom += (float)z/h * ((float)m_neighbourBiomes[2] - (float)m_biome); // localBiom += (float)x/w * ((float)m_neighbourBiomes[1] - (float)m_biome); // localBiom += (1f-(float)z/h) * ((float)m_neighbourBiomes[0]- (float)m_biome); // localBiom += (1f-(float)x/w) * ((float)m_neighbourBiomes[3]- (float)m_biome); // float factor = Mathf.Clamp01((surfacePerlin.FractalNoise2D(x, z, 4, 400.0f, 1.0f) + 0.75f)/1.5f); // float it = ht + SampleIslands(worldX, worldZ, surfacePerlin); // ht = (ht+m_surfaceLevel+1f) * factor + it * (1f-factor); // float factor = Mathf.Clamp01((surfacePerlin.FractalNoise2D(x, z, 4, 400.0f, 1.5f) + 0.75f)/1.5f); // float it = ht + SampleSpikes(worldX, worldZ, surfacePerlin); // ht = it; //(ht-1f) * factor + it * (1f-factor); /* * float factor = Mathf.Clamp01((surfacePerlin.FractalNoise2D(x, z, 4, 400.0f, 1.0f) + 0.75f)/1.5f); * float st = SampleSpikes(worldX, worldZ, surfacePerlin); * ht = (ht+m_surfaceLevel-1f) * factor + (ht + st) * (1f-factor); * * factor = Mathf.Clamp01((surfacePerlin.FractalNoise2D(x, z, 4, 150.0f, 1.0f) + 0.75f)/1.5f); * float it = SampleIslands(worldX, worldZ, surfacePerlin); * ht = (ht+m_surfaceLevel+1f) * factor + (ht + it) * (1f-factor); * * ht -= m_surfaceLevel; * ht -= SampleMountains(worldX, worldZ, surfacePerlin); */ VoronoiNoise.SetDistanceToEuclidian(); VoronoiNoise.SetCombinationTo_D2_D0(); ht *= VoronoiNoise.FractalNoise2D(worldX, worldZ, 2, 500f, 2f, 6); float factor = Mathf.Clamp01((surfacePerlin.FractalNoise2D(worldX, worldZ, 4, 400.0f, 1.0f) + 0.9375f) / 1.875f); float st = SampleSpikes(worldX, worldZ, surfacePerlin); ht = (ht + m_surfaceLevel - 1f) * factor + (ht + st) * (1f - factor); factor = Mathf.Clamp01((surfacePerlin.FractalNoise2D(worldX, worldZ, 4, 150.0f, 1.0f) + 0.9375f) / 1.875f); float it = SampleIslands(worldX, worldZ, surfacePerlin); ht = (ht + m_surfaceLevel + 1f) * factor + (ht + it) * (1f - factor); ht -= m_surfaceLevel * 1.5f; // ht -= SampleMountains(worldX, worldZ, surfacePerlin); for (int y = 0; y < h; y++) { float worldY = y + m_pos.y - m_surfaceLevel; //If we take the heigth value and add the world //the voxels will change from positiove to negative where the surface cuts through the voxel chunk m_voxels[x, y, z] = Mathf.Clamp(ht + worldY, -1.0f, 1.0f); if (m_biome == 15) { float caveHt = SampleCaves(worldX, worldY, worldZ, cavePerlin); //This fades the voxel value so the caves never appear more than h units from //the surface level. float fade = 1.0f - Mathf.Clamp01(Mathf.Max(0.0f, worldY) / h); m_voxels[x, y, z] += caveHt * fade; m_voxels[x, y, z] = Mathf.Clamp(m_voxels[x, y, z], -1.0f, 1.0f); } } } } //Debug.Log("Create voxels time = " + (Time.realtimeSinceStartup-startTime).ToString() ); }
void fillDetailMap(Terrain terrain) { DetailPrototype[] m_detailProtoTypes = new DetailPrototype[0]; terrain.terrainData.detailPrototypes = m_detailProtoTypes; m_detailProtoTypes = new DetailPrototype[2]; float minHeight = 0.25f; float maxHeight = 1f; float minWidth = 0.25f; float maxWidth = 1f; m_detailProtoTypes[0] = new DetailPrototype(); m_detailProtoTypes[0].prototypeTexture = m_detail0; m_detailProtoTypes[0].renderMode = detailMode; m_detailProtoTypes[0].healthyColor = m_grassHealthyColor; m_detailProtoTypes[0].dryColor = m_grassDryColor; m_detailProtoTypes[0].minHeight = minHeight; m_detailProtoTypes[0].maxHeight = maxHeight; m_detailProtoTypes[0].minWidth = minWidth; m_detailProtoTypes[0].maxWidth = maxWidth; m_detailProtoTypes[1] = new DetailPrototype(); m_detailProtoTypes[1].prototypeTexture = m_detail1; m_detailProtoTypes[1].renderMode = detailMode; m_detailProtoTypes[1].healthyColor = m_grassHealthyColor; m_detailProtoTypes[1].dryColor = m_grassDryColor; m_detailProtoTypes[1].minHeight = minHeight; m_detailProtoTypes[1].maxHeight = maxHeight; m_detailProtoTypes[1].minWidth = minWidth; m_detailProtoTypes[1].maxWidth = maxWidth; terrain.terrainData.detailPrototypes = m_detailProtoTypes; PerlinNoise m_detailNoise = new PerlinNoise(Random.Range(0, 1000)); //each layer is drawn separately so if you have a lot of layers your draw calls will increase int[,] detailMap0 = new int[m_terrainSize, m_terrainSize]; int[,] detailMap1 = new int[m_terrainSize, m_terrainSize]; for (int x = 0; x < m_terrainSize; x++) { for (int z = 0; z < m_terrainSize; z++) { detailMap0[z, x] = 0; detailMap1[z, x] = 0; // Get the steepness value at the normalized coordinate. float angle = terrain.terrainData.GetSteepness(x, z); // Steepness is given as an angle, 0..90 degrees. Divide // by 90 to get an alpha blending value in the range 0..1. float frac = angle / 90.0f; if (frac < 0.2f) { float worldPosX = x; float worldPosZ = z; float noise = m_detailNoise.FractalNoise2D(worldPosX, worldPosZ, 3, m_detailFrq, 1.0f); if (noise > 0.0f) { float rnd = Random.value; if (rnd < 0.5f) { detailMap0[z, x] = 1; } else { detailMap1[z, x] = 1; } } } } } terrain.terrainData.wavingGrassStrength = m_wavingGrassStrength; terrain.terrainData.wavingGrassAmount = m_wavingGrassAmount; terrain.terrainData.wavingGrassSpeed = m_wavingGrassSpeed; terrain.terrainData.wavingGrassTint = m_wavingGrassTint; terrain.detailObjectDensity = m_detailObjectDensity; terrain.detailObjectDistance = m_detailObjectDistance; terrain.terrainData.SetDetailResolution(m_terrainSize, m_detailResolutionPerPatch); terrain.terrainData.SetDetailLayer(0, 0, 0, detailMap0); terrain.terrainData.SetDetailLayer(0, 0, 1, detailMap1); terrain.Flush(); }
public float SampleGround(float x,float z, PerlinNoise perlin) { //This creates the noise used for the ground. //The last value (8.0f) is the amp that defines (roughly) the maximum float w = perlin.FractalNoise2D(x , z ,1,GroundFrequency,GroundAmplitude); return perlin.FractalNoise2D(x-w, z-w,GroundOct,GroundFrequency,GroundAmplitude); }
/// <summary> /// Generate trees on the terrain /// </summary> List <TreeInstance> GenerateTrees(TerrainData data, int tileX, int tileZ) { //make sure prototypes have been set if (_treePrototypes.Length < 1) { return(null); } var trees = new List <TreeInstance>(); int spacing = 8; var maxHeight = _terrainSettings.TerrainHeight * 0.7f; var minHeight = _terrainSettings.TerrainHeight * 0.1f; for (var x = 0; x < _terrainSize; x += spacing) { for (var z = 0; z < _terrainSize; z += spacing) { var unit = 1.0f / (_terrainSize - 1); var offsetX = Random.value * unit * spacing; var offsetZ = Random.value * unit * spacing; var xNorm = x * unit + offsetX; var zNorm = z * unit + offsetZ; var xWorld = x + tileX * (_terrainSize - 1); var zWorld = z + tileZ * (_terrainSize - 1); //randomizes the spacing spacing = Random.Range(4, 12); // Get the steepness value at the normalized coordinate. var angle = data.GetSteepness(xNorm, zNorm); // Steepness is given as an angle, 0..90 degrees. Divide // by 90 to get an alpha blending value in the range 0..1. var frac = angle / 90.0f; if (frac < 0.7f) { var noise = _treeNoise.FractalNoise2D(xWorld, zWorld, 3, _terrainSettings.TreeFrequency, 1.0f); var height = data.GetInterpolatedHeight(xNorm, zNorm); //no trees on high mountains if (noise > 0.1f && height < maxHeight && height > minHeight) { //Create the tree instance var tree = new TreeInstance() { heightScale = 1, widthScale = 1, prototypeIndex = Random.Range(0, _treePrototypes.Length), lightmapColor = Color.white, color = Color.white, position = new Vector3(xNorm, height, zNorm) }; trees.Add(tree); } } } } return(trees); }
public static Color Generate(float x, float y, float freq, float colorBase, float colorVariance, int seed) { Color color; float index, bright, red, green, blue; PerlinNoise myPerlin = new PerlinNoise(seed); index = colorBase + myPerlin.FractalNoise2D(x, y, 3, freq, colorVariance); while (index > 6.0f) { index -= 6.0f; } while (index < 0.0f) { index += 6.0f; } bright = 0.5f + myPerlin.FractalNoise2D(x, y, 3, freq, 0.5f); while (bright > 1.0f) { bright -= 0.01f; } while (bright < 0.0f) { bright += 0.01f; } red = 0.0f; green = 0.0f; blue = 0.0f; if (index >= 2.0f && index < 4.0f) { red = 0.0f; } else if (index >= 0.0f && index < 1.0f) { red = bright; } else if (index >= 1.0f && index < 2.0f) { red = bright * (2.0f - index); } else if (index >= 4.0f && index < 5.0f) { red = bright * (index - 4.0f); } else if (index >= 5.0f && index <= 6.0f) { red = bright; } if (index >= 4.0f && index < 6.0f) { green = 0.0f; } else if (index >= 1.0f && index < 3.0f) { green = bright; } else if (index >= 3.0f && index < 4.0f) { green = bright * (4.0f - index); } else if (index >= 0.0f && index < 1.0f) { green = bright * index; } if (index >= 0.0f && index < 2.0f) { blue = 0.0f; } else if (index >= 3.0f && index < 5.0f) { blue = bright; } else if (index >= 2.0f && index < 3.0f) { blue = bright * (index - 2.0f); } else if (index >= 5.0f && index <= 6.0f) { blue = bright * (6.0f - index); } color = new Vector4(red, green, blue); return(color); }
//All of these sample functions create the noise needed for a certain effect, for example caves, moutains etc. //The last three values in the noise functions are octaves, frequency and amplitude. //More ocatves will create more detail but is slower. //Higher/lower frquency will 'strech/shrink' out the noise. //Amplitude defines roughly the range of the noise, ie amp = 1.0 means roughly -1.0 to +1.0 * range of noise //The range of noise is 0.5 for 1D, 0.75 for 2D and 1.5 for 3D float SampleMountains(float x, float z, PerlinNoise perlin) { //This creates the noise used for the mountains. It used something called //domain warping. Domain warping is basically offseting the position used for the noise by //another noise value. It tends to create a warped effect that looks nice. float w = perlin.FractalNoise2D(x, z, 3, 120.0f, 32.0f); //Clamp noise to 0 so mountains only occur where there is a positive value //The last value (32.0f) is the amp that defines (roughly) the maximum mountaion height //Change this to create high/lower mountains return Mathf.Min(0.0f, perlin.FractalNoise2D(x+w, z+w, 6, 120.0f, 32.0f) ); }
public static Color Generate(float x, float y,float freq, float colorBase, float colorVariance,int seed) { Color color; float index,bright,red,green,blue; PerlinNoise myPerlin = new PerlinNoise(seed); index = colorBase + myPerlin.FractalNoise2D(x,y,3, freq, colorVariance); while(index > 6.0f){ index -= 6.0f; } while(index < 0.0f){ index += 6.0f; } bright = 0.5f + myPerlin.FractalNoise2D(x,y,3, freq, 0.5f); while(bright > 1.0f){ bright -= 0.01f; } while(bright < 0.0f){ bright += 0.01f; } red=0.0f; green=0.0f; blue=0.0f; if(index >= 2.0f && index < 4.0f){ red = 0.0f; } else if(index >= 0.0f && index < 1.0f){ red = bright; } else if(index >= 1.0f && index < 2.0f){ red = bright * (2.0f - index); } else if(index >= 4.0f && index < 5.0f){ red = bright * (index - 4.0f); } else if(index >= 5.0f && index <= 6.0f){ red = bright; } if(index >= 4.0f && index < 6.0f){ green = 0.0f; } else if(index >= 1.0f && index < 3.0f){ green = bright; } else if(index >= 3.0f && index < 4.0f){ green = bright * (4.0f - index); } else if(index >= 0.0f && index < 1.0f){ green = bright * index; } if(index >= 0.0f && index < 2.0f){ blue = 0.0f; } else if(index >= 3.0f && index < 5.0f){ blue = bright; } else if(index >= 2.0f && index < 3.0f){ blue = bright * (index - 2.0f); } else if(index >= 5.0f && index <= 6.0f){ blue = bright * (6.0f - index); } color = new Vector4(red,green,blue); return color; }