Starscape Texture OSL

This is a script based off of Michel over at blenderthings.blogspot.com . I highly recommend that site.
Anyway, I took his Starscape script and in my humble opinion, improved it a fair amount. There didn’t seem to be an easily available starscape texture for Cycles, so here’s one.
He releases his code under CC BY-SA, and I’m crediting him. If you’re reading this, and you want me to remove it, just PM me and I will.

/*  Scarscape Texture for OSL and Cycles.
**  Based off of the script from blenderthings.blogspo`t.com
**  I've changed the scaling so that 1 produces good results.
**  I've also added a random color variation to the stars, 
**  and my own "twinkle" effect.
*/


#include "stdosl.h"
#include "node_texture.h"


point voronoi3dp(point p, float density, output float d2)
{
	int xx, yy, zz, xi, yi, zi;
	xi = (int)floor(p[0]);
	yi = (int)floor(p[1]);
	zi = (int)floor(p[2]);


	float dbest = 1e10;
	point pbest = 1e10;
	vector dz = vector(7,111,19);
	for (xx = xi - 1; xx <= xi + 1; xx++) {
		for (yy = yi - 1; yy <= yi + 1; yy++) {
			for (zz = zi - 1; zz <= zi + 1; zz++) {
				vector ip = vector(xx, yy, zz);
				if(cellnoise(ip)<density){
					point  vp = ip + cellnoise(ip+dz);
					vector dp = p-vp;
					float  d  = dot(dp,dp);
					if (d < dbest) {
						dbest = d;
						pbest = vp;
					}
				}
			}
		}
	}


	d2=dbest;
	return pbest;
}


shader stars(
    float Scale = 1
        [[string help = "Scale of the starfield, smaller values give bigger stars",
        float min = 0]],
    float StarDensity = 1
        [[string help = "Density of the stars, higher values mean more stars per area",
        float min = 0]],
    float StarColorVariation = 0
        [[string help = "Adds random color variation to the stars.",
        float min = 0, float max = 1]],
    float TwinkleAmount = 1
        [[string help = "Adds a random brightness to the stars",
        float min = 0]],
    float TwinkleTime = 0
        [[string help = "Controlls the TwinkleAmount. Animate this value to get twinkling stars.",
        float min = 0]],
    point Pos = P,
    
    output color Color = 0.0,
    output float Fac = 0.0
)
{
    float scaleint = Scale * 750;
    point p = Pos * scaleint;
    color starcolorint = 0.0;
    float stardensityint = StarDensity/100;
    float twinkle = 0.0;


    
    float d;
    voronoi3dp(p, stardensityint, d);
    Fac = exp(-d * 10);
    if(StarColorVariation){
        starcolorint = color("hsv", noise(p/10), StarColorVariation, 1);
    }
    else{
        starcolorint = color(0.9, 0.9, 0.9);
    }
    if(TwinkleAmount){
        twinkle = noise("uperlin", p/10+TwinkleTime) * TwinkleAmount;
        twinkle += 0.3;
        twinkle = clamp(twinkle, 0, 1);
        starcolorint *= twinkle;
    }
    starcolorint *= Fac;
    
    Color = starcolorint;
}



you might like to include an image so we can see what it looks like - for those like me who are too lazy to try it out :wink:

Here’s some quick demos:



With color variation:

Seems too uniform in both brightness and distribution. A starfield should have lots of dims stars. a bit fewer of the medium stars, and a few very bright stars.

Steve S

In the original “Spacewars” game (for an impossibly-tiny ancient computer), they programmed constellations into it using a table of star-positions in a celestial almanac . . . (true!) . . . :yes:

I remember Space Wars. It was the first video game that I really got into. I never cared much for Pong.

Steve S

Wow, awesome!

Yep - the number of stars at various magnitudes increases exponentially as you go dimmer. The star field would be more realistic if it followed this general rule.

If you start out with a few stars at 100% brightness - then for every 50% reduction in brightness - you should multiply this number by 2.5.

For example - if you start out with 10 bright stars at 100%. You should have 25 stars at brightness 50%, 63 stars at brightness 25%, 170 stars at brightness 12.5%, 426 stars at 6.75% brightness etc.

I am new to this OSL scripting. How do I use this script in blender? Do I copy it and go to the material and select it as a script?

Thanks in advance.

If I remember right, you have to a place the OSL script in the text editor. Then, in the Node editor, add a script node to the material tree. Select Internal for the script node source and choose the text in the text editor. The Script node also allows reference to stored text files on the disk too.

Another thing to remember is that OSL does not work with the GPU so remember to set Cycles to CPU and check the box that says “Open Shading Language