Procedural Space Skybox

Because variety is the spice of life

I wanted to procedurally generate a large number of space backgrounds, so I decided to brush up on my shader skills and attempt to write a fully procedural starfield using no textures.

A run through of some randomly generated skyboxes.

    // common noise functions
    #include "NoiseCommon.cginc"
    #include "Perlin.cginc"
    #include "Simplex.cginc"

    //
    // variables //////////////////////////////////////////////////////////////
    //
    
    uniform float _Seed, _StarSize, _StarDensity, _NebulaStr, _NebulaPlx;
    uniform float4 _StarColor, _NebulaColor, _NebulaPlxColor;

    //
    // types //////////////////////////////////////////////////////////////////
    //
    
    // app -> vert
    struct appdata
    {
        float4 vertex : POSITION;
        float3 tex0: TEXCOORD0;
    };

    //
    // ------------------------------------------------------------------------
    //
    
    // vert -> frag
    struct v2f
    {
        float4 pos: SV_POSITION;
        float3 tex0: TEXCOORD0;
        float3 tex1: TEXCOORD1;
    };

    //
    // ------------------------------------------------------------------------
    //

    float4 pointStarsLayer(float3 t0, float size)
    {
        float p = simplex(t0*_StarSize);
        float amt = (p-size)*100/(1.0-size);
        return clamp(_StarColor * amt,0,0.4);
    }
    
    float4 pointStars(float seed, float size, float3 texCoord)
    {
        float4 result = float4(0,0,0,1);

        result += pointStarsLayer(texCoord, size);
        
        return result;
    }

    //
    // ------------------------------------------------------------------------
    //

    float4 nebula(float seed, float3 texcoord, float4 color)
    {
        float4 base = color;
        float4 main = color * perlin(texcoord+seed);
        return (base + main);
    }
   
    //
    // vertex program /////////////////////////////////////////////////////////
    //

    v2f vert(appdata v)
    {
        v2f o;
        o.pos = UnityObjectToClipPos(v.vertex);
        o.tex0 = v.tex0;
        o.tex1 = v.vertex.xyz;
        return o;
    }

    //
    // fragment program ///////////////////////////////////////////////////////
    //
    
    float4 frag(v2f i) : COLOR
    {
        float4 stars = pointStars(_Seed, 1.0 - _StarDensity, i.tex0)*0.8;

        float4 neb = nebula(_Seed, i.tex0, _NebulaColor) * _NebulaStr;
        float4 neb2 = nebula(_Seed/5.0, i.tex0*0.5, _NebulaPlxColor) * _NebulaPlx;
        float4 col = neb + neb2 + stars;
        return col;
    }

This is pretty basic stuff, but it was fun to get back into writing shaders again. All we do is take generate some noise using perlin and simplex algorithms and scale and color to get stars and nebulae. The colors are randomized in the host application.