public static DustCloud[] Generate(Random rand, int count) { float minRad = 1f; float maxRad = 16f; float near = 20f; float far = 32f; var clrPairs = new Color4[, ] { { Color4.Red, Color4.Blue } }; int variation = rand.Next(16, 32); var seta = new Vector3[variation]; var setb = new Vector3[variation]; for (int i = 0; i < variation; ++i) { seta[i] = Starfield.GetRandomPosition(rand, near, far); setb[i] = Starfield.GetRandomPosition(rand, near, far); } int index = rand.Next(clrPairs.GetLength(0)); var clra = clrPairs[index, 0]; var clrb = clrPairs[index, 1]; var dusts = new DustCloud[count]; for (int i = 0; i < count; ++i) { var pos = Starfield.GetRandomPosition(rand, near, far); float scale = (float)Math.Pow(rand.NextDouble(), 4); float rad = minRad + scale * (maxRad - minRad); float alpha = (1 - scale) / 96f; var suma = seta.Sum(x => 1f / Math.Max(0.125f, (pos - x).LengthSquared)); var sumb = setb.Sum(x => 1f / Math.Max(0.125f, (pos - x).LengthSquared)); var shift = (suma * suma) / ((suma * suma) + (sumb * sumb)); var clr = new Color4( clra.R * shift + clrb.R * (1f - shift), clra.G * shift + clrb.G * (1f - shift), clra.B * shift + clrb.B * (1f - shift), alpha); var dust = new DustCloud(pos, rad, clr); dusts[i] = dust; } Array.Sort(dusts, Starfield.Comparer); return(dusts); }
public static CubeMapTexture Generate(int seed, int resolution, int samples) { var rand = seed == 0 ? new Random() : new Random(seed); var stars = Star.Generate(rand, rand.Next(16384, 32768)); var dusts = DustCloud.Generate(rand, rand.Next(4096, 8192)); int renderResolution = resolution * samples; var camera = new Camera(renderResolution, renderResolution, MathHelper.PiOver2, 4f, 64f); var starShader = new StarShader { Camera = camera }; var dustShader = new DustCloudShader { Camera = camera }; var target = new FrameBuffer(new BitmapTexture2D(new Bitmap(renderResolution, renderResolution)), 16); var angles = new[] { Tuple.Create(0f, MathHelper.PiOver2), Tuple.Create(0f, -MathHelper.PiOver2), Tuple.Create(MathHelper.PiOver2, 0f), Tuple.Create(-MathHelper.PiOver2, 0f), Tuple.Create(0f, 0f), Tuple.Create(0f, MathHelper.Pi) }; var bmps = new Bitmap[6]; target.Begin(); GL.ClearColor(Color.Black); var bmp = new Bitmap(renderResolution, renderResolution); for (int i = 0; i < 6; ++i) { camera.Pitch = angles[i].Item1; camera.Yaw = angles[i].Item2; GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); dustShader.BeginBatch(); foreach (var dust in dusts) { dustShader.Render(dust); } dustShader.EndBatch(); starShader.BeginBatch(); foreach (var star in stars) { starShader.Render(star); } starShader.EndBatch(); var data = bmp.LockBits(new Rectangle(0, 0, renderResolution, renderResolution), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); GL.ReadPixels(0, 0, renderResolution, renderResolution, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0); bmp.UnlockBits(data); bmps[i] = new Bitmap(bmp, new Size(resolution, resolution)); } bmp.Dispose(); target.End(); target.Dispose(); return(new CubeMapTexture(bmps[0], bmps[1], bmps[2], bmps[3], bmps[4], bmps[5])); }