duck

Unity 3D Procedural Terrain - Step 5 - Basic Texture Assign

Mar 1st, 2013
260
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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.             // Generate Heightmap
  79.            
  80.             float waterHeight = water.position.y / data.size.y;
  81.            
  82.             for( int x=0; x< data.heightmapWidth; ++x)
  83.             {
  84.                 for( int z=0; z< data.heightmapHeight; ++z)
  85.                 {
  86.                     // accumulate height values from each perlin noise layer
  87.                     float height = 0;
  88.                     foreach(NoiseLayer noiseLayer in noiseLayers)
  89.                     {
  90.                         float f = noiseLayer.frequency;
  91.                         float a = noiseLayer.amplitude;
  92.                         height += Mathf.PerlinNoise(x*f, z*f) * a;
  93.                     }
  94.                    
  95.                     // smooth heights at water level
  96.                     float waterSmoothedHeight = height - waterHeight;
  97.                     float heightSign = Mathf.Sign(waterSmoothedHeight);
  98.                     waterSmoothedHeight *= (waterSmoothedHeight * heightSign) * heightBoost;
  99.                     waterSmoothedHeight += waterHeight;
  100.                    
  101.                    
  102.                     height = Mathf.Lerp( height, waterSmoothedHeight, waterSmooth );
  103.                    
  104.                     heights[x,z] = height;
  105.                    
  106.                 }
  107.             }
  108.            
  109.             data.SetHeights(0, 0, heights);
  110.            
  111.            
  112.             // Generate Texture mixing map
  113.            
  114.             float [,,] alphamap = new float[ data.alphamapWidth, data.alphamapHeight, 4];
  115.                
  116.             for (int x=0; x<data.alphamapWidth; ++x)
  117.             {
  118.                 for (int z=0; z<data.alphamapWidth; ++z)
  119.                 {
  120.                     // normalize x and z values
  121.                     float nx = x / (float)data.alphamapHeight;
  122.                     float nz = z / (float)data.alphamapWidth;
  123.                    
  124.                     Vector4 mix = new Vector4(1,0,0,0);
  125.                    
  126.                     float height = data.GetInterpolatedHeight( nz, nx ) / data.size.y;
  127.                        
  128.                     if (height > waterHeight) {
  129.                         mix = new Vector4(0,1,0,0);
  130.                     }
  131.                    
  132.                     alphamap[x,z,0] = mix.x;
  133.                     alphamap[x,z,1] = mix.y;
  134.                     alphamap[x,z,2] = mix.z;
  135.                     alphamap[x,z,3] = mix.w;
  136.                 }
  137.                
  138.             }
  139.            
  140.             data.SetAlphamaps( 0, 0, alphamap );
  141.            
  142.             dirty = false;
  143.         }
  144.     }
  145.    
  146. }
  147.  
  148.  
  149. public struct NoiseLayer
  150. {
  151.     public float amplitude;
  152.     public float frequency;
  153. }
Advertisement
Add Comment
Please, Sign In to add comment