Skip to content

Instantly share code, notes, and snippets.

@unitycoder
Forked from stonstad/StarfieldMeshBuilder.cs
Created October 22, 2025 13:32
Show Gist options
  • Save unitycoder/5e5fe42d66e7ae904ca7587f2ecf1d85 to your computer and use it in GitHub Desktop.
Save unitycoder/5e5fe42d66e7ae904ca7587f2ecf1d85 to your computer and use it in GitHub Desktop.
using System;
using UnityEngine;
using UnityEngine.Rendering;
using Random = System.Random;
namespace StellarConquest.Presentation.Unity
{
public class StarfieldMeshBuilder : MonoBehaviour
{
public float SphereRadius = 4000;
public int StarsCount = 0;
public int Seed = 0;
[Range(1, 15)]
public float StarSizeScale = 4.5f;
[SerializeField] AnimationCurve StarSize = new AnimationCurve(new Keyframe(0, 1), new Keyframe(1, 10));
[SerializeField] AnimationCurve Brightness = new AnimationCurve(new Keyframe(0, 0.8f), new Keyframe(1, 2f));
[SerializeField] Gradient StarColor = new Gradient();
private MeshFilter _MeshFilter;
private Mesh _Mesh;
private bool _IsDirty = false;
#if UNITY_EDITOR
private void OnValidate()
{
_IsDirty = true;
}
#endif
private void Update()
{
if (_IsDirty)
Build();
}
[ContextMenu("Build")]
public void Build()
{
_IsDirty = false;
if (!_MeshFilter)
_MeshFilter = GetComponent<MeshFilter>();
if (_Mesh == null)
{
_Mesh = new Mesh() { indexFormat = IndexFormat.UInt32 };
_Mesh.name = name;
_MeshFilter.mesh = _Mesh;
}
_Mesh.Clear();
Vector3[] vertices = new Vector3[4 * StarsCount];
int[] triangles = new int[3 * 2 * StarsCount];
Vector2[] uvs = new Vector2[vertices.Length];
Color[] colors = new Color[vertices.Length];
Random rnd = new Random(Seed);
for (int i = 0; i < StarsCount; i++)
{
//calc position
int index = i * 4;
float distance = SphereRadius + SphereRadius * NextFloat() / 2f;
float size = StarSize.Evaluate(NextFloat()) * StarSizeScale;
Vector3 pos = NextOnSphere() * distance;
Vector3 up = Vector3.Cross(pos, Math.Abs(pos.z) > distance / 2 ? Vector3.up : Vector3.right).normalized;
Vector3 left = Vector3.Cross(-up, pos).normalized;
//vertices
vertices[index + 0] = pos + (left + up) * size;
vertices[index + 1] = pos + (-left + up) * size;
vertices[index + 2] = pos + (-left - up) * size;
vertices[index + 3] = pos + (left - up) * size;
//uv
uvs[index + 0] = new Vector2(0, 0);
uvs[index + 1] = new Vector2(1, 0);
uvs[index + 2] = new Vector2(1, 1);
uvs[index + 3] = new Vector2(0, 1);
//triangles
var iTr = i * 2 * 3;
triangles[iTr++] = index + 0;
triangles[iTr++] = index + 1;
triangles[iTr++] = index + 2;
triangles[iTr++] = index + 0;
triangles[iTr++] = index + 2;
triangles[iTr++] = index + 3;
//color
Color color = Brightness.Evaluate(NextFloat()) * StarColor.Evaluate(NextFloat());
colors[index + 0] = colors[index + 1] = colors[index + 2] = colors[index + 3] = color;
}
_Mesh.SetVertices(vertices);
_Mesh.SetUVs(0, uvs);
_Mesh.SetTriangles(triangles, 0);
_Mesh.SetColors(colors);
_Mesh.RecalculateNormals();
_Mesh.RecalculateBounds();
float NextFloat()
{
return (float)rnd.NextDouble();
}
Vector3 NextOnSphere()
{
var theta = 2 * Math.PI * rnd.NextDouble();
var phi = Math.Acos(2 * rnd.NextDouble() - 1.0);
var sinPhi = Math.Sin(phi);
var x = Math.Cos(theta) * sinPhi;
var y = Math.Sin(theta) * sinPhi;
var z = Math.Cos(phi);
return new Vector3((float)x, (float)y, (float)z);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment