I have recently been spending a lot of time with procedural texture generation. However that quickly came to a halt when I was trying to get the textures to map to a sphere. I am required to use an image projected into something called equirectangular cylindrical projection. Here I have an image of random noise that I want mapped to the projection:
Here is an image using the Projection code I found below, however this code does not reproject an image, but rather picks points in 3D noise and then maps those points to a texture:
The code used to get this image can be found here credit to the original author
This is the code that I have currently to reproject the texture, although it does not work how I would like:
public static class EquirectangularReProjection
{
public static Texture2D ConvertToEquirectangular(Texture2D tex, TextureData data)
{
if (!data._ReprojectToEquirectangular)
{
return tex;
}
int xSize = tex.width;
int ySize = tex.height;
Texture2D output = InitializeTextureSettings(xSize, ySize, tex.name);
Color[] colors = new Color[xSize * ySize];
Stopwatch watch = new Stopwatch();
watch.Start();
for (int x = 0; x < xSize; x++)
{
for (int y = 0; y < ySize; y++)
{
int i = (y * xSize) + x;
float longitude = (-180 + x * 360f / xSize) * Mathf.Deg2Rad;
float latitude = (-90 + y * 180f / ySize) * Mathf.Deg2Rad;
Vector3 point = data._Radius * new Vector3(Mathf.Cos(longitude) * Mathf.Cos(latitude), Mathf.Sin(latitude), Mathf.Sin(longitude) * Mathf.Cos(latitude));
colors[i] = SampleTexture(point, data);
}
}
output.SetPixels(colors);
output.Apply();
watch.Stop();
if (data._DebugTimes)
{
UnityEngine.Debug.Log($"Time to Reproject {output.name}: {watch.ElapsedMilliseconds}ms | {watch.ElapsedTicks}-ticks");
}
return output;
}
private static float MinLWH = float.MaxValue;
private static float MaxLWH = float.MinValue;
private static Color SampleTexture(Vector3 point3d, TextureData data)
{
float heightFrac = Map(LayerWorldHeight(point3d, data), MinLWH, MaxLWH, 0f, 1f);
Color heightColour = Color.Lerp(Color.black, Color.white, heightFrac);
return heightColour;//Color.Lerp (randomColour, heightColour, p.gradientBlending);
}
private static float LayerWorldHeight(Vector3 x, TextureData p) => LayerWorldHeight(x.x, x.y, x.z, p);
private static float LayerWorldHeight(float x, float y, float z, TextureData p)
{
float layerTotal = p._Noise.fastNoise.GetNoise(x, y, z);
if (layerTotal < MinLWH) MinLWH = layerTotal;
if (layerTotal > MaxLWH) MaxLWH = layerTotal;
return layerTotal;
}
private static float Map(float x, float in_min, float in_max, float out_min, float out_max) => (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
I would like to reproject as my last step in the texture creation process so that it is a lot easier to manipulate.