View difference between Paste ID: VVZuAM4u and 3vGshxMv
SHOW: | | - or go back to the newest paste.
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
			float waterBlendRange = 25 / data.size.y;
113
			
114
			float steepGroundAngle = 25;
115
			float cliffAngle = 55;
116
			float angleBlendRange = 10;
117
			
118
			
119
			// Generate Texture mixing map
120
			
121
			float [,,] alphamap = new float[ data.alphamapWidth, data.alphamapHeight, 4];
122
				
123
			for (int x=0; x<data.alphamapWidth; ++x)
124
			{
125
				for (int z=0; z<data.alphamapWidth; ++z)
126
				{
127
					// normalize x and z values
128
					float nx = x / (float)data.alphamapHeight;
129
					float nz = z / (float)data.alphamapWidth;
130
					
131
					Vector4 mix = new Vector4(1,0,0,0);
132
					
133
					float height = data.GetInterpolatedHeight( nz, nx ) / data.size.y;
134
						
135
					// blend between underwater texture and abovewater texture
136
					if (height > waterHeight ) {
137
						float blend = Mathf.InverseLerp( waterHeight, waterHeight+waterBlendRange, height );
138
						mix = Vector4.Lerp ( mix, new Vector4(0,1,0,0), blend );
139
					}
140
					
141
					// blend between above water texture and the steep ground texture 
142
					Vector3 normal = data.GetInterpolatedNormal( nz, nx );
143
					float angle = Vector3.Angle( normal, Vector3.up );
144
					
145
					if (angle > steepGroundAngle)
146
					{
147
						float blend = Mathf.InverseLerp( steepGroundAngle, steepGroundAngle+angleBlendRange, angle );
148
						mix = Vector4.Lerp ( mix, new Vector4(0,0,1,0), blend );
149
					}
150
					
151
					if (angle > cliffAngle)
152
					{
153
						float blend = Mathf.InverseLerp( cliffAngle, cliffAngle+angleBlendRange, angle );
154
						mix = Vector4.Lerp ( mix, new Vector4(0,0,0,1), blend );
155
					}
156
					
157
					alphamap[x,z,0] = mix.x;
158
					alphamap[x,z,1] = mix.y;
159
					alphamap[x,z,2] = mix.z;
160
					alphamap[x,z,3] = mix.w;
161
				}
162
				
163
			}
164
			
165
			data.SetAlphamaps( 0, 0, alphamap );
166
			
167
		
168
			dirty = false;
169
		}
170
	}
171
	
172
}
173
174
175
public struct NoiseLayer
176
{
177
	public float amplitude;
178
	public float frequency;
179
	
180
}