Skip to content

Commit 0afac51

Browse files
author
Cory Leach
committed
Visualizing Derivatives and Normals
1 parent 8a4d114 commit 0afac51

File tree

2 files changed

+68
-13
lines changed

2 files changed

+68
-13
lines changed

Runtime/Utility/ValueNoise.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,23 @@ public static float Fractal1D(float x, uint seed, float frequency, int octaves,
3737
return sum / range;
3838
}
3939

40+
public static NoiseSample FractalSample1D(float x, uint seed, float frequency, int octaves,
41+
float lacunarity = 2f, float persistence = 0.5f)
42+
{
43+
var sum = Sample1D(x, seed, frequency);
44+
var amplitude = 1f;
45+
var range = 1f;
46+
for (var i = 1; i < octaves; i++)
47+
{
48+
frequency *= lacunarity;
49+
amplitude *= persistence;
50+
range += amplitude;
51+
sum += Sample1D(x, seed, frequency) * amplitude;
52+
}
53+
54+
return sum * (1f / range);
55+
}
56+
4057
/// <summary>
4158
/// 2 dimensional fractal perlin noise
4259
/// </summary>
@@ -145,7 +162,8 @@ public static float Noise1D(float x, uint seed)
145162

146163
public static NoiseSample Sample1D(float x, uint seed, float frequency = 1)
147164
{
148-
var x0 = Mathf.FloorToInt(x * frequency);
165+
x *= frequency;
166+
var x0 = Mathf.FloorToInt(x);
149167
var x1 = x0 + 1;
150168

151169
var t = Smooth(x - x0);

Runtime/Visualizers/SurfaceMeshVisualizer.cs

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ public class SurfaceMeshVisualizer : MonoBehaviour
2525

2626
[SerializeField] private Vector3 offset;
2727

28+
[SerializeField] private bool showNormals;
29+
[SerializeField] private float normalSize = 0.1f;
30+
2831
private Mesh mesh;
2932
private int currentResolution;
3033
private Vector3[] vertices;
@@ -70,10 +73,23 @@ private void OnEnable()
7073
Refresh();
7174
}
7275

76+
private void OnDrawGizmosSelected()
77+
{
78+
if (showNormals && vertices != null)
79+
{
80+
Gizmos.color = Color.yellow;
81+
for (int v = 0; v < vertices.Length; v++)
82+
{
83+
Gizmos.DrawRay( transform.TransformPoint(vertices[v]), normals[v] * normalSize);
84+
}
85+
}
86+
}
87+
7388
[ContextMenu("Refresh")]
7489
private void Refresh()
7590
{
76-
if (currentResolution != resolution || mesh == null)
91+
if (currentResolution != resolution || mesh == null || vertices == null ||
92+
vertices.Length != ((resolution + 1) * (resolution + 1)))
7793
{
7894
CreateMesh();
7995
}
@@ -83,8 +99,8 @@ private void Refresh()
8399
var point01 = transform.TransformPoint(new Vector3(-0.5f, 0, 0.5f)) + offset;
84100
var point11 = transform.TransformPoint(new Vector3(0.5f, 0, 0.5f)) + offset;
85101

86-
//var minSample = float.MaxValue;
87-
//var maxSample = float.MinValue;
102+
var minSample = float.MaxValue;
103+
var maxSample = float.MinValue;
88104

89105
var stepSize = 1f / resolution;
90106
for (int v = 0, y = 0; y <= resolution; y++)
@@ -95,16 +111,19 @@ private void Refresh()
95111
{
96112
var point = Vector3.Lerp(point0, point1, x * stepSize);
97113
var sample = Noise(point);
98-
//minSample = Mathf.Min(sample, minSample);
99-
//maxSample = Mathf.Max(sample, maxSample);
100-
vertices[v].y = (sample - 0.5f) * strength;
101-
colors[v] = coloring.Evaluate(sample);
114+
minSample = Mathf.Min(sample.value, minSample);
115+
maxSample = Mathf.Max(sample.value, maxSample);
116+
vertices[v].y = (sample.value - 0.5f) * strength;
117+
colors[v] = coloring.Evaluate(sample.value);
118+
normals[v] = new Vector3(sample.derivative.x, 1, 0).normalized;
102119
}
103120
}
104121

122+
//Debug.Log($"Min: {minSample} Max:{maxSample}");
123+
105124
mesh.vertices = vertices;
125+
mesh.normals = normals;
106126
mesh.colors = colors;
107-
mesh.RecalculateNormals();
108127
}
109128

110129
[ContextMenu("Force Refresh")]
@@ -114,40 +133,58 @@ private void ForceRefresh()
114133
Refresh();
115134
}
116135

117-
private float Noise(Vector3 point)
136+
private NoiseSample Noise(Vector3 point)
118137
{
119138
var v = 0f;
139+
var sample = new NoiseSample();
120140
switch (dimension)
121141
{
122142
case Dimension.Value1D:
123-
v = ValueNoise.Fractal1D(point.x * frequency, seed, frequency, octaves, lacunarity, persistence);
143+
//sample = ValueNoise.Sample1D(point.x, seed, frequency);
144+
sample = ValueNoise.FractalSample1D(point.x, seed:seed, frequency:frequency, octaves:octaves, lacunarity:lacunarity, persistence:persistence);
145+
//v = ValueNoise.Fractal1D(point.x * frequency, seed, frequency, octaves, lacunarity, persistence);
124146
break;
125147
case Dimension.Value2D:
126148
v = ValueNoise.Fractal2D(point * frequency, seed, frequency, octaves, lacunarity, persistence);
149+
sample.value = v;
127150
break;
128151
case Dimension.Value3D:
129152
v = ValueNoise.Fractal3D(point * frequency, seed, frequency, octaves, lacunarity, persistence);
153+
sample.value = v;
130154
break;
131155
case Dimension.Perlin1D:
132156
v = PerlinGradientNoise.Fractal1D(point.x, seed, frequency, octaves, lacunarity, persistence);
157+
sample.value = v;
133158
break;
134159
case Dimension.Perlin2D:
135160
v = PerlinGradientNoise.Fractal2D(point.x, point.y, seed, frequency, octaves, lacunarity,
136161
persistence);
162+
sample.value = v;
137163
break;
138164
case Dimension.Perlin3D:
139165
v = PerlinGradientNoise.Fractal3D(point.x, point.y, point.z, seed, frequency, octaves, lacunarity,
140166
persistence);
167+
sample.value = v;
141168
break;
142169
}
143170

144-
return v;
171+
return sample;
145172
}
146173

147174
private void CreateMesh()
148175
{
149176
currentResolution = resolution;
150-
mesh.Clear();
177+
178+
if (mesh == null)
179+
{
180+
mesh = new Mesh();
181+
mesh.name = "Surface Mesh";
182+
MeshFilter.mesh = mesh;
183+
}
184+
else
185+
{
186+
mesh.Clear();
187+
}
151188

152189
vertices = new Vector3[(resolution + 1) * (resolution + 1)];
153190
colors = new Color[vertices.Length];

0 commit comments

Comments
 (0)