My Notebook

Random starfield generator for THREE.js

Author
Date
Category
Web Development/JavaScript

Any kind of 3d space simulation needs a skybox with a starfield as background decoration. At first I wanted to get this right and use a realistic starfield with real stars in their correct positions, but it is really hard to get those for free in high resolutions.

This website has a very good description of the problems associated with star fields and some free sample textures.

Most of the time you get low resolution starfields and you are not allowed to redistribute them. However it is much easier to just generate your own random texture on the fly.

Generate random star field texture

Generating a random texture to be mapped on a sphere, without any distortions, is quite hard. So I settled for a simple sky box. It is easy to generate the textures for it, and it looks good enough. At least for my purposes.

function getRandomStarField(numberOfStars, width, height) {
    var canvas = document.createElement('CANVAS');

	canvas.width = width;
	canvas.height = height;

	var ctx = canvas.getContext('2d');

	ctx.fillStyle="black";
	ctx.fillRect(0, 0, width, height);

	for (var i = 0; i < numberOfStars; ++i) {
		var radius = Math.random() * 2;
		var x = Math.floor(Math.random() * width);
		var y = Math.floor(Math.random() * height);

		ctx.beginPath();
		ctx.arc(x, y, radius, 0, 2 * Math.PI, false);
		ctx.fillStyle = 'white';
		ctx.fill();
	}

	var texture = new THREE.Texture(canvas);
	texture.needsUpdate = true;
	return texture;
};

The function uses a canvas element to draw a certain number of blurred stars with random sizes on random positions on a black background. It is so simple, but it arguably looks better than most of the sophisticated projection stuff.

Demo

The following code is used to create a simple sky box around the model:

var skyBox = new THREE.BoxGeometry(120, 120, 120);
var skyBoxMaterial = new THREE.MeshBasicMaterial({
    map: getRandomStarField(600, 2048, 2048),
	side: THREE.BackSide
});
var sky = new THREE.Mesh(skyBox, skyBoxMaterial);
scene.add(sky);

References