duck

Unity 3D Procedural Terrain - Step 4 - Multi-Layer Perlin

Mar 1st, 2013
305
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.71 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class TerrainNoise : MonoBehaviour {
  5.    
  6.     float waterSmooth = 0;
  7.     float[,] heights;
  8.     Terrain terrain;
  9.     TerrainData data;
  10.     Transform water;
  11.     int noiseLayerCount = 20;
  12.     NoiseLayer[] noiseLayers;
  13.     float heightBoost = 10;
  14.     float updateTime;
  15.     bool dirty = true;
  16.    
  17.     void OnGUI()
  18.     {
  19.         GUILayout.BeginArea( new Rect(20,20,400,400) );
  20.        
  21.         GUI.color = Color.black;
  22.        
  23.         GUILayout.Label("WaterSmooth: "+waterSmooth);
  24.         float newWaterSmooth = GUILayout.HorizontalSlider(waterSmooth, 0f, 1f);
  25.         if (newWaterSmooth != waterSmooth)
  26.         {
  27.             waterSmooth = newWaterSmooth;
  28.             dirty = true;
  29.             updateTime = Time.time + 0.5f;
  30.         }
  31.        
  32.         GUILayout.Label("HeightBoost: "+heightBoost);
  33.         float newHeightBoost = GUILayout.HorizontalSlider(heightBoost, 1f, 40f);
  34.         if (newHeightBoost != heightBoost)
  35.         {
  36.             heightBoost = newHeightBoost;
  37.             dirty = true;
  38.             updateTime = Time.time + 0.5f;
  39.         }
  40.        
  41.         GUILayout.EndArea();
  42.        
  43.     }
  44.    
  45.     void Start()
  46.     {
  47.        
  48.         terrain = GetComponent<Terrain>(); 
  49.         data = terrain.terrainData;
  50.         heights = new float[ data.heightmapWidth, data.heightmapHeight];
  51.         water = GameObject.Find ("Water").transform;
  52.        
  53.        
  54.        
  55.         // create the required number of noise layer definitions
  56.         noiseLayers = new NoiseLayer[noiseLayerCount];
  57.         float frequency = .003f;
  58.         float amplitude = 0.5f;
  59.         for( int n=0; n<noiseLayers.Length; ++n)
  60.         {
  61.             noiseLayers[n] = new NoiseLayer();
  62.             noiseLayers[n].frequency = frequency;
  63.             noiseLayers[n].amplitude = amplitude;
  64.            
  65.             amplitude *= 0.5f;
  66.             frequency *= 2f;
  67.            
  68.         }
  69.        
  70.     }
  71.    
  72.     // Use this for initialization
  73.     void Update () {
  74.    
  75.         if (dirty && Time.time > updateTime)
  76.         {
  77.        
  78.             float waterHeight = water.position.y / data.size.y;
  79.            
  80.             for( int x=0; x< data.heightmapWidth; ++x)
  81.             {
  82.                 for( int z=0; z< data.heightmapHeight; ++z)
  83.                 {
  84.                     // accumulate height values from each perlin noise layer
  85.                     float height = 0;
  86.                     foreach(NoiseLayer noiseLayer in noiseLayers)
  87.                     {
  88.                         float f = noiseLayer.frequency;
  89.                         float a = noiseLayer.amplitude;
  90.                         height += Mathf.PerlinNoise(x*f, z*f) * a;
  91.                     }
  92.                    
  93.                     // smooth heights at water level
  94.                     float waterSmoothedHeight = height - waterHeight;
  95.                     float heightSign = Mathf.Sign(waterSmoothedHeight);
  96.                     waterSmoothedHeight *= (waterSmoothedHeight * heightSign) * heightBoost;
  97.                     waterSmoothedHeight += waterHeight;
  98.                    
  99.                    
  100.                     height = Mathf.Lerp( height, waterSmoothedHeight, waterSmooth );
  101.                    
  102.                     heights[x,z] = height;
  103.                    
  104.                 }
  105.             }
  106.            
  107.             data.SetHeights(0, 0, heights);
  108.            
  109.            
  110.             dirty = false;
  111.         }
  112.     }
  113.    
  114. }
  115.  
  116.  
  117. public struct NoiseLayer
  118. {
  119.     public float amplitude;
  120.     public float frequency;
  121.    
  122. }
Advertisement
Add Comment
Please, Sign In to add comment