[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class EarthSphereGenerator : MonoBehaviour
// Number of divisions along latitude and longitude to match your data grid
public int latitudeSegments = 180; // From -90 to 90 degrees
public int longitudeSegments = 360; // From -180 to 180 degrees
public float radius = 1.0f; // Radius of the sphere
MeshFilter meshFilter = GetComponent<MeshFilter>();
mesh.name = "EarthSphere";
int vertCount = (latitudeSegments + 1) * (longitudeSegments + 1);
Vector3[] vertices = new Vector3[vertCount];
Vector3[] normals = new Vector3[vertCount];
Vector2[] uv = new Vector2[vertCount];
int[] triangles = new int[latitudeSegments * longitudeSegments * 6];
// Generate vertices, normals, and UVs
for (int lat = 0; lat <= latitudeSegments; lat++)
float latFraction = (float)lat / latitudeSegments;
float latitude = Mathf.Lerp(-90f, 90f, latFraction);
float theta = Mathf.Deg2Rad * latitude;
float sinTheta = Mathf.Sin(theta);
float cosTheta = Mathf.Cos(theta);
for (int lon = 0; lon <= longitudeSegments; lon++)
float lonFraction = (float)lon / longitudeSegments;
float longitude = Mathf.Lerp(-180f, 180f, lonFraction);
float phi = Mathf.Deg2Rad * longitude;
float sinPhi = Mathf.Sin(phi);
float cosPhi = Mathf.Cos(phi);
// Calculate vertex position
float x = radius * cosTheta * cosPhi;
float y = radius * sinTheta;
float z = radius * cosTheta * sinPhi;
vertices[vertIndex] = new Vector3(x, y, z);
normals[vertIndex] = vertices[vertIndex].normalized;
uv[vertIndex] = new Vector2(lonFraction, latFraction);
for (int lat = 0; lat < latitudeSegments; lat++)
for (int lon = 0; lon < longitudeSegments; lon++)
int current = lat * (longitudeSegments + 1) + lon;
int next = current + longitudeSegments + 1;
// First triangle of the quad
triangles[triIndex++] = current;
triangles[triIndex++] = next;
triangles[triIndex++] = current + 1;
// Second triangle of the quad
triangles[triIndex++] = current + 1;
triangles[triIndex++] = next;
triangles[triIndex++] = next + 1;
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.RecalculateBounds();
meshFilter.sharedMesh = mesh;
if (Application.isPlaying)