Skip to content

Commit 07dcd34

Browse files
author
hayden-donnelly
committed
Interpolation showoff.
1 parent bbe4cdc commit 07dcd34

File tree

9 files changed

+660
-0
lines changed

9 files changed

+660
-0
lines changed

Assets/Development/Scenes/Interpolation.unity

Lines changed: 404 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/Development/Scenes/Interpolation.unity.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using UnityEngine;
4+
using Unity.Barracuda;
5+
using NeuralTerrainGeneration;
6+
using System;
7+
8+
// This is not for use in the final product.
9+
// It is just a script used to showoff interpolation.
10+
public class Interpolator : MonoBehaviour
11+
{
12+
// General.
13+
[SerializeField] private WorkerFactory.Type workerType = WorkerFactory.Type.ComputePrecompiled;
14+
[SerializeField] private TensorMathHelper tensorMathHelper = new TensorMathHelper();
15+
[SerializeField] private TerrainHelper terrainHelper = new TerrainHelper();
16+
[SerializeField] private int modelOutputWidth = 256;
17+
[SerializeField] private int modelOutputHeight = 256;
18+
private int upSampledWidth = 0;
19+
private int upSampledHeight = 0;
20+
[SerializeField] private float heightMultiplier = 0.5f;
21+
private int channels = 1;
22+
[SerializeField] private NNModel modelAsset;
23+
private Model runtimeModel;
24+
25+
// Diffusion.
26+
private const float maxSignalRate = 0.9f;
27+
private const float minSignalRate = 0.02f;
28+
private Diffuser diffuser = new Diffuser();
29+
private int samplingSteps = 10;
30+
31+
// Upsampling.
32+
// Left: upsample resolution, right: upsample factor.
33+
private enum UpSampleResolution
34+
{
35+
_256 = 1,
36+
_512 = 2,
37+
_1024 = 4,
38+
_2048 = 8,
39+
_4096 = 16
40+
};
41+
private UpSampleResolution upSampleResolution = UpSampleResolution._512;
42+
43+
// Smoothing.
44+
[SerializeField] private int kernelSize = 12;
45+
[SerializeField] private float sigma = 6.0f;
46+
47+
// Seeds to interpolate.
48+
[SerializeField] private int[] seeds = new int[2];
49+
50+
// Interpolation.
51+
private const int numInterpolationSteps = 20;
52+
private float interpolationStepSize = 0.0f;
53+
private float[] stepSizes = new float[numInterpolationSteps];
54+
55+
[SerializeField] private Terrain terrain;
56+
57+
private void Start()
58+
{
59+
// Calculate upsampled dimensions.
60+
int upSampleFactor = (int)upSampleResolution;
61+
upSampledWidth = modelOutputWidth * upSampleFactor;
62+
upSampledHeight = modelOutputHeight * upSampleFactor;
63+
64+
// Load model.
65+
runtimeModel = ModelLoader.Load(modelAsset);
66+
67+
// Calculate interpolation step size.
68+
interpolationStepSize = 1.0f / (numInterpolationSteps);
69+
70+
for(int i = 0; i < numInterpolationSteps; i++)
71+
{
72+
stepSizes[i] = StepSizeSchedule(i, numInterpolationSteps);
73+
}
74+
float stepSizesSum = 0.0f;
75+
for(int i = 0; i < numInterpolationSteps; i++)
76+
{
77+
stepSizesSum += stepSizes[i];
78+
}
79+
for(int i = 0; i < numInterpolationSteps; i++)
80+
{
81+
stepSizes[i] /= stepSizesSum;
82+
}
83+
84+
StartCoroutine(MyCoroutine());
85+
}
86+
87+
private float StepSizeSchedule(float currentStep, float endPoint)
88+
{
89+
/*double n = (float)endPoint;
90+
double k = (float)steepness;
91+
double x = (float)currentStep;
92+
double y = 1 / (1 + Math.Exp(-k * (x - n / 2)));
93+
double dy = k * y * (1 - y);
94+
return (float)y;*/
95+
96+
return -0.25f * currentStep * (currentStep - endPoint);
97+
}
98+
99+
private IEnumerator MyCoroutine()
100+
{
101+
for(int currentSeedIndex = 0; currentSeedIndex < seeds.Length - 1; currentSeedIndex++)
102+
{
103+
int seed1 = seeds[currentSeedIndex];
104+
int seed2 = seeds[currentSeedIndex + 1];
105+
106+
Tensor input1 = tensorMathHelper.PseudoRandomNormalTensor(
107+
1,
108+
modelOutputWidth,
109+
modelOutputHeight,
110+
channels,
111+
seed1
112+
);
113+
Tensor input2 = tensorMathHelper.PseudoRandomNormalTensor(
114+
1,
115+
modelOutputWidth,
116+
modelOutputHeight,
117+
channels,
118+
seed2
119+
);
120+
121+
for(int currentStep = 0; currentStep < numInterpolationSteps; currentStep++)
122+
{
123+
float t = 0.0f;
124+
for(int i = 0; i < currentStep; i++)
125+
{
126+
t += stepSizes[i];
127+
}
128+
Tensor interpolatedInput = tensorMathHelper.VectorSlerp(
129+
input1,
130+
input2,
131+
t
132+
);
133+
float[] heightmap = GenerateHeightmap(
134+
upSampleResolution,
135+
samplingSteps,
136+
0,
137+
interpolatedInput
138+
);
139+
terrainHelper.SetTerrainHeights(
140+
terrain,
141+
heightmap,
142+
upSampledWidth,
143+
upSampledHeight,
144+
heightMultiplier
145+
);
146+
147+
Debug.Log("CurrentStep: " + currentStep);
148+
yield return new WaitForSeconds(2);
149+
}
150+
}
151+
}
152+
153+
private Tensor Smooth(Tensor input)
154+
{
155+
GaussianSmoother gaussianSmoother = new GaussianSmoother(
156+
kernelSize,
157+
sigma,
158+
1,
159+
kernelSize-1,
160+
upSampledWidth,
161+
upSampledHeight,
162+
workerType
163+
);
164+
Tensor output = gaussianSmoother.Execute(input);
165+
gaussianSmoother.Dispose();
166+
167+
return output;
168+
}
169+
170+
private Tensor UpSample(Tensor input, UpSampleResolution upSampleResolutionArg)
171+
{
172+
if(upSampleResolutionArg == UpSampleResolution._256)
173+
{
174+
return input;
175+
}
176+
177+
int upSampleFactor = (int)upSampleResolutionArg;
178+
Tensor output = new Tensor(1, upSampledHeight, upSampledWidth, 1);
179+
180+
BarraUpSampler barraUpSampler = new BarraUpSampler(
181+
modelOutputWidth,
182+
modelOutputHeight,
183+
upSampleFactor,
184+
true,
185+
workerType
186+
);
187+
output = barraUpSampler.Execute(input);
188+
barraUpSampler.Dispose();
189+
190+
return output;
191+
}
192+
193+
private float[] GenerateHeightmap(
194+
UpSampleResolution upSampleResolutionArg,
195+
int diffusionSteps,
196+
int startingStep = 0,
197+
Tensor customInput = null
198+
)
199+
{
200+
float[] heightmap = new float[upSampledWidth * upSampledHeight];
201+
using(var worker = WorkerFactory.CreateWorker(workerType, runtimeModel))
202+
{
203+
Tensor input = new Tensor(1, modelOutputWidth, modelOutputHeight, channels);
204+
input = customInput;
205+
206+
Tensor diffusionOutput = diffuser.ReverseDiffusion(
207+
worker,
208+
input,
209+
modelOutputWidth,
210+
modelOutputHeight,
211+
diffusionSteps,
212+
startingStep
213+
);
214+
215+
Tensor upSampled = UpSample(diffusionOutput, upSampleResolutionArg);
216+
Tensor smoothed = Smooth(upSampled);
217+
heightmap = smoothed.ToReadOnlyArray();
218+
input.Dispose();
219+
diffusionOutput.Dispose();
220+
upSampled.Dispose();
221+
smoothed.Dispose();
222+
}
223+
224+
// TODO: I might have forgotten to denormalize values after reverse diffusion.
225+
// Reference this to make sure it was done correctly:
226+
// https://keras.io/examples/generative/ddim/
227+
228+
return heightmap;
229+
}
230+
}

Assets/Development/Scripts/Interpolator.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
0 Bytes
Binary file not shown.
544 KB
Binary file not shown.

Assets/Development/Terrain/Interpolation_Terrain.asset.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)